The credential you keep distributing isn’t the credential you should be distributing
If your authorization server is OAuth 2.0–based and your workloads are SPIFFE-identified, you have a credential redundancy problem. The workload already holds a SPIFFE Verifiable Identity Document — an X.509-SVID or JWT-SVID or WIT-SVID — issued at runtime, bound to its identity, attested by the platform, rotated continuously. And then your deployment process distributes an OAuth client secret or a private-key JWT signing key out of band, alongside the SVID, so the workload can authenticate to the authorization server.
This as one of the most obvious-in-retrospect inefficiencies in the modern IAM stack. Why provision two credentials when one would do? Why deal with the operational burden of OAuth client secret rotation when SPIFFE has already solved short-lived credential issuance for you?
draft-ietf-oauth-spiffe-client-auth, co-authored by Pieter Kasselman, Arndt Schwenkschuster, Scott Rose (NIST), and Stian Thorgersen (IBM), is the answer. It profiles RFC 7521 (Assertion Framework for OAuth 2.0 Client Authentication), RFC 7523 (JWT Profile for OAuth 2.0 Client Authentication), and the OAuth 2.0 Attestation-Based Client Authentication draft to define exactly how an OAuth client uses its SVIDs to authenticate to an OAuth authorization server.
This article walks through the three authentication modes the profile defines, the Client ID Metadata Document integration that makes dynamic agent registration tractable, the bundle endpoint pattern for key distribution, and the security considerations that matter for production deployment.
What the profile actually defines
The draft (currently at version -01, adopted by the OAuth working group, last updated 2 March 2026, expires September 2026) defines three modes of OAuth client authentication using SPIFFE credentials, one for each SVID type:
- JWT-SVID client authentication — a profile of RFC 7523 (JWT Profile for OAuth 2.0 Client Authentication)
- 509-SVID client authentication — a profile of RFC 8705 (OAuth Mutual-TLS Client Authentication)
- WIT-SVID client authentication — a profile of draft-ietf-oauth-attestation-based-client-auth using the WIMSE Workload Identity Token
All three eliminate the need for client secrets. None require out-of-band credential distribution. All three integrate with OAuth Dynamic Client Registration (RFC 7591) and the new OAuth Client ID Metadata Document draft.
The interoperability rule from the draft: an authorization server MUST support at least one of JWT-SVID or X.509-SVID, advertising support via the standard token_endpoint_auth_methods_supported parameter in its RFC 8414 metadata. The new method names are spiffe_jwt, spiffe_wit, and spiffe_x509. A client MUST support at least one of JWT-SVID, WIT-SVID, or X.509-SVID, and SHOULD support all three to guarantee interoperability across deployments.
JWT-SVID client authentication
The JWT-SVID mode follows the RFC 7523 pattern with a SPIFFE-specific assertion type. A client authenticating to the token endpoint sends:

Two parameters distinguish this from a normal RFC 7523 flow:
client_assertion_type must be urn:ietf:params:oauth:client-assertion-type:jwt-spiffe. This is a new OAuth URI being registered by the draft — distinct from the generic RFC 7523 type — because the validation rules are SPIFFE-specific.
client_assertion is a SPIFFE JWT-SVID. The decoded payload looks like:

The authorization server’s validation rules are tightly specified:
- Verify the JWT is well-formed and contains sub, aud, and exp.
- Verify exp has not passed.
- Verify aud contains only the issuer identifier of the authorization server (per draft-ietf-oauth-rfc7523bis). Multiple audiences are not allowed.
- Verify the signature using the trust domain’s signing keys, retrieved per the bundle distribution rules (see below).
- Verify the SPIFFE ID in sub matches a recognized client identifier, either as an exact match against a registered client_id or — if the request uses a Client ID Metadata Document — as a match against the spiffe_id value in that document (with optional wildcard support).
The audience restriction is critical: it prevents an attacker who steals a JWT-SVID intended for one authorization server from replaying it against a different one. The signing-key validation rule is the other critical piece: the AS must validate against the trust domain’s keys, never against keys discovered from the JWT’s iss claim alone, to prevent token confusion attacks (a topic the security considerations section addresses at length).
X.509-SVID client authentication
X.509-SVID mode uses mutual TLS. The client establishes an mTLS connection to the token endpoint, presenting its X.509-SVID as the client certificate. The authorization server validates:
- Standard X.509 path validation against trust anchors for the relevant trust domain — not the system trust store.
- The certificate contains exactly one URI SAN with a valid SPIFFE ID.
- The certificate is a leaf certificate (CA:FALSE in Basic Constraints).
- The certificate has the digitalSignature key usage.
- The SPIFFE ID in the URI SAN matches a registered client identifier.
The token request itself is otherwise standard OAuth, with the client_id parameter containing the SPIFFE ID of the client (which must match the URI SAN of the presented certificate):

The mTLS handshake itself is the authentication — no separate client_assertion is needed. The draft is explicit that the server’s certificate must be validated by the client using the client’s system trust store, not the SPIFFE trust bundle. This avoids a circular dependency in the trust establishment chain.
WIT-SVID client authentication
The WIT-SVID mode is the most recent addition (introduced in -01 of the draft) and the most architecturally interesting because it combines two attestation layers. The WIT-SVID is the SPIFFE profile of the WIMSE Workload Identity Token (draft-ietf-wimse-workload-creds-00) and is key-bound: it contains a cnf claim with the workload’s public key.
When using WIT-SVID for client authentication, the workload sends two HTTP headers per draft-ietf-oauth-attestation-based-client-auth:

The OAuth-Client-Attestation header carries the WIT-SVID (with typ: wit+jwt):

The OAuth-Client-Attestation-PoP header carries a proof-of-possession JWT signed by the private key referenced in the WIT-SVID’s cnf claim:

The authorization server validates both: the WIT-SVID signature against the trust domain keys, the PoP signature against the cnf key. This closes the bearer-token loophole — possession of the WIT-SVID alone is not enough to authenticate, because the holder must also prove possession of the corresponding private key.
WIT-SVID is the right choice for agentic deployments where tokens may flow through intermediaries (API gateways, MCP relays, agent orchestrators) and you cannot rule out interception in transit. It’s also the natural credential for the transaction token flow covered in the next article in this series.
Client ID Metadata Documents: dynamic agent registration at scale
OAuth’s traditional client registration model — register clients up front, distribute client_id/client_secret to each one — does not scale to agentic deployments where instances appear and disappear continuously. Dynamic Client Registration (RFC 7591) helps but still requires a registration interaction per client.
The draft-ietf-oauth-client-id-metadata-document draft (also being progressed through the OAuth working group) lets the client_id itself be a URL that resolves to a JSON document containing client metadata. The OAuth SPIFFE Client Authentication profile defines two new metadata fields for use in such documents:
- spiffe_id (REQUIRED): the SPIFFE ID of the client. May end with /* to indicate a path-segment prefix match. For example, spiffe://example.org/agents/onboardid/* matches spiffe://example.org/agents/onboardid/registration-wizard but does not match spiffe://example.org/agents/onboardid-other.
- spiffe_bundle_endpoint (OPTIONAL): the URL of the SPIFFE Bundle Endpoint for the client’s trust domain. If omitted, the AS must obtain signing keys through some other mechanism (pre-configured bundle, etc.).
A client request using a Client ID Metadata Document looks like:

Where https://example.org/client/metadata.json resolves to:

The authorization server fetches the metadata document, validates that the JWT-SVID’s sub matches the spiffe_id (with prefix-match if a wildcard is used), and proceeds. New agent instances appear, get an SVID with a matching SPIFFE ID, and authenticate to the AS without any registration ceremony.
For agentic deployments where you might spin up a fresh agent per user session or per task, this is the unlock that makes the OAuth integration tractable.
Key distribution: do this, not that
The draft is unusually opinionated about key distribution. Section 6 prescribes the SPIFFE Bundle Endpoint as the recommended mechanism and explicitly lists several alternatives as “NOT RECOMMENDED” or worse.
The recommended pattern: the authorization server is configured with an explicit mapping from trust domain to Bundle Endpoint URL. For each trust domain it federates with, it has a configuration entry like:

The endpoint serves a JWKS-formatted document with keys typed by use (x509-svid, jwt-svid, wit-svid). The AS polls the endpoint periodically, respecting the spiffe_refresh_hint from the bundle (typically 300 seconds). Server authentication on the endpoint uses WebPKI — the bundle endpoint has a regular TLS server certificate trusted by the AS’s system trust store.
The explicitly discouraged alternatives, and why:
SPIFFE Workload API. Would require the AS itself to be a SPIFFE workload in a trust domain, which is a significant deployment constraint. Also creates ambiguity around federated trust domain bundles.
Manual configuration. Acceptable in small, static environments but doesn’t scale and requires human-mediated key rotation.
System trust store for X.509-SVID validation. Forbidden. Using the system trust store would allow any CA in it to issue a trusted X.509-SVID for any SPIFFE ID — an obvious privilege escalation. SPIFFE-native validation restricts SPIFFE-ID signing to the corresponding trust domain’s keys.
Using the JWT-SVID iss claim for key discovery. Allowed only as a compatibility fallback, subject to strict conditions. The security considerations section warns at length about token confusion: an attacker who can get the AS to discover keys based on an attacker-controlled iss claim can present an OAuth/OIDC token (issued for some other purpose) as if it were a JWT-SVID. The defense: the AS MUST NOT do issuer-based discovery unless the iss value is already known to it and explicitly bound to a configured SPIFFE Trust Domain, and MUST validate SVIDs against SVID-specific requirements (not just “it’s a JWT that validates”).
Implementation status
The draft tracks running code per RFC 7942. As of -01, one implementation is registered: Keycloak, with preview-maturity coverage of JWT-SVID client authentication using the SPIFFE Trust Bundle Endpoint. Keycloak is the natural early adopter — Stian Thorgersen (IBM), one of the draft’s co-authors, is a Keycloak project lead.
For enterprise IAM teams, this matters because Keycloak is the most widely deployed open-source identity platform in production today, including across DoD and federal environments. A preview implementation in Keycloak is a clear signal that this profile is exiting standards-track theory and entering deployable practice. Other major OAuth implementations — Ping, Okta, ForgeRock, Auth0 — are likely to follow as the draft moves toward IESG approval.
Security considerations that bite in production
Three security topics from the draft are worth surfacing for any architect planning to deploy this.
Audience restriction is not optional. The aud claim on a JWT-SVID used for client authentication must contain only the AS’s issuer identifier. Multi-audience JWT-SVIDs cannot be used for client authentication. This is the primary defense against cross-domain token replay.
Trust bundle misconfiguration is catastrophic. If an AS is misconfigured to trust the wrong bundle for a trust domain, an attacker holding a valid SVID from the wrong trust domain can authenticate as a legitimate client of the right one. The Bundle Endpoint URL must be configured authoritatively and out of band; do not rely on auto-discovery.
Token-type confusion is a real attack class. Don’t accept “JWT that validates and has a SPIFFE-looking sub” as proof of SVID-ness. The same JWT signing infrastructure may be used to issue OAuth access tokens, OIDC ID tokens, and SVIDs. The AS must validate against SVID-specific rules and against keys explicitly bound to a configured SPIFFE Trust Domain.
What this unlocks operationally
Once an organization has agents authenticating to its authorization server via SPIFFE SVIDs, the rest of the OAuth ecosystem becomes accessible without secret distribution. Token exchange flows (RFC 8693), JWT authorization grants (RFC 7523), refresh tokens, introspection, revocation — all of these work normally with SPIFFE-credentialed clients, just with the client authentication step replaced.
The operational profile shifts substantially:
- No more OAuth client secret rotation. SPIFFE handles credential rotation on its own clock (minutes), invisibly to the workload.
- No more shared secrets in configuration management. Vault, Sealed Secrets, External Secrets Operator — for OAuth client credentials, the entire chain becomes unnecessary.
- Per-instance accountability for agents. Each agent instance has a distinct SPIFFE ID (typically including an instance identifier in the path), so the audit log shows which instance authenticated, not just “an agent did.”
- First-use registration via Client ID Metadata Document. New agent instances appear and authenticate without registration ceremony, as long as their SPIFFE ID matches the metadata document’s wildcard.
For agentic deployments specifically, this is the bridge between “we have an OAuth-based authorization architecture” and “we have a workload-identity-based authentication architecture.” You don’t have to choose. The profile makes them the same thing.
The next article in this series picks up where this one ends: once an agent has a valid OAuth access token, how do you preserve user identity and authorization context as that agent fans out into a call chain across multiple downstream workloads? That’s the transaction tokens story.
Primary sources: draft-ietf-oauth-spiffe-client-auth-01 (Schwenkschuster, Kasselman, Rose, Thorgersen; March 2026); draft-ietf-oauth-rfc7523bis; draft-ietf-oauth-client-id-metadata-document-01; draft-ietf-oauth-attestation-based-client-auth-07; draft-ietf-wimse-workload-creds-00; RFC 7521, RFC 7523, RFC 7591, RFC 8414, RFC 8705.