hashicorp / hashicorp/vault-plugin-auth-jwt

OIDC auth method cannot use Azure Workload Identity for client authentication (requires static client secret)

Open
#405 1 comment 1 reaction 0 assignees View on GitHub
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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.