4.2 KiB
4.2 KiB
OIDC Workload Attestation
How the oidc-attestor plugin identifies workloads via OIDC tokens.
Flow
Workload SPIRE Agent oidc-attestor OIDC Provider
| | | |
| FetchX509SVID | | |
|----------------->| | |
| | Attest(pid=1234) | |
| |------------------->| |
| | | GET /.well-known/ |
| | | openid-configuration|
| | |-------------------->|
| | | JWKS endpoint |
| | |<--------------------|
| | | |
| | | Read token from |
| | | /var/run/secrets/ |
| | | oidc/token |
| | | |
| | | Verify signature |
| | | via JWKS |
| | | |
| | Selectors | |
| |<-------------------| |
| X509-SVID | | |
|<-----------------| | |
Token Discovery
The plugin discovers the workload's OIDC token via a configurable path. In Kubernetes, the token is typically projected into the pod filesystem:
# Pod spec
volumes:
- name: oidc-token
projected:
sources:
- serviceAccountToken:
audience: spire
expirationSeconds: 3600
path: token
containers:
- name: app
volumeMounts:
- name: oidc-token
mountPath: /var/run/secrets/oidc
readOnly: true
Plugin configuration:
WorkloadAttestor "guildhouse_oidc" {
plugin_cmd = "/opt/spire/plugins/oidc-attestor"
plugin_data {
issuer = "https://keycloak.guildhouse.example.org/realms/platform"
audience = "spire"
token_path = "/var/run/secrets/oidc/token"
}
}
Token Verification
- Plugin reads the JWT from the configured path.
- Fetches the OIDC discovery document from
{issuer}/.well-known/openid-configuration. - Retrieves the JWKS from the
jwks_uriin the discovery document. - Verifies the JWT signature using the matching key from the JWKS.
- Validates standard claims:
issmatches configured issuer,audincludes configured audience,expis in the future.
Selector Output
The plugin returns selectors that SPIRE uses to match workloads against registration entries:
| Selector | Source Claim | Example |
|---|---|---|
oidc_attestor:iss:<value> |
iss |
oidc_attestor:iss:https://keycloak.example.org/realms/platform |
oidc_attestor:sub:<value> |
sub |
oidc_attestor:sub:f47ac10b-58cc-4372-a567-0e02b2c3d479 |
oidc_attestor:email:<value> |
email |
oidc_attestor:email:operator@guildhouse.coop |
oidc_attestor:group:<value> |
groups[] |
oidc_attestor:group:platform-engineers |
Registration Entry Matching
To grant an SVID to workloads authenticated via OIDC:
spire-server entry create \
-spiffeID spiffe://guildhouse.io/ns/prod/sa/web-server \
-parentID spiffe://guildhouse.io/spire/agent/k8s_psat/guildhouse/... \
-selector oidc_attestor:sub:f47ac10b-58cc-4372-a567-0e02b2c3d479
Multiple selectors can be combined (AND logic):
spire-server entry create \
-spiffeID spiffe://guildhouse.io/ns/prod/sa/admin-tool \
-parentID spiffe://guildhouse.io/spire/agent/k8s_psat/guildhouse/... \
-selector oidc_attestor:iss:https://keycloak.example.org/realms/platform \
-selector oidc_attestor:group:platform-engineers
JWKS Caching
The plugin caches JWKS responses for the duration specified by the Cache-Control header (or 5 minutes if not present). This avoids hitting the OIDC provider on every attestation.