Skip to content

Support Vault auth response data in defaultResponse - #1327

Open
ilamminir wants to merge 1 commit into
hashicorp:mainfrom
ilamminir:fix/default-response-auth-fallback
Open

Support Vault auth response data in defaultResponse#1327
ilamminir wants to merge 1 commit into
hashicorp:mainfrom
ilamminir:fix/default-response-auth-fallback

Conversation

@ilamminir

Copy link
Copy Markdown

Description
VaultDynamicSecret produces empty secret data when targeting Vault endpoints that return data in the auth field instead of the data field. This affects endpoints like auth/token/create/, where the Vault API response contains the token and metadata under auth, while data is null.

Steps to Reproduce
Create a VaultDynamicSecret resource targeting a token creation endpoint:

apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultDynamicSecret
metadata:
  name: vault-prometheus-token-sync
  namespace: openshift-monitoring
spec:
  destination:
    create: true
    name: vault-prometheus-token
  mount: auth/token
  path: create/prometheus-metrics-role
  refreshAfter: 12h
  requestHTTPMethod: POST
  vaultAuthRef: my-auth

Observe the resulting Kubernetes secret — all data fields are empty.
Expected Behavior
The operator should populate the Kubernetes secret with data from the Vault response's auth field (including client_token, accessor, policies, etc.), since that is where auth/token/create places its response data.

Actual Behavior
The Kubernetes secret is created with empty maps. The _raw field contains null.

The operator logs show the response metadata (annotations, etc.) but the secret data portion is:

{map[] map[] map[] map[...annotations...] map[]}
Root Cause
defaultResponse.Data() in vault/responses.go exclusively returns r.secret.Data:

func (r *defaultResponse) Data() map[string]any {
    if r.secret == nil {
        return nil
    }
    return r.secret.Data
}

SecretK8sData() similarly only reads from secret.Data for both the _raw field and the template input (.Secrets).

The Vault Go API's api.Secret struct correctly parses the auth JSON field into secret.Auth (*api.SecretAuth), but the operator never accesses it. Vault's auth/token/create endpoint returns:

{
  "auth": {
    "client_token": "s.xxxxx",
    "accessor": "...",
    "policies": ["default", "..."],
    "renewable": true,
    ...
  },
  "data": null
}

Since data is null, all downstream processing produces empty results.

Proposed Fix
When secret.Data is nil, defaultResponse should fall back to converting secret.Auth into a map[string]any (via JSON roundtrip — the same pattern already used for WrapInfo in the same file). This preserves full backward compatibility: when Data is present it takes precedence; the fallback only activates for auth-style responses.

Files Changed
vault/responses.go — added authAsData() helper; modified Data() and SecretK8sData() to fall back to auth data
vault/responses_test.go — added test cases for auth fallback, template rendering, and data-precedence

Vault endpoints like auth/token/create return data in the "auth" field
instead of "data". defaultResponse.Data() and SecretK8sData() now fall
back to converting secret.Auth into a data map when secret.Data is nil,
enabling VaultDynamicSecret to work with token creation endpoints.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@ilamminir
ilamminir requested review from a team as code owners August 4, 2026 09:19
@hashicorp-cla-app

Copy link
Copy Markdown

CLA assistant check

Thank you for your submission! We require that all contributors sign our Contributor License Agreement ("CLA") before we can accept the contribution. Read and sign the agreement

Learn more about why HashiCorp requires a CLA and what the CLA includes

Have you signed the CLA already but the status is still pending? Recheck it.

1 similar comment
@hashicorp-cla-app

Copy link
Copy Markdown

CLA assistant check

Thank you for your submission! We require that all contributors sign our Contributor License Agreement ("CLA") before we can accept the contribution. Read and sign the agreement

Learn more about why HashiCorp requires a CLA and what the CLA includes

Have you signed the CLA already but the status is still pending? Recheck it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant