Documentation
¶
Overview ¶
Package identity defines the per-run workload identity contract. One provider exists today: embedded, a SPIFFE-shaped JWT issuer (sub-ms mint, denylist+TTL revocation, runner-asserted attestation, a strict SPIFFE subset via go-spiffe — no custom attestation or federation). spire (real SPIRE, per-run child entries, node attestation) is planned for v0.5, not yet implemented.
INVARIANT (Confinement gating): cloud STS federation and hostile multi-tenant workloads hard-require the (not-yet-built) spire provider; embedded must refuse to mint identities whose grants include types.GrantCloudSTS.
Index ¶
Constants ¶
const ( // RunTokenTTL bounds the embedded identity and sidecar renewal give-up window. RunTokenTTL = time.Hour // RunTokenLapseAfter includes the control-plane stamp/skew allowance. Both // the org sweeper and offline runner contain egress after this same window. RunTokenLapseAfter = RunTokenTTL + 5*time.Minute )
Variables ¶
This section is empty.
Functions ¶
func Names ¶
func Names() []string
Names returns the registered provider names (for /healthz and error messages).
func Register ¶
func Register(name string, c Constructor)
Register adds an identity-provider implementation; call it from an init().
Types ¶
type Claims ¶
type Claims struct {
// SPIFFEID is spiffe://<trust-domain>/agent-run/<run-id>.
SPIFFEID string
RunID uuid.UUID
// Sub is the human principal the run acts on behalf of.
Sub string
// Sponsor is the accountable human owner (defaults to Sub).
Sponsor string
// OperatorOwned says the run's owner is the operator itself (admin token, local mode),
// not a person — decided from what authenticated the request, never from Sub
// (IdP-spoofable), and signed into the token.
OperatorOwned bool
// JTI uniquely identifies this token for revocation/audit join.
JTI string
// Audience the token was minted for (RFC 8707 discipline).
Audience string
IssuedAt time.Time
Expiry time.Time
}
Claims is the verified content of a run identity token; the delegation chain is first-class — Sub is the human principal, Act is the agent run.
type Constructor ¶
Constructor builds a Provider from Deps.
type Deps ¶
type Deps struct {
SigningKey *ecdsa.PrivateKey // embedded signs with this; nil => generated
TrustDomain string
Revocations RevocationStore // kill-switch denylist (pg-backed in production)
Audit audit.Recorder
}
Deps are the platform primitives an identity.Provider constructor may use. An impl ignores fields it does not need and reads its own config from the env in its constructor.
type ExpiredTokenError ¶ added in v0.7.2
ExpiredTokenError is the typed refusal for a presented token whose ONLY defect is expiry — signature and audience were good, and the token names a run. It carries that run id so the API's internal-auth boundary can record a dead-identity call against the right run (run.identity.expire), since callers otherwise see only an error.
NOT an authorization result: Verify still returns nil claims with it, and callers must keep failing closed. A provider that can't resolve the run id returns an ordinary error instead, so the fallback is silence, not a row keyed to the wrong run.
func (*ExpiredTokenError) Error ¶ added in v0.7.2
func (e *ExpiredTokenError) Error() string
func (*ExpiredTokenError) Unwrap ¶ added in v0.7.2
func (e *ExpiredTokenError) Unwrap() error
type Provider ¶
type Provider interface {
// Name returns "embedded" or "spire" — surfaced in UI/audit so the trust boundary is always visible.
Name() string
// MintRunIdentity creates the run's identity; audience binds the token, operatorOwned becomes Claims.OperatorOwned.
MintRunIdentity(ctx context.Context, runID uuid.UUID, humanSub, sponsor, audience string, operatorOwned bool) (RunIdentity, error)
// Verify authenticates a presented token and returns its claims; revoked or expired tokens must fail closed.
Verify(ctx context.Context, token, expectedAudience string) (*Claims, error)
// RevokeRun invalidates ALL identities for a run (kill-switch cascade).
RevokeRun(ctx context.Context, runID uuid.UUID) error
}
Provider mints, verifies, and revokes per-run identities.
type RevocationStore ¶
type RevocationStore interface {
IsRevoked(ctx context.Context, jti string, runID uuid.UUID) (bool, error)
RevokeRun(ctx context.Context, runID uuid.UUID) error
RevokeJTI(ctx context.Context, jti string, runID uuid.UUID) error
}
RevocationStore backs the kill-switch denylist for run identities. The pg-backed implementation lives in the control plane (cmd/wardynd); the embedded provider ships an in-memory one for tests.
All read methods MUST fail closed: a provider treats any IsRevoked error as a revoked token. RevokeRun is the kill-switch cascade (invalidates every current and future token for a run without enumerating jtis).
Directories
¶
| Path | Synopsis |
|---|---|
|
Package embedded implements the default, SPIFFE-shaped JWT-SVID identity provider satisfying identity.Provider.
|
Package embedded implements the default, SPIFFE-shaped JWT-SVID identity provider satisfying identity.Provider. |
|
Package identitytest provides a reusable conformance suite for any identity.Provider implementation, so the blessed default (embedded) and a future alternate (SPIRE) are held to the identical security contract.
|
Package identitytest provides a reusable conformance suite for any identity.Provider implementation, so the blessed default (embedded) and a future alternate (SPIRE) are held to the identical security contract. |