Documentation
¶
Overview ¶
Package api manages project-local machine-to-machine API credentials. Administrative methods are trusted host operations, never bearer capabilities.
Index ¶
- Variables
- func WithActor(ctx context.Context, actor Actor) context.Context
- type Actor
- type AuditEvent
- type AuditReader
- type AuditedOperationStore
- type AuditedRetirementStore
- type AuditedStore
- type AuditedTimedStore
- type AuthenticationDetails
- type Cache
- type CacheFactory
- type Client
- type Config
- type Credential
- type CredentialDetails
- type IssueRequest
- type Issued
- type ManagementStore
- type NonExpiringStore
- type OperationReceipt
- type OperationResult
- type OperationSpec
- type OperationStore
- type Option
- type Principal
- type ReadResult
- type Record
- type RotateRequest
- type SecretVersion
- type SecretVersionInfo
- type Service
- func (s *Service) AuditEvents(ctx context.Context, before int64, limit int) ([]AuditEvent, error)
- func (s *Service) Authenticate(ctx context.Context, token string, required ...string) (Principal, error)
- func (s *Service) AuthenticateDetails(ctx context.Context, token string, required ...string) (AuthenticationDetails, error)
- func (s *Service) Client(ctx context.Context, id string) (Client, error)
- func (s *Service) Clients(ctx context.Context, after string, limit int) ([]Client, error)
- func (s *Service) Close() error
- func (s *Service) CreateClient(ctx context.Context, name string, scopes []string) (Client, error)
- func (s *Service) Credential(ctx context.Context, id string) (Credential, error)
- func (s *Service) CredentialDetails(ctx context.Context, id string) (CredentialDetails, error)
- func (s *Service) Credentials(ctx context.Context, clientID, after string, limit int) ([]Credential, error)
- func (s *Service) Errors() <-chan error
- func (s *Service) Issue(ctx context.Context, req IssueRequest) (Issued, error)
- func (s *Service) IssueOnce(ctx context.Context, id string, req IssueRequest) (OperationResult, error)
- func (s *Service) Operation(ctx context.Context, id string) (OperationReceipt, error)
- func (s *Service) PruneAuditEvents(ctx context.Context, before time.Time, limit int) (int64, error)
- func (s *Service) RetireVersion(ctx context.Context, credentialID, versionID string) error
- func (s *Service) Revoke(ctx context.Context, id string) error
- func (s *Service) RevokeAll(ctx context.Context, clientID string) error
- func (s *Service) Rotate(ctx context.Context, req RotateRequest) (Issued, error)
- func (s *Service) RotateOnce(ctx context.Context, id string, req RotateRequest) (OperationResult, error)
- func (s *Service) SecretVersions(ctx context.Context, id string, before int64, limit int) ([]SecretVersionInfo, error)
- func (s *Service) SetClientBanned(ctx context.Context, id string, banned bool) error
- func (s *Service) SetClientScopes(ctx context.Context, id string, scopes []string) error
- func (s *Service) Start(ctx context.Context) error
- func (s *Service) UsageStats() UsageStats
- type Snapshot
- type Source
- type Store
- type TimedStore
- type UsageConfig
- type UsageObservation
- type UsageStats
- type UsageStore
- type Watcher
- type WatcherWithErrors
Constants ¶
This section is empty.
Variables ¶
var ( ErrInvalid = errors.New("api: invalid input") ErrNotFound = errors.New("api: not found") ErrConflict = errors.New("api: conflict") ErrForbidden = errors.New("api: forbidden") ErrClosed = errors.New("api: closed") )
var ErrUnsupported = errors.New("api: unsupported capability")
ErrUnsupported means the configured adapter lacks an optional capability.
Functions ¶
Types ¶
type Actor ¶ added in v0.2.0
Actor is an identity verified by the trusted host, never by a business token.
type AuditEvent ¶ added in v0.2.0
type AuditEvent struct {
ID int64 `json:"id"`
Actor Actor `json:"actor"`
Action string `json:"action"`
ClientID string `json:"client_id,omitempty"`
CredentialID string `json:"credential_id,omitempty"`
VersionID string `json:"version_id,omitempty"`
OperationID string `json:"operation_id,omitempty"`
OccurredAt time.Time `json:"occurred_at"`
// Details is a whitelist of safe result metadata, never secrets or digests.
Details map[string]any `json:"details,omitempty"`
}
type AuditReader ¶ added in v0.2.0
type AuditedOperationStore ¶ added in v0.2.0
type AuditedOperationStore interface {
IssueOnceAudited(
ctx context.Context, actor Actor, spec OperationSpec, credential Credential, version SecretVersion, ttl time.Duration,
) (OperationReceipt, bool, error)
RotateOnceAudited(
ctx context.Context, actor Actor, spec OperationSpec, id string, generation int64,
version SecretVersion, ttl, grace time.Duration,
) (OperationReceipt, bool, error)
}
type AuditedRetirementStore ¶ added in v0.2.0
type AuditedStore ¶ added in v0.2.0
type AuditedStore interface {
CreateClientAudited(ctx context.Context, actor Actor, client Client) error
SetClientScopesAudited(ctx context.Context, actor Actor, id string, scopes []string) error
SetClientBannedAudited(ctx context.Context, actor Actor, id string, banned bool) error
IssueAudited(ctx context.Context, actor Actor, credential Credential, version SecretVersion) error
RotateAudited(
ctx context.Context, actor Actor, id string, generation int64, version SecretVersion, grace time.Duration, at time.Time,
) (Credential, error)
RevokeAudited(ctx context.Context, actor Actor, id string, at time.Time) error
RevokeAllAudited(ctx context.Context, actor Actor, id string, at time.Time) error
}
AuditedStore implementations record every successful administrative command in the same transaction as its mutation, and reject invalid actors.
type AuditedTimedStore ¶ added in v0.2.0
type AuditedTimedStore interface {
IssueWithLifetimeAudited(
ctx context.Context, actor Actor, credential Credential, version SecretVersion, ttl time.Duration,
) (Credential, SecretVersion, error)
RotateWithLifetimeAudited(
ctx context.Context, actor Actor, id string, generation int64, version SecretVersion, ttl, grace time.Duration,
) (Credential, SecretVersion, error)
}
type AuthenticationDetails ¶ added in v0.2.0
type Cache ¶
type Cache interface {
Start(ctx context.Context) error
Lookup(ctx context.Context, key string, change uint64) (ReadResult, error)
Invalidate()
Close() error
}
Cache implementations never decide authorization. Start owns workers until Close; constructors must be side-effect free. Returned values are immutable.
type CacheFactory ¶
type Credential ¶
type Credential struct {
ID string `json:"id"`
ClientID string `json:"client_id"`
Name string `json:"name"`
Scopes []string `json:"scopes"`
Generation int64 `json:"generation"`
RevokedAt *time.Time `json:"revoked_at,omitempty"`
CreatedAt time.Time `json:"created_at"`
}
Credential is a stable access grant. Rotation changes its secret, not its ID.
type CredentialDetails ¶ added in v0.2.0
type CredentialDetails struct {
Credential Credential `json:"credential"`
ClientBanned bool `json:"client_banned"`
EffectiveScopes []string `json:"effective_scopes"`
CurrentVersion SecretVersionInfo `json:"current_version"`
UnexpiredVersions int `json:"unexpired_versions"`
LastUsedAt *time.Time `json:"last_used_at,omitempty"`
}
type IssueRequest ¶
type Issued ¶
type Issued struct {
NonExpiring bool `json:"non_expiring"`
Credential Credential `json:"credential"`
Token string `json:"token"`
ExpiresAt time.Time `json:"expires_at"`
}
Issued is the only administrative result containing the plaintext token. Do not log or persist Token. It cannot be recovered from the store.
type ManagementStore ¶ added in v0.2.0
type NonExpiringStore ¶ added in v0.2.0
type NonExpiringStore interface {
SupportsNonExpiring() bool
}
NonExpiringStore advertises explicit support for zero-expiry permanent secrets. Stores must preserve the flag and enforce finite retirement during rotation.
type OperationReceipt ¶ added in v0.2.0
type OperationReceipt struct {
Fingerprint [32]byte `json:"-"`
ID string `json:"id"`
Kind string `json:"kind"`
Credential Credential `json:"credential"`
Version SecretVersionInfo `json:"version"`
CommittedAt time.Time `json:"committed_at"`
}
OperationReceipt is immutable proof of a committed operation, not current state. It never contains a token or verification digest. Retain it without expiration.
type OperationResult ¶ added in v0.2.0
type OperationResult struct {
Receipt OperationReceipt `json:"receipt"`
Issued *Issued `json:"issued,omitempty"`
}
type OperationSpec ¶ added in v0.2.0
OperationSpec identifies a logical request. Fingerprint is a SHA-256 of its normalized requested parameters and actor (when auditing is enabled).
type OperationStore ¶ added in v0.2.0
type OperationStore interface {
Operation(ctx context.Context, id string) (OperationReceipt, error)
IssueOnce(
ctx context.Context, spec OperationSpec, credential Credential, version SecretVersion, ttl time.Duration,
) (OperationReceipt, bool, error)
RotateOnce(
ctx context.Context, spec OperationSpec, id string, generation int64, version SecretVersion, ttl, grace time.Duration,
) (OperationReceipt, bool, error)
}
OperationStore commits receipt and mutation atomically. A matching replay is checked before current client/generation policy; it returns applied=false. ErrNotFound from Operation means not observed, not proof of rollback.
type Option ¶
type Option func(*settings) error
func WithAudit ¶ added in v0.2.0
func WithAudit() Option
WithAudit requires transactional audit support and a host-verified Actor for writes.
func WithCache ¶
func WithCache(factory CacheFactory, maxStaleness time.Duration) Option
WithCache opts into bounded-staleness verification. The duration is mandatory and may be seconds or minutes. Expiry of the actual secret is always enforced.
func WithNonExpiring ¶ added in v0.2.0
func WithNonExpiring() Option
WithNonExpiring permits explicit permanent issuance. Finite defaults remain unchanged. Existing permanent credentials authenticate without this option.
func WithUsageTracking ¶ added in v0.2.0
func WithUsageTracking(cfg UsageConfig) Option
WithUsageTracking enables bounded, best-effort LastUsedAt collection. Zero fields use defaults; failure to persist statistics never denies access.
type ReadResult ¶
ReadResult and Snapshot carry conservative monotonic freshness metadata.
type Record ¶
type Record struct {
Client Client
Credential Credential
Secret SecretVersion
}
Record must come from one consistent database statement/snapshot.
type RotateRequest ¶
type SecretVersion ¶
type SecretVersion struct {
ID string
CredentialID string
Generation int64
Digest [32]byte
ExpiresAt time.Time
NonExpiring bool `json:"non_expiring"`
CreatedAt time.Time
}
SecretVersion contains verification material, never a plaintext secret. ExpiresAt includes any earlier retirement deadline introduced by rotation. NonExpiring requires a zero ExpiresAt; finite versions require a nonzero expiry.
type SecretVersionInfo ¶ added in v0.2.0
type SecretVersionInfo struct {
NonExpiring bool `json:"non_expiring"`
ID string `json:"id"`
CredentialID string `json:"credential_id"`
Generation int64 `json:"generation"`
CreatedAt time.Time `json:"created_at"`
ExpiresAt time.Time `json:"expires_at"`
LastUsedAt *time.Time `json:"last_used_at,omitempty"`
}
SecretVersionInfo contains safe administrative metadata only.
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
Service owns verification and optional workers, but never the Store's pool. New is side-effect free. Strict verification needs no Start; caches do.
func (*Service) AuditEvents ¶ added in v0.2.0
AuditEvents lists newest events first; before=0 starts at the newest event.
func (*Service) Authenticate ¶
func (s *Service) Authenticate(ctx context.Context, token string, required ...string) (Principal, error)
Authenticate verifies the secret and every requested scope. No returned slice aliases the Store or cache. Errors never include the supplied token.
func (*Service) AuthenticateDetails ¶ added in v0.2.0
func (s *Service) AuthenticateDetails(ctx context.Context, token string, required ...string) (AuthenticationDetails, error)
AuthenticateDetails verifies access and returns safe secret-version metadata.
func (*Service) Close ¶
Close cancels workers and in-flight operations and waits for their completion.
func (*Service) CreateClient ¶
func (*Service) Credential ¶
func (*Service) CredentialDetails ¶ added in v0.2.0
CredentialDetails reads consistent current management state from the primary.
func (*Service) Credentials ¶
func (*Service) Errors ¶
Errors reports recoverable cache/notification failures and unexpected watcher termination. Delivery is nonblocking and rate limited; use separate metrics for counting every failure. Freshness deadlines still apply.
func (*Service) IssueOnce ¶ added in v0.2.0
func (s *Service) IssueOnce(ctx context.Context, id string, req IssueRequest) (OperationResult, error)
IssueOnce creates at most one committed credential per schema and operation ID. A replay returns a receipt without the unrecoverable plaintext token.
func (*Service) Operation ¶ added in v0.2.0
Operation returns a committed receipt. ErrNotFound does not prove rollback.
func (*Service) PruneAuditEvents ¶ added in v0.2.0
PruneAuditEvents removes only the host-selected historical window in small batches.
func (*Service) RetireVersion ¶ added in v0.2.0
RetireVersion shortens only a historical version's deadline, never the current one.
func (*Service) RotateOnce ¶ added in v0.2.0
func (s *Service) RotateOnce(ctx context.Context, id string, req RotateRequest) (OperationResult, error)
RotateOnce makes a generation-checked rotation safe to retry with the same ID.
func (*Service) SecretVersions ¶ added in v0.2.0
func (s *Service) SecretVersions(ctx context.Context, id string, before int64, limit int) ([]SecretVersionInfo, error)
SecretVersions lists newest generations first; zero before starts at the newest.
func (*Service) SetClientBanned ¶
func (*Service) SetClientScopes ¶
func (*Service) Start ¶
Start begins optional cache and notification workers. It may be called once. Canceling ctx stops workers and makes further operations unavailable.
func (*Service) UsageStats ¶ added in v0.2.0
func (s *Service) UsageStats() UsageStats
UsageStats reports local collection state. Missing observations never prove that a key is unused; other replicas and dropped observations are not included.
type Source ¶
type Source interface {
Lookup(ctx context.Context, secretID string) (ReadResult, error)
Snapshot(ctx context.Context) (Snapshot, error)
Now() time.Time
MaxStaleness() time.Duration
}
Source binds a cache to exactly the Service and Store it was constructed for.
type Store ¶
type Store interface {
CreateClient(ctx context.Context, client Client) error
Client(ctx context.Context, id string) (Client, error)
Clients(ctx context.Context, afterID string, limit int) ([]Client, error)
SetClientScopes(ctx context.Context, id string, scopes []string) error
SetClientBanned(ctx context.Context, id string, banned bool) error
Issue(ctx context.Context, cred Credential, version SecretVersion) error
Credential(ctx context.Context, id string) (Credential, error)
Credentials(ctx context.Context, clientID, afterID string, limit int) ([]Credential, error)
// Rotate locks client then credential; rejects banned/revoked state and a
// mismatched generation. Only the preceding current secret's expiry is
// shortened to min(original expiry, at+grace). Older deadlines never extend.
Rotate(
ctx context.Context, credID string, expectedGeneration int64, version SecretVersion, gracePeriod time.Duration, at time.Time,
) (Credential, error)
Revoke(ctx context.Context, id string, at time.Time) error
RevokeAll(ctx context.Context, clientID string, at time.Time) error
Lookup(ctx context.Context, secretID string) (Record, error)
// Snapshot is all-or-nothing, keyed by secret version ID; expired or revoked
// rows may be omitted. Partial query/scan/iteration results are errors.
Snapshot(ctx context.Context) (map[string]Record, error)
}
Store implementations are concurrent-safe and enforce administrative invariants transactionally, not only in Service prechecks. Reads must use the authority's primary. Returned records belong to the caller, including slices and pointers.
type TimedStore ¶
type TimedStore interface {
IssueWithLifetime(
ctx context.Context, cred Credential, version SecretVersion, ttl time.Duration,
) (Credential, SecretVersion, error)
RotateWithLifetime(
ctx context.Context, credID string, expectedGeneration int64, version SecretVersion, ttl, grace time.Duration,
) (Credential, SecretVersion, error)
}
TimedStore is an optional Store capability for assigning Issue and Rotate deadlines after authority locks are acquired. Returned times are the values actually committed. Stores without it retain the original Store contract.
type UsageConfig ¶ added in v0.2.0
type UsageObservation ¶ added in v0.2.0
type UsageStats ¶ added in v0.2.0
type UsageStore ¶ added in v0.2.0
type UsageStore interface {
RecordUsage(ctx context.Context, observations []UsageObservation) error
}
UsageStore merges times monotonically without authorization invalidation. Missing/pruned versions are ignored, never reinserted.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
cache
|
|
|
arc
Package arc provides an optional bounded-staleness ARC adapter.
|
Package arc provides an optional bounded-staleness ARC adapter. |
|
rcu
Package rcu provides a whole-snapshot bounded-staleness cache adapter.
|
Package rcu provides a whole-snapshot bounded-staleness cache adapter. |
|
examples
|
|
|
access
command
Command access demonstrates project-local M2M credential administration and a single protected HTTP endpoint.
|
Command access demonstrates project-local M2M credential administration and a single protected HTTP endpoint. |
|
Package httpapi adapts API credential verification to net/http.
|
Package httpapi adapts API credential verification to net/http. |
|
Package postgres provides the PostgreSQL authority for api credentials.
|
Package postgres provides the PostgreSQL authority for api credentials. |