Skip to main content

WIT-SVID (Workload Identity Token)

Preview feature

WIT-SVID is a forward-looking feature and is off by default. Contact Defakto support to enable it for your organization. The token format follows a draft IETF/SPIFFE specification that may still change, so it is not yet recommended for production use.

A JWT-SVID is a bearer token: Anyone who holds it can present it and impersonate the workload. If a JWT-SVID leaks, an attacker can replay it until it expires.

A WIT-SVID closes that gap by being cryptographically bound to a key pair held by the workload. The token embeds the workload's proof-of-possession (PoP) public key in a cnf claim (RFC 7800) and is delivered together with the matching private key. A verifier can require the presenter to prove possession of that private key, so a stolen WIT-SVID alone is not enough to impersonate the workload.

WIT-SVID implements the SPIFFE WIT Workload API profile, built on the IETF WIMSE Workload Identity Token draft.

JWT-SVID compared with WIT-SVID

JWT-SVIDWIT-SVID
Token type (typ)JWTwit+jwt
Bearer or bound?BearerBound to a PoP key pair
Workload receivesToken onlyToken and private key
Replay protectionNone (expiry only)Proof-of-possession
aud (audience)RequiredProhibited
Bundle formatJWK SetJWK Set (keys tagged use: "wit-svid")

How it works

The Agent generates the proof-of-possession key pair. The workload calls the Workload API and receives both the token and its private key.

Key points:

  • The private key never leaves the Agent host until it is handed to your workload, and it is never sent to the Trust Domain Server. The server only sees the public key (in cnf).
  • FetchWITSVID is a streaming RPC. Your workload keeps the stream open, and the Agent pushes a new WIT-SVID before the current one expires. This mirrors the X.509-SVID streaming model, and differs from the JWT-SVID model.
  • The PoP key pair is EC P-256 by default.

What's in a WIT-SVID

A WIT-SVID is a JWS (signed JWT) with these characteristics:

Claim / headerValue
typ (header)wit+jwt
subThe workload's SPIFFE ID
exp, iatExpiry and issued-at timestamps
jtiA random ID for log correlation. WIT-SVID verification does not rely on jti for replay protection.
cnf{ "jwk": <PoP public key> }. The proof-of-possession binding (RFC 7800).
issOmitted. The trust domain is conveyed by sub; WIT-SVIDs deliberately are not OIDC-discoverable.
audNever present. Prohibited by the spec.

Example decoded payload:

{
"sub": "spiffe://example.org/workload/payments",
"exp": 1750000000,
"iat": 1749996400,
"jti": "a1b2c3d4e5f6...",
"cnf": {
"jwk": {
"kty": "EC",
"crv": "P-256",
"alg": "ES256",
"x": "...",
"y": "..."
}
}
}

Signing keys and trust bundles

WIT-SVIDs are signed with a dedicated WIT signing key, separate from the X.509 and JWT signing keys. This allows independent rotation of WIT keys, and keeps the credential types cryptographically isolated. The WIT signing key is provisioned automatically per key set (default EC P-256) and rotated as part of the normal key-set lifecycle.

Verifiers fetch the WIT validation keys through the Workload API's FetchWITBundles RPC, which returns trust bundles as JWK Sets keyed by trust domain. Each WIT key in the set carries use: "wit-svid", which is how clients distinguish WIT authorities from JWT authorities within a unified SPIFFE bundle.

Next, enable WIT-SVID and provision the signing key.