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.

Vault CLI

The CLI is the primary way to interact with Vault. Almost every operation that can be performed via the HTTP API can be performed by the CLI. The CLI is a single static binary and does not require a runtime. Once downloaded, it can be run from anywhere.

To start, you need to install Vault. The process varies depending on your operating system. Detailed installation instructions can be found in the official documentation.

After installation, you can use the vault command to access Vault CLI. The general usage is:

vault <command> [options] [args]

For help on any command, you can use:

vault <command> -h

A typical workflow includes running a vault server, logging into vault, and then performing operations such as read, write, and delete.

Secrets Management

Secrets management is the core feature of Vault. It allows you to securely store and tightly control access to tokens, passwords, certificates, API keys, and other secrets.

Here’s an example of how to store and retrieve secrets:

# Write a secret
vault kv put secret/hello foo=world

# Read a secret
vault kv get secret/hello

Vault provides a range of options for secret storage, including:

  • Key/Value Secrets: These are simple key-value pairs that can be stored and retrieved. In the example above, foo=world is a key-value pair.

  • Dynamic Secrets: Vault can generate secrets on-demand for some systems, such as AWS or SQL databases. For instance, when an app needs to access an S3 bucket, it asks Vault for AWS credentials. Vault will create an IAM user with the desired permissions, generate a key, and provide the key to the requester.

  • Leases and Renewals: All secrets in Vault have a lease, and when the lease is up, Vault automatically revokes the secret. Some systems, like AWS IAM/STS, have leases built-in. For other systems, Vault can keep track of leases.

Managing Policies in HashiCorp Vault

Policies in Vault control what a user can access and the actions they can perform. Policies are written in HashiCorp Configuration Language (HCL) but can also be expressed in JSON. A policy document contains one or many policy paths, with each path corresponding to a namespace in Vault.

Here’s an example of a policy:

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

In this policy, the specified capabilities apply to any secrets stored under the secret/data/myapp path.

Capabilities

Capabilities are the actions a user can perform on a path. They include:

  • create: Allows a key to be created at the path.
  • read: Allows a key to be read at the path.
  • update: Allows a key to be updated at the path.
  • delete: Allows a key to be deleted at the path.
  • list: Allows keys to be listed at the path.

In our example policy above, the user has all these capabilities on secrets under secret/data/myapp.

Applying Policies

To create a policy, you use the vault policy write command, providing the policy name and the file containing the policy:

vault policy write my-policy my-policy.hcl

After creating a policy, you can assign it to a token. This token can then be used to perform actions based on the capabilities defined in the policy.

vault token create -policy=my-policy

You can also list, read, and delete policies:

Example Policies in HashiCorp Vault

Scenario:

Let’s consider a scenario where we have two users: a developer and an admin. We want to:

  • Allow the developer to read secrets under the path secret/data/project, but not write or update them.
  • Allow the admin to have full control (read/write/update) over the secret/data/project, but not delete them.
  • Allow the admin to have full control (create/read/update/delete/list) over secret/data/admin.

Here’s how we can achieve this:

Step 1: Create the Policies

First, create the policy files:

  • developer.hcl:
path "secret/data/project/*" {
  capabilities = ["read", "list"]
}
  • admin.hcl:
# Full control over secret/data/project except delete
path "secret/data/project/*" {
  capabilities = ["create", "read", "update", "list"]
}

# Full control over secret/data/admin
path "secret/data/admin/*" {
  capabilities = ["create", "read", "update", "delete", "list"]
}

Step 2: Write the Policies to Vault

You can write these policies to Vault using the vault policy write command:

vault policy write developer developer.hcl
vault policy write admin admin.hcl

Step 3: Apply the Policies to Users

To apply these policies, you can create tokens associated with the policies:

vault token create -policy=developer
vault token create -policy=admin

This command will create a token for each user, which they can use to authenticate with Vault. The developer will only have read access to secrets under secret/data/project/*, while the admin will have more extensive privileges, as defined above.

In this way, Vault’s policy system allows for granular access control to secrets, with different users or roles having different permissions as required.

Please note that managing tokens for users this way is a basic approach, and for a real-world scenario, integrating Vault with an existing identity system (like LDAP, GitHub, etc.) would be more practical and secure.

Step 1: Enable and Configure Azure AD Authentication

First, you need to enable the Azure AD authentication method in Vault:

vault auth enable azure

Then, you configure it with details about your Azure environment:

vault write auth/azure/config \
    tenant_id="..." \
    resource="https://vault.hashicorp.com" \
    client_id="..." \
    client_secret="..."

Replace "..." with your Azure AD tenant ID, client ID, and client secret.

  • tenant_id: The tenant ID of your Azure Active Directory.
  • client_id: The client ID of the Azure Managed Identity.
  • client_secret: The client secret for the Azure Managed Identity.
  • resource: The Vault resource URL.

Step 2: Create Role and Bind It with Azure Identity

After the Azure authentication method is configured, you can create a Vault role and bind it to an Azure service principal or managed identity. For example:

vault write auth/azure/role/my-role \
    policies="developer,admin" \
    bound_service_principal_ids="..."

Replace "..." with your Azure service principal ID.

  • policies: The Vault policies to assign to authenticated identities.
  • bound_service_principal_ids: The Azure service principal that is allowed to authenticate.

This example assigns the developer and admin policies to authenticated Azure identities with the matching service principal.

Step 3: Authenticate

Azure identities can authenticate with Vault by sending their Azure Managed Identity JWT token to Vault. Here’s a CLI example using the Azure CLI:

# Get a token from Azure AD for the MSI, with Vault as the audience
token=$(az account get-access-token --resource https://vault.hashicorp.com --query accessToken -o tsv)

# Send this token to Vault
vault write auth/azure/login role="my-role" jwt=$token subscription_id=$AZURE_SUBSCRIPTION_ID \
resource_group_name=$AZURE_RESOURCE_GROUP vm_name=$AZURE_VM_NAME

Replace $AZURE_SUBSCRIPTION_ID, $AZURE_RESOURCE_GROUP, and $AZURE_VM_NAME with your Azure details.

On a successful authentication, Vault returns a token that the Azure identity can use to make authenticated requests.

Now, any authenticated Azure identities (service principals or managed identities) mapped to the my-role role will receive the associated policies (developer, admin) and can perform actions in Vault according to those policy definitions.

Step 1: Enable GitHub Authentication

# First, enable the GitHub authentication method in Vault:
vault auth enable github

# Then, configure it with a GitHub personal access token:
# Replace `<YourGitHubOrganization>` and `<YourGitHubToken>` with your GitHub organization name and personal access token, respectively.
vault write auth/github/config \
    organization="<YourGitHubOrganization>" \
    base_url="https://api.github.com/" \
    token="<YourGitHubToken>"
  • organization: The name of your GitHub organization.
  • token: Your GitHub personal access token. The base_url is set to GitHub’s API URL.

Step 3: Create Mapping for Users and Teams

After the GitHub authentication method is configured, you can map Vault policies to GitHub teams and users:

# For teams:
# Replace `<YourGitHubTeam>` and `<VaultPolicies>` with your GitHub team name and the Vault policies to assign, respectively.
vault write auth/github/map/teams/<YourGitHubTeam> value=<VaultPolicies>

# For users:
# Replace `<YourGitHubUser>` and `<VaultPolicies>` with your GitHub username and the Vault policies to assign, respectively.
vault write auth/github/map/users/<YourGitHubUser> value=<VaultPolicies>

Step 4: Authenticate

GitHub users can authenticate with Vault by sending their GitHub token to Vault:

# Replace `<GitHubToken>` with your GitHub personal access token.
vault login -method=github token=<GitHubToken>

On successful authentication, Vault returns a token that the GitHub user can use to make authenticated requests.

Now, any authenticated GitHub users or teams mapped to the given Vault policies will have access according to the capabilities defined in those policies.



Buy Me a Coffee