hashicorp / hashicorp/vault-plugin-auth-jwt
OIDC auth method cannot use Azure Workload Identity for client authentication (requires static client secret)
- Dominant language
- Go
- Stars
- 107
- Forks
- 73
- Avg merge
- 13h 49m
- Merged PRs (30d)
- 7
Description
### Is your feature request related to a problem? Please describe.
The OIDC auth method's only supported relying-party credential for authenticating to the identity provider is a static `oidc_client_secret`. When Vault runs on Kubernetes (e.g. AKS) and uses Microsoft Entra ID for human OIDC login, this is the last static Azure credential that cannot be eliminated — it must be stored, mounted into the Vault pod, and rotated.
Every other Azure integration in this environment can already go secret-free: workloads authenticate to Vault via the Kubernetes JWT auth method, and Vault authenticates to Azure APIs (e.g. the auto-unseal seal) via the Azure SDK's workload-identity support. The human-login OIDC client secret is the one remaining gap.
### Describe the solution you'd like
Support authenticating the OIDC client to Entra ID using an **Azure Workload Identity federated token presented as a `client_assertion`** (RFC 7523 / `private_key_jwt` grant), instead of a static client secret.
Proposed UX — opt in via the existing Azure `provider_config`, omit the secret:
```shell
vault write auth/oidc/config \
oidc_discovery_url="https://login.microsoftonline.com/$TENANT_ID/v2.0" \
oidc_client_id="$CLIENT_ID" \
provider_config='{"provider":"azure","use_workload_identity":true}'
# no oidc_client_secret
```
The Vault pod supplies the federated token via AZURE_FEDERATED_TOKEN_FILE (projected by the Azure Workload Identity webhook), and a federated credential on the Entra app registration trusts the cluster's OIDC issuer + Vault's service account.
### Feasibility / prior art
Argo CD already implements this exact flow for Azure AD login (azure.useWorkloadIdentity): https://github.com/argoproj/argo-cd/blob/master/util/oidc/oidc.go
github.com/hashicorp/cap/oidc — already a dependency at v0.13.0 — supports injecting a client assertion via WithClientAssertionJWT (added in cap v0.11.0, https://github.com/hashicorp/cap/pull/155), and Config.Validate intentionally permits an empty ClientSecret. No dependency bump is required.
### Describe alternatives you've considered
Keep using oidc_client_secret and store it in a secret manager — does not remove the long-lived credential.
oidc_client_secret_wo (write-only) — keeps the secret out of Terraform state but the secret still exists and must be rotated.
A generic private_key_jwt (Vault signs its own assertion with a configured key) — a reasonable separate feature, but does not cover the federated-token-from-file case that Azure Workload Identity uses.
### Additional context
Fully opt-in and backwards compatible — the existing oidc_client_secret path is unchanged; behavior is identical when the flag is unset.
I have a working implementation with tests and docs and have opened a PR: #404. Happy to adjust the approach/config surface to maintainer preference.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with the existing OIDC configuration path and the github.com/hashicorp/cap/oidc dependency's WithClientAssertionJWT support; compare the approach with Argo CD's util/oidc/oidc.go. Inspect PR #404 and its tests and docs. Done means Azure Workload Identity can authenticate without oidc_client_secret while the existing secret-based path remains unchanged.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- azure, go, kubernetes
- Domain
- authentication
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 25/100