identity

package
v0.8.2 Latest Latest
Warning

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

Go to latest
Published: Sep 30, 2026 License: Apache-2.0 Imports: 6 Imported by: 0

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

This section is empty.

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

type Constructor func(Deps) (Provider, error)

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

type ExpiredTokenError struct {
	RunID uuid.UUID
	Err   error
}

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.

func New

func New(name string, d Deps) (Provider, error)

New constructs the identity provider selected by name (empty => default).

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).

type RunIdentity

type RunIdentity struct {
	SPIFFEID string
	// Token is the JWT-SVID (or embedded JWT) presented by sidecars and the in-sandbox credential helper when calling the broker.
	Token  string
	JTI    string
	Expiry time.Time
}

RunIdentity is what a provider mints at sandbox start.

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.

Jump to

Keyboard shortcuts

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