You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Forge agents authenticate inbound callers via the auth provider chain (auth.providers, first-match-wins: oidc, aws_sigv4, gcp_iap, azure_ad, http_verifier, static_token). Today, agent-to-agent and platform-to-agent auth means registering an OIDC resource app per agent in Okta — which doesn't scale to agent fleets and has no agent-native construct.
Once agents get SPIFFE identity from a managed SPIRE plane (initializ/console-next#6, forge#239), the same SVID should serve inbound: the agent presents it as its server identity, and callers that are workloads present their own SVIDs. This issue adds a spiffe inbound auth provider so caller identity is a SPIFFE ID validated against the SPIRE trust bundle — no per-agent Okta resource app.
Proposed control
A spiffe provider in the existing auth chain (analogous to the oidc provider), with two modes:
JWT-SVID bearer (minimal path). Caller presents a JWT-SVID (sub = caller SPIFFE ID, aud = this agent's SPIFFE ID). The agent validates it against the SPIRE trust bundle (the JWT signing keys' JWKS, rooted in the customer KMS per Modular skills architecture with trust model and security analyzer #6) — structurally the same as the current OIDC bearer flow, issuer = SPIRE. Slots into the existing bearer chain with minimal transport change.
X.509-SVID mTLS (fuller mode). Mutual TLS: the agent presents its SVID and requires + verifies the caller's client SVID against the trust bundle. Either terminated in-process (agent TLS server config) or by a SPIFFE-aware mesh/gateway (Istio/Envoy) that forwards the verified identity.
Authorize by SPIFFE ID — an allowlist/policy (e.g. only spiffe://<td>/agent/frontend may call), rather than Okta audience/scope.
Agent Card advertises the SPIFFE scheme in securitySchemes (via the existing PopulateSecuritySchemes derivation) so callers discover how to authenticate.
Hybrid via the chain — spiffe for internal agent-to-agent / platform-to-agent; keep oidc for external/human callers. First-match-wins.
Scope: Kubernetes-first (SVIDs from the k8s_psat-attested SPIRE plane). JWT-SVID is the minimal deliverable; X.509 mTLS is the fuller mode.
Acceptance criteria
spiffe provider registered in the auth chain; selectable alongside oidc (both can be active — first-match-wins).
JWT-SVID validation against the SPIRE trust bundle (KMS-rooted), with bundle auto-rotation; invalid/expired/wrong-audience SVIDs are rejected with the standard auth failure (auth_fail audit event).
X.509-SVID mTLS mode: agent presents its SVID and verifies caller SVIDs against the bundle (in-process or mesh-terminated with forwarded identity).
Authorization by caller SPIFFE ID (allowlist/policy); unauthorized SPIFFE IDs are denied even with a valid SVID.
Agent Card advertises the SPIFFE security scheme.
Coexists with oidc in the chain (SPIFFE for internal callers, OIDC for external) without per-agent Okta resource apps.
Problem
Forge agents authenticate inbound callers via the auth provider chain (
auth.providers, first-match-wins:oidc,aws_sigv4,gcp_iap,azure_ad,http_verifier,static_token). Today, agent-to-agent and platform-to-agent auth means registering an OIDC resource app per agent in Okta — which doesn't scale to agent fleets and has no agent-native construct.Once agents get SPIFFE identity from a managed SPIRE plane (initializ/console-next#6, forge#239), the same SVID should serve inbound: the agent presents it as its server identity, and callers that are workloads present their own SVIDs. This issue adds a
spiffeinbound auth provider so caller identity is a SPIFFE ID validated against the SPIRE trust bundle — no per-agent Okta resource app.Proposed control
A
spiffeprovider in the existing auth chain (analogous to theoidcprovider), with two modes:sub= caller SPIFFE ID,aud= this agent's SPIFFE ID). The agent validates it against the SPIRE trust bundle (the JWT signing keys' JWKS, rooted in the customer KMS per Modular skills architecture with trust model and security analyzer #6) — structurally the same as the current OIDC bearer flow, issuer = SPIRE. Slots into the existing bearer chain with minimal transport change.Common to both:
spiffe://<td>/agent/frontendmay call), rather than Okta audience/scope.securitySchemes(via the existingPopulateSecuritySchemesderivation) so callers discover how to authenticate.spiffefor internal agent-to-agent / platform-to-agent; keepoidcfor external/human callers. First-match-wins.Scope: Kubernetes-first (SVIDs from the
k8s_psat-attested SPIRE plane). JWT-SVID is the minimal deliverable; X.509 mTLS is the fuller mode.Acceptance criteria
spiffeprovider registered in the auth chain; selectable alongsideoidc(both can be active — first-match-wins).auth_failaudit event).oidcin the chain (SPIFFE for internal callers, OIDC for external) without per-agent Okta resource apps.Conformance test
TestSpiffeProvider_ValidJWTSVIDAccepted/_ExpiredOrWrongAudienceRejectedTestSpiffeProvider_AuthorizesBySpiffeID(valid SVID, unlisted SPIFFE ID -> denied)TestAuthChain_SpiffeAndOidcCoexistOut of scope
oidcstays in the chain for people.References