Documentation
¶
Overview ¶
Package credentials delivers explicitly sandbox-authorized credentials. Revocable credentials are encrypted and recorded durably before delivery; scope reductions and failed revocations survive process/replica changes.
Index ¶
- Variables
- func Scope(a *access.SeatAccess, connection string) (connectors.CredentialScope, error)
- type Connections
- type Ledger
- type Registry
- func (r *Registry) Issue(ctx context.Context, org, seatID string, a *access.SeatAccess, ...) (runtimeapi.CredentialResponse, error)
- func (r *Registry) Outstanding(org, seat string) int
- func (r *Registry) Reconcile(ctx context.Context, org string, _ map[string]*access.SeatAccess) []Revoked
- func (r *Registry) RevokeSeat(ctx context.Context, org, seatID string) []Revoked
- func (r *Registry) Sweep(ctx context.Context) []Revoked
- type Revoked
Constants ¶
This section is empty.
Variables ¶
var ErrForbidden = errors.New("credential not granted")
Functions ¶
func Scope ¶
func Scope(a *access.SeatAccess, connection string) (connectors.CredentialScope, error)
Scope returns the exact sandbox scope. Platform-only clauses never enter a sandbox credential. A single token cannot represent heterogeneous per-repository permissions, so that combination is rejected.
Types ¶
type Connections ¶
type Connections interface {
Tracker(orgID, key string) (connectors.Tracker, error)
}
Connections resolves the connection's current adapter. Revocation must be idempotent: retries include a remote success followed by a database failure.
type Ledger ¶ added in v0.7.0
type Ledger interface {
Seat(context.Context, string) (*store.Seat, error)
RecordIssuedCredential(context.Context, store.IssuedCredential, *access.SeatAccess) error
ListIssuedCredentials(context.Context) ([]store.IssuedCredential, error)
SetCredentialPending(context.Context, string) error
ClaimCredentialRevocation(context.Context, string) (string, error)
FinishCredentialRevocation(context.Context, string, string, bool) error
CountIssuedCredentials(context.Context, string, string) (int, error)
}
Ledger is shared by all replicas. Implementations must not fall back to process-local state when durability is unavailable.
type Registry ¶
type Registry struct {
Connections Connections
Ledger Ledger
EncryptionKey []byte
Log *slog.Logger
Now func() time.Time
}
Registry issues credentials only when current, durably checked access permits it. EncryptionKey is a stable 32-byte key shared by all replicas, kept outside the database. Never rotate it while outstanding rows remain.
func (*Registry) Issue ¶
func (r *Registry) Issue(ctx context.Context, org, seatID string, a *access.SeatAccess, connection string) (runtimeapi.CredentialResponse, error)
Issue persists a revocable credential before exposing it to the caller. seatID must be the authenticated stable seat UUID, never its reusable key. Access is read again before minting, and RecordIssuedCredential checks the same seat identity/access while holding a database lock before committing.
func (*Registry) Outstanding ¶
Outstanding counts unexpired revocable credentials. New callers should use the ledger count directly when they need to distinguish a database error.
func (*Registry) Reconcile ¶
func (r *Registry) Reconcile(ctx context.Context, org string, _ map[string]*access.SeatAccess) []Revoked
Reconcile uses current committed access, not the caller's snapshot, so a stale sync on another replica cannot preserve a revoked scope. The seats argument is retained for source compatibility; the durable store is authoritative.
func (*Registry) RevokeSeat ¶ added in v0.3.0
RevokeSeat makes existing credentials pending even if access is later restored. seatID is the stable identity, never its reusable key. Retries continue in Sweep after the retirement call returns.