Skip to main content

Set up HashiCorp Vault as a parameter backend

This guide walks you through connecting nullplatform to HashiCorp Vault so parameter values land in your Vault instance instead of nullplatform's database. Values are stored under the KV v2 mount and base path you configure. Developers keep using parameters the same way.

Prerequisites

Before you start, make sure you have:

  • A reachable HashiCorp Vault instance with a KV v2 secrets engine enabled.
  • A Vault token with the policy described in Required Vault token policy below.

    💡 Tip: We recommend a periodic token tied to a role rather than a root token.

  • The mount point and base path you want to use (defaults: secret mount, nullplatform path).
note

If you don't yet have Vault running, see HashiCorp's Vault deployment guide and the KV v2 docs. The rest of this page assumes Vault is up.

Required Vault token policy

The token nullplatform uses must be able to create, read, update, and delete secrets under the configured path, and to manage the metadata that sits alongside them. With the defaults (mount: secret, secret_path: nullplatform), the minimum policy is:

path "secret/data/nullplatform/*" {
capabilities = ["create", "read", "update", "delete"]
}

path "secret/metadata/nullplatform/*" {
capabilities = ["create", "read", "update", "delete", "list"]
}

path "secret/metadata/nullplatform" {
capabilities = ["read", "list"]
}

If you customize mount or secret_path, replace secret and nullplatform in the paths above with your values. The metadata paths are required because nullplatform writes traceability metadata (parameter ID, NRN, dimensions, secret flag) next to each value.

Configure the provider

Create a hashicorp-vault provider on the NRN where you want Vault to take over. You can do it through the UI, the CLI, or Terraform.

  1. Go to Platform settings > Security & Secrets > HashiCorp Vault.
  2. Click + New provider, pick the resource (NRN) and any dimensions.
  3. Fill in Setup:
    • Vault Address: full URL, e.g. https://vault.acme-corp.io.
    • Mount Point: KV v2 engine mount. Defaults to secret.
    • Secret Path: base path inside the mount. Defaults to nullplatform.
  4. Fill in Security:
    • Vault Token: the token nullplatform will use to talk to Vault.
    • Token Expiration: the date the token expires.
  5. Click Create provider.

Verify the setup

Create a parameter value under the configured NRN and confirm the secret lands in Vault:

np parameter-value create \
--parameter <parameter-id> \
--nrn organization=1:account=2:namespace=3:application=4 \
--value "my-secret-value"

Then, in Vault, list the secrets under the configured path. With the defaults (mount: secret, secret_path: nullplatform) and an NRN that resolves all the way down to an application, you should see something like:

vault kv list secret/nullplatform/acme-corp/acme-corp-main/billing-namespace/billing-api
Keys
----
db-password-c63ad214-d386-4755-b64e-aaaee103e120
api-key-d4294ab9-cb47-44be-b853-d3b7690f853f

Each entry is named <parameter-name-slug>-<uuid>. Reading it back through the parameter API returns the value as if it lived in nullplatform's own database. You don't need to know the path layout to use the feature: nullplatform resolves it deterministically on read, write, and delete.

Token rotation

Tokens expire. To rotate without downtime:

  1. Issue a new Vault token with the same policies. Keep the old token valid for a grace period.
  2. Update the provider with the new vault_token and token_expires_at.
  3. Wait up to 5 minutes (the resolver caches the configuration per {NRN, dimensions} tuple). Existing parameter operations keep working with the previous token until the cache refreshes.
  4. Once you confirm new operations succeed with the rotated token, revoke the old one in Vault.

If you absolutely need an immediate cutover, plan a brief window where in-flight reads can fail, then revoke and update.

Troubleshooting

Parameter value writes fail with Vault: permission denied

The Vault token doesn't have write permission at the configured path. Confirm the policy attached to the token allows create, update, and delete on {mount}/data/{secret_path}/* and on {mount}/metadata/{secret_path}/*.

Reads return value not found after a successful write

Check that the provider's mount and secret_path match what you actually have in Vault. The full Vault URL is logged in nullplatform's parameters API; compare it to a manual vault kv get to spot mismatches.

The provider is created but secrets are still going to nullplatform's database

Two common causes:

  • The NRN you used on the parameter value is not under the NRN where you configured the provider, so NRN inheritance doesn't match.
  • The dimensions on the value don't overlap with the dimensions on the provider.

List active providers for the same NRN to confirm coverage:

np provider list --nrn organization=1:account=2:namespace=3:application=4

Next steps