Universal OIDC Workload Federation
RFC 7517 / 7519
Static API tokens and long-lived credentials stored in CI/CD variables are a major attack vector for supply chain breaches. Sovereign Vault v0.3.0 implements a Universal OpenID Connect (OIDC) Workload Identity Engine in pure Rust (ring 0.17), allowing external workloads to exchange ephemeral cryptographic JWTs for least-privilege vault paths with zero static tokens.
1. Cryptographic Specifications & Algorithms
Supported Signing Algorithms
- • RS256, RS384, RS512: RSA PKCS#1 v1.5 with SHA-2
- • ES256, ES384: ECDSA on P-256 / P-384 curves
- • EdDSA: Edwards-curve Digital Signature (Ed25519)
- • Zero OpenSSL: 100% pure-Rust cryptographic engine
Autonomous JWKS Cache Engine
- • In-memory public key cache refreshed every 15 minutes (900s)
- • Immediate ad-hoc refresh upon binding enrollment or revocation
- • Manual refresh via
POST /v1/sys/oidc/refresh - • Air-gapped fallback via static inline JWKS JSON support
2. Built-In Provider Presets
Preset shortcuts eliminate manual JWKS URL discovery and certificate configuration:
| Preset | Issuer URL | Default Audience |
|---|---|---|
| github | https://token.actions.githubusercontent.com | https://github.com/{owner} |
| kubernetes | https://kubernetes.default.svc | sovereign-vault |
| gitlab | https://gitlab.com | https://gitlab.com |
| https://accounts.google.com | Configurable client ID | |
| azure | https://login.microsoftonline.com/{tenant}/v2.0 | api://AzureADTokenExchange |
| authelia / dex | Local homelab IdP endpoint | sovereign-vault |
| custom | Any RFC 8414 OpenID discovery endpoint | Custom audience |
3. End-to-End Example: GitHub Actions Tokenless CI/CD
Step 1: Enroll GitHub Actions trust binding on Sovereign Vault:
sovereign-vault oidc enroll \
--preset github \
--project payments-svc \
--name gh-main-deploy \
--subject-pattern "repo:my-org/payments:ref:refs/heads/main" \
--path "apps/payments/*" \
--cap read Step 2: Authenticate in your GitHub Actions workflow with zero static secrets:
name: Deploy Payments Microservice
on:
push:
branches: [main]
permissions:
id-token: write # Mandatory to request short-lived OIDC JWT
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Request OIDC JWT
id: oidc
run: |
JWT=$(curl -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
"$ACTIONS_ID_TOKEN_REQUEST_URL&audience=https://github.com/my-org" | jq -r '.value')
echo "::add-mask::$JWT"
echo "JWT=$JWT" >> $GITHUB_ENV
- name: Fetch Secret via Sovereign Vault
run: |
curl -s --fail https://vault.company.internal:8443/v1/secret/apps/payments/stripe_key \
-H "Authorization: Bearer $JWT" \
-o stripe_credentials.json 4. Kubernetes ServiceAccount Projection
Kubernetes pods can project bound tokens directly onto a pod volume, allowing microservices to authenticate without managing Kubernetes Secret resources:
# Vault OIDC enrollment:
sovereign-vault oidc enroll \
--preset kubernetes \
--project analytics \
--name k8s-analytics-sa \
--subject-pattern "system:serviceaccount:production:analytics-worker" \
--path "apps/analytics/*" \
--cap read
# In Kubernetes Pod YAML:
# Mount projected serviceAccountToken to /var/run/secrets/oidc/token
# In initContainer:
sovereign-vault export \
--token-file /var/run/secrets/oidc/token \
--map DB_PASS=apps/analytics/db_pass \
--output /dev/shm/.env