HashiCorp Vault, tool for secrets management, data encryption, and identity-based access.

Introduction to Vault

Vault is a tool for securely accessing secrets. A secret could be anything that you want to tightly control access to, like API keys, passwords, or certificates. Vault provides a unified interface to any secret while providing tight access control and recording a detailed audit log.

I have kept this as a practical CLI notebook, separated into the parts I most often need.

CLI Setup

The CLI is the primary way I interact with Vault. Almost every operation available through the HTTP API is represented there, and the client is a single binary without a separate runtime. Install it from HashiCorp’s repository or package for the platform, then point it at the server:

export VAULT_ADDR=https://vault.example.com
vault status
vault login

The value returned by an auth method is a Vault token. Dynamic credentials and service certificates may have renewable or revocable leases; static KV secrets generally do not. Vault lease concepts

KV Version 2

Secrets management is the core feature: API keys, passwords, certificates, and other values live behind explicit policy. Vault can also generate dynamic credentials for systems such as databases and cloud providers instead of storing one long-lived value.

For the simple key/value case, the friendly CLI hides KV v2’s API path split:

vault secrets enable -path=secret kv-v2
vault kv put secret/project/database username=app password=replace-me
vault kv get secret/project/database
vault kv get -field=username secret/project/database
vault kv metadata get secret/project/database
vault kv delete secret/project/database

Policies use secret/data/... for secret versions and secret/metadata/... for listing or metadata operations:

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

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

That data/metadata distinction is specific to KV v2. KV v2 API

Policies and Capabilities

Policies control what an identity can do on a path. The useful verbs from my original example remain create, read, update, delete, and list; a policy should include only the ones the user or workload needs.

For example, I can give a developer read-only access to the project secrets while an administrator can update them without automatically granting delete:

# developer.hcl
path "secret/data/project/*" {
  capabilities = ["read"]
}

# admin.hcl
path "secret/data/project/*" {
  capabilities = ["create", "read", "update"]
}

I write the policy, inspect it, and test it with the same path the application will use:

vault policy write developer developer.hcl
vault policy read developer
vault token capabilities secret/data/project/database

For a short-lived test token:

vault token create -policy=developer -ttl=30m -explicit-max-ttl=2h

Tokens are credentials, not user records. For people and workloads I prefer an auth method that maps an external identity to policies. Vault policy documentation

GitHub Authentication

Vault’s GitHub auth method is configured with the organization name. The administrator does not store a personal token in the auth-method configuration:

vault auth enable github
vault write auth/github/config organization=my-github-organization
vault write auth/github/map/teams/platform value=developer
vault write auth/github/map/users/my-user value=admin

A user authenticates with their own GitHub token:

vault login -method=github token="$GITHUB_TOKEN"

The token must be able to read organization membership, and organization policy such as SAML SSO may require authorization. Vault GitHub auth

Azure Authentication

For an Azure VM or workload with managed identity, I configure the Azure auth method and bind a Vault role to the Azure identity and resource scope:

vault auth enable azure
vault write auth/azure/config \
  tenant_id="$AZURE_TENANT_ID" \
  resource=https://management.azure.com/

vault write auth/azure/role/my-role \
  policies=developer \
  bound_subscription_ids="$AZURE_SUBSCRIPTION_ID" \
  bound_resource_groups=my-resource-group \
  bound_service_principal_ids="$AZURE_MANAGED_IDENTITY_OBJECT_ID"

On the Azure workload, the Vault CLI performs the managed-identity login and supplies the required Azure instance metadata:

vault login -method=azure role=my-role

This replaces my older example that requested an Azure CLI access token with a Vault-specific audience and manually posted it. The supported login fields depend on whether the identity is a VM, VMSS, or another Azure resource, so I check the role and workload against the current Vault Azure auth documentation.

What I Keep from the Original Approach

The useful model has not changed: secrets live under deliberate paths, policies grant the smallest capabilities needed, and authentication supplies a short-lived Vault token. The corrections here are mostly terminology and KV v2 path handling, not a different way of thinking about Vault.



Buy Me a Coffee