facts

package
v0.42.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 12, 2026 License: Apache-2.0, Apache-2.0 Imports: 29 Imported by: 0

Documentation

Overview

Package facts owns directory and inventory protocol types, service authentication, and typed clients. DataClient performs issuance lookups, ControlClient invokes private operations with service-key credentials, and AdminClient invokes public administration with user bearer credentials. Built-in services and stores live in the control, server, directory, inventory, and storage subpackages; this package does not depend on those implementations.

Index

Constants

View Source
const Audience = "epithet-policy"

Audience is the aud claim on every service token.

View Source
const DirectoryAudience = "epithet-directory"
View Source
const InventoryAudience = "epithet-inventory"
View Source
const MaxControlResponse = 8 << 20
View Source
const TokenTTL = 60 * time.Second

TokenTTL bounds how long a minted request token is accepted.

Variables

View Source
var (
	ErrInvalid     = errors.New("invalid service operation")
	ErrNotFound    = errors.New("service resource not found")
	ErrDenied      = errors.New("service operation denied")
	ErrConflict    = errors.New("service revision or uniqueness conflict")
	ErrUnavailable = errors.New("service unavailable")
)

Functions

This section is empty.

Types

type Actor added in v0.41.0

type Actor struct {
	UserName     string
	ID           string
	Active       bool
	Groups       []string
	UserType     string
	Department   string
	Organization string
}

Actor carries the directory identity used for public administrative grants. Its field names preserve the private actor-snapshot JSON contract; it includes inactive identities so the public service can reject them explicitly.

type ActorSnapshot added in v0.41.0

type ActorSnapshot struct {
	User     *Actor `json:"user"`
	Revision string `json:"authorizationRevision"`
}

ActorSnapshot includes inactive users for administrative authorization checks. Its revision identifies the same snapshot as the returned user.

type AdminClient added in v0.41.0

type AdminClient struct {
	// contains filtered or unexported fields
}

AdminClient sends public directory and inventory administration requests using the caller's bearer credential. It is separate from the service-key ControlClient used between the public control service and private backends.

func NewAdminClient added in v0.41.0

func NewAdminClient(endpoint string, cfg tlsconfig.Config) (*AdminClient, error)

NewAdminClient binds a client to the complete public administration URL. An empty endpoint means the CA does not advertise managed inventory.

func (*AdminClient) Capabilities added in v0.41.0

func (c *AdminClient) Capabilities(ctx context.Context) (Capabilities, error)

Capabilities reads configured capabilities before host enrollment. Directory administration alone does not enable managed host enrollment. Errors must not be interpreted as absence: an outage cannot select static enrollment.

func (*AdminClient) Control added in v0.41.0

func (c *AdminClient) Control(ctx context.Context, bearer string, request ControlRequest) (*ControlResponse, int, error)

Control sends a single operation to the configured endpoint. Callers choose the credential for this operation; redirects never receive it.

type Authorization added in v0.41.0

type Authorization struct {
	Actor             string
	DirectoryRevision string
}

Authorization is the human identity and coherent directory revision already authorized by public control. The actor is signed in the service credential; the revision is signed in the request body. The client does not grant roles.

type Capabilities added in v0.41.0

type Capabilities struct {
	Version      int      `json:"version"`
	Capabilities []string `json:"capabilities"`
}

Capabilities distinguishes host enrollment from directory-only administration. An unavailable or malformed endpoint is an error, never static fallback.

type ControlClient added in v0.41.0

type ControlClient struct {
	// contains filtered or unexported fields
}

ControlClient owns signed administration and provisioning operations against private directory and inventory backends. It never accepts a user bearer token and never exposes raw HTTP requests or responses.

func NewControlClient added in v0.41.0

func NewControlClient(directoryURL, inventoryURL string, key sshcert.RawPrivateKey, cfg tlsconfig.Config) (*ControlClient, error)

NewControlClient configures the enabled private backends. An empty endpoint omits that backend; its operations report unavailable capabilities. Both may be omitted when control uses alternative read-only fact providers.

func (*ControlClient) Actor added in v0.41.0

func (c *ControlClient) Actor(ctx context.Context, id string) (*Actor, string, error)

Actor returns the administrator's current facts and authorization revision. Absence is nil; inactive users are returned so control can deny them explicitly.

func (*ControlClient) AddPattern added in v0.41.0

func (c *ControlClient) AddPattern(ctx context.Context, auth Authorization, proposal Proposal) (*HostRecord, error)

AddPattern creates an active pattern record under the supplied administrator.

func (*ControlClient) ApproveHost added in v0.41.0

func (c *ControlClient) ApproveHost(ctx context.Context, auth Authorization, id string, revision uint64) (*HostRecord, error)

ApproveHost activates a pending record at its exact reviewed revision.

func (*ControlClient) Capabilities added in v0.41.0

func (c *ControlClient) Capabilities(ctx context.Context) (Capabilities, error)

Capabilities combines the enabled backends' supported operations. Failure to read a backend is an error, never evidence that its capabilities are absent.

func (*ControlClient) CreateToken added in v0.41.0

func (c *ControlClient) CreateToken(ctx context.Context, auth Authorization, lifetimeSeconds int64) (*EnrollmentToken, error)

CreateToken creates a single-use enrollment token. Lifetime is in seconds; zero retains the backend default lifetime.

func (*ControlClient) DenyHost added in v0.41.0

func (c *ControlClient) DenyHost(ctx context.Context, auth Authorization, id string, revision uint64) (*HostRecord, error)

DenyHost denies a pending record at its exact reviewed revision.

func (*ControlClient) DirectoryAudit added in v0.41.0

func (c *ControlClient) DirectoryAudit(ctx context.Context, auth Authorization, after uint64, limit int) ([]DirectoryAuditEvent, error)

DirectoryAudit reads at most limit events after the exclusive sequence cursor. Zero limit retains the backend default.

func (*ControlClient) EditHost added in v0.41.0

func (c *ControlClient) EditHost(ctx context.Context, auth Authorization, id string, revision uint64, proposal Proposal) (*HostRecord, error)

EditHost replaces a reviewed proposal using its exact record revision.

func (*ControlClient) Enroll added in v0.41.0

func (c *ControlClient) Enroll(ctx context.Context, proposal Proposal, token string) (*HostRecord, error)

Enroll is a nonhuman operation; the optional single-use token grants the existing preapproval. Pending enrollment is represented by the record status.

func (*ControlClient) Groups added in v0.42.0

func (c *ControlClient) Groups(ctx context.Context, auth Authorization) (*GroupSnapshot, error)

Groups returns current directory group names and identifiers.

func (*ControlClient) Host added in v0.41.0

func (c *ControlClient) Host(ctx context.Context, auth Authorization, id string) (*HostRecord, error)

Host returns a managed record by ID, including pending and denied records.

func (*ControlClient) HostAudit added in v0.41.0

func (c *ControlClient) HostAudit(ctx context.Context, auth Authorization, after uint64, limit int) ([]HostAuditEvent, error)

HostAudit returns one page of inventory events after an exclusive sequence cursor. Zero starts at the beginning; zero limit defaults to 100.

func (*ControlClient) Hosts added in v0.41.0

func (c *ControlClient) Hosts(ctx context.Context, auth Authorization, after string, limit int, pending bool) ([]HostRecord, error)

Hosts returns one ID-ordered page of managed records, optionally restricted to pending records. Empty after starts enumeration; zero limit defaults to 100.

func (*ControlClient) Provision added in v0.41.0

func (c *ControlClient) Provision(ctx context.Context, request SCIMRequest) (*SCIMResult, error)

Provision executes a SCIM operation using the control service key, with no human actor. The result retains SCIM status, format, preconditions and location.

func (*ControlClient) RemoveHost added in v0.41.0

func (c *ControlClient) RemoveHost(ctx context.Context, auth Authorization, id string, revision uint64) error

RemoveHost deletes the record using its exact reviewed revision.

func (*ControlClient) RevokeToken added in v0.41.0

func (c *ControlClient) RevokeToken(ctx context.Context, auth Authorization, id string) error

RevokeToken revokes the identified enrollment token.

func (*ControlClient) Tokens added in v0.41.0

func (c *ControlClient) Tokens(ctx context.Context, auth Authorization, after string, limit int) ([]EnrollmentToken, error)

Tokens returns one ID-ordered page of enrollment tokens, including used and revoked tokens. Empty after starts enumeration; zero limit defaults to 100.

func (*ControlClient) Users added in v0.41.0

func (c *ControlClient) Users(ctx context.Context, auth Authorization) (*UserSnapshot, error)

Users returns the complete directory authorization snapshot.

type ControlEnvelope added in v0.41.0

type ControlEnvelope struct {
	Request               ControlRequest `json:"request"`
	AuthorizationRevision string         `json:"authorizationRevision,omitempty"`
}

ControlEnvelope is the existing private backend wire contract. Senders use typed ControlClient operations; backends decode this envelope at the boundary.

type ControlRequest added in v0.41.0

type ControlRequest struct {
	After           string    `json:"after,omitempty"`
	Limit           int       `json:"limit,omitempty"`
	Pending         bool      `json:"pending,omitempty"`
	AuditAfter      uint64    `json:"audit-after,omitempty"`
	AuditLimit      int       `json:"audit-limit,omitempty"`
	Action          string    `json:"action"`
	ID              string    `json:"id,omitempty"`
	Revision        uint64    `json:"revision,omitempty"`
	Host            *Proposal `json:"host,omitempty"`
	Token           string    `json:"token,omitempty"`
	LifetimeSeconds int64     `json:"lifetime-seconds,omitempty"`
}

ControlRequest is one operation at the complete advertised inventory URL. An optional single-use token preapproves enrollment. Admin authentication is the OIDC bearer header. Revision binds review/edit to the displayed record. Host and token lists use exclusive After IDs and Limit (0 defaults to 100, maximum 1000); Pending filters host lists. Audits use AuditAfter sequences and AuditLimit with the same bounds. Cursor fields survive JSON as exact values.

type ControlResponse added in v0.41.0

type ControlResponse struct {
	DirectoryUsers *UserSnapshot         `json:"directory-users,omitempty"`
	Directory      *GroupSnapshot        `json:"directory,omitempty"`
	DirectoryAudit []DirectoryAuditEvent `json:"directory-audit,omitempty"`
	Host           *HostRecord           `json:"host,omitempty"`
	Hosts          []HostRecord          `json:"hosts,omitempty"`
	Token          *EnrollmentToken      `json:"token,omitempty"`
	Tokens         []EnrollmentToken     `json:"tokens,omitempty"`
	Audit          []HostAuditEvent      `json:"audit,omitempty"`
	Error          string                `json:"error,omitempty"`
}

ControlResponse carries the result of one ControlRequest. Only the fields relevant to the requested action are set; Error accompanies a non-2xx status.

type DataClient added in v0.41.0

type DataClient struct {
	// contains filtered or unexported fields
}

DataClient supplies validated authorization It exposes only lookups; caller identity and management operations belong to ControlClient.

func NewDataClient added in v0.41.0

func NewDataClient(directoryURL, inventoryURL string, key sshcert.RawPrivateKey, cfg tlsconfig.Config) (*DataClient, error)

NewDataClient configures the directory and inventory lookup endpoints in use. Empty endpoints are omitted; at least one is required. Each endpoint is signed for its own service audience using the configured reader key.

func (*DataClient) Host added in v0.41.0

func (c *DataClient) Host(ctx context.Context, name string) (*Host, error)

Host returns facts for a normalized hostname, or nil when absent. It validates the returned names, account restrictions and principal metadata before use.

func (*DataClient) User added in v0.41.0

func (c *DataClient) User(ctx context.Context, id string) (*User, error)

User returns active user facts for the exact authentication subject, or nil when absent or inactive. It validates identity and object attributes on every read.

type DirectoryAuditEvent added in v0.41.0

type DirectoryAuditEvent struct {
	Sequence   uint64    `json:"sequence"`
	Revision   uint64    `json:"revision"`
	Time       time.Time `json:"time"`
	Actor      string    `json:"actor"`
	Action     string    `json:"action"`
	ID         string    `json:"id"`
	Alias      string    `json:"alias,omitempty"`
	PreviousID string    `json:"previous-id,omitempty"`
}

DirectoryAuditEvent records one directory mutation. Sequence identifies the event independently of directory revisions: several events can belong to the same mutation, and zero starts a cursor at the beginning.

type DirectoryUser added in v0.41.0

type DirectoryUser struct {
	UserName     string   `json:"userName"`
	ID           string   `json:"id"`
	Active       bool     `json:"active"`
	Groups       []string `json:"groups"`
	UserType     string   `json:"userType,omitempty"`
	Department   string   `json:"department,omitempty"`
	Organization string   `json:"organization,omitempty"`
}

type EnrollmentToken added in v0.41.0

type EnrollmentToken struct {
	ID        string    `json:"id"`
	ExpiresAt time.Time `json:"expires-at"`
	UsedBy    string    `json:"used-by,omitempty"`
	Revoked   bool      `json:"revoked"`
}

EnrollmentToken is a single-use preapproval for host enrollment.

type GroupSnapshot added in v0.42.0

type GroupSnapshot struct {
	Revision uint64         `json:"revision"`
	Groups   []GroupSummary `json:"groups"`
}

GroupSnapshot is a coherent view of current provisioned groups.

type GroupSummary added in v0.42.0

type GroupSummary struct {
	ID          string `json:"id"`
	DisplayName string `json:"displayName"`
	ExternalID  string `json:"externalId,omitempty"`
}

GroupSummary exposes the current group name and identifiers.

type Host added in v0.41.0

type Host struct {
	wire.Host
	Revision Revision `json:"revision,omitzero"`
}

Host keeps the inventory account and principal validation contract while allowing optional revision metadata alongside it.

func (*Host) UnmarshalJSON added in v0.41.0

func (h *Host) UnmarshalJSON(data []byte) error

type HostAuditEvent added in v0.41.0

type HostAuditEvent struct {
	Sequence uint64    `json:"sequence"`
	At       time.Time `json:"at"`
	Actor    string    `json:"actor"`
	Action   string    `json:"action"`
	Resource string    `json:"resource"`
}

HostAuditEvent records one administrative change to host inventory.

type HostRecord added in v0.41.0

type HostRecord struct {
	ID        string    `json:"id"`
	Revision  uint64    `json:"revision"`
	Status    string    `json:"status"`
	Proposal  Proposal  `json:"host"`
	CreatedAt time.Time `json:"created-at"`
	UpdatedAt time.Time `json:"updated-at"`
}

HostRecord is one managed inventory record as administrators see it.

type Proposal added in v0.41.0

type Proposal struct {
	Names         []string          `json:"names"`
	Pattern       string            `json:"pattern,omitempty"`
	Labels        map[string]string `json:"labels"`
	Accounts      []string          `json:"accounts"`
	PrincipalMode string            `json:"principal-mode"`
	Realm         string            `json:"realm,omitempty"`
}

Proposal is the entire editable authorization record for one host. Admission and ownership are server-owned metadata, never fields a host can approve for itself. Accounts nil means unrestricted; an empty list permits no accounts.

func (*Proposal) UnmarshalJSON added in v0.41.0

func (p *Proposal) UnmarshalJSON(data []byte) error

UnmarshalJSON requires accounts at the input boundary. Explicit null is unrestricted; [] permits none. Accidentally omitting the field must not broaden access, so omission is an error rather than a default.

type Revision added in v0.41.0

type Revision struct {
	// contains filtered or unexported fields
}

Revision is optional opaque logging metadata, never a concurrency token.

func (Revision) IsZero added in v0.41.0

func (r Revision) IsZero() bool

IsZero distinguishes omitted metadata from a provider-supplied empty string.

func (Revision) MarshalJSON added in v0.41.0

func (r Revision) MarshalJSON() ([]byte, error)

func (Revision) String added in v0.41.0

func (r Revision) String() string

func (*Revision) UnmarshalJSON added in v0.41.0

func (r *Revision) UnmarshalJSON(data []byte) error

type SCIMRequest added in v0.41.0

type SCIMRequest struct {
	Method      string `json:"method"`
	Target      string `json:"target"`
	ContentType string `json:"contentType"`
	IfMatch     string `json:"ifMatch"`
	Body        []byte `json:"body"`
}

SCIMRequest preserves the public provisioning operation across the signed hop, including its conditional-write precondition and complete query parameters.

type SCIMResult added in v0.41.0

type SCIMResult struct {
	Status                                       int
	ContentType, ETag, Location, WWWAuthenticate string
	Body                                         []byte
}

SCIMResult owns the provisioning response body and SCIM-relevant metadata. SCIM success and error statuses are results; transport failures are Go errors.

type ServiceError added in v0.41.0

type ServiceError struct {
	Status  int
	Message string
}

ServiceError preserves a rejected operation's message and protocol status for the public HTTP adapter. Callers can use errors.Is for domain error categories.

func (*ServiceError) Error added in v0.41.0

func (e *ServiceError) Error() string

func (*ServiceError) Is added in v0.41.0

func (e *ServiceError) Is(target error) bool

type Signer added in v0.41.0

type Signer struct {
	// contains filtered or unexported fields
}

Signer mints request-bound JWTs signed with a service SSH private key.

func NewSigner added in v0.41.0

func NewSigner(privateKey sshcert.RawPrivateKey) (*Signer, error)

NewSigner creates a Signer from an SSH private key.

func NewSignerFor added in v0.41.0

func NewSignerFor(privateKey sshcert.RawPrivateKey, audience string) (*Signer, error)

func (*Signer) Authorize added in v0.41.0

func (s *Signer) Authorize(req *http.Request, body []byte) error

Authorize mints a request-bound JWT and sets the Authorization header. body may be nil (GET); the bh claim is then over the empty string.

func (*Signer) AuthorizeActor added in v0.41.0

func (s *Signer) AuthorizeActor(req *http.Request, body []byte, actor string) error

AuthorizeActor binds an authenticated human actor to this backend request. An empty actor is used for service operations such as enrollment and SCIM.

type User

type User struct {
	ID         string            `json:"id"`
	Names      object.Strings    `json:"name"`
	UserName   string            `json:"userName,omitempty"`
	Attributes object.Attributes `json:"attributes,omitempty"`
	Groups     []object.Object   `json:"groups"`
	Revision   Revision          `json:"revision,omitzero"`
}

func (User) PolicyUser added in v0.42.0

func (u User) PolicyUser() wire.User

PolicyUser retains the validated authorization facts and drops logging metadata.

type UserSnapshot added in v0.41.0

type UserSnapshot struct {
	Revision string          `json:"revision"`
	Users    []DirectoryUser `json:"users"`
}

UserSnapshot is the selected directory's authorization view. IDs identify users to OIDC and policy; groups are policy names, not SCIM resource IDs.

type Verifier added in v0.41.0

type Verifier struct {
	// contains filtered or unexported fields
}

Verifier checks request-bound JWTs against the CA's SSH public key.

func NewVerifier added in v0.41.0

func NewVerifier(publicKey sshcert.RawPublicKey) (*Verifier, error)

NewVerifier creates a Verifier from an SSH public key.

func NewVerifierFor added in v0.41.0

func NewVerifierFor(publicKey sshcert.RawPublicKey, audience string) (*Verifier, error)

func (*Verifier) Verify added in v0.41.0

func (v *Verifier) Verify(req *http.Request, body []byte) error

Verify checks the request's Authorization header JWT: signature, aud, exp/iat freshness, that htm/htu match the request actually received, and that bh matches sha256(body). It takes the request (rather than just the header) because method/target binding needs req.Method, req.Host, and req.URL.RequestURI().

func (*Verifier) VerifyActor added in v0.41.0

func (v *Verifier) VerifyActor(req *http.Request, body []byte) (string, error)

VerifyActor returns only the subject covered by a valid request signature.

Directories

Path Synopsis
Package control authenticates public requests and authorizes administrative operations, then invokes fact services through their typed clients.
Package control authenticates public requests and authorizes administrative operations, then invokes fact services through their typed clients.
Package directory owns managed identities, administration, and the user and group facts supplied to authorization.
Package directory owns managed identities, administration, and the user and group facts supplied to authorization.
scim
Package scim adapts SCIM provisioning to the directory storage contract.
Package scim adapts SCIM provisioning to the directory storage contract.
sqlitestore
Package sqlitestore implements the managed directory using embedded SQLite.
Package sqlitestore implements the managed directory using embedded SQLite.
Package inventory owns managed host facts, enrollment, patterns, and storage.
Package inventory owns managed host facts, enrollment, patterns, and storage.
sqlitestore
Package sqlitestore implements managed inventory using embedded SQLite.
Package sqlitestore implements managed inventory using embedded SQLite.
Package server serves built-in directory and inventory facts and their private management APIs.
Package server serves built-in directory and inventory facts and their private management APIs.
Package storage owns the database settings shared by the built-in fact stores.
Package storage owns the database settings shared by the built-in fact stores.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL