Policies

Policies in Vault control what a user can access. In the Authentication tutorial, you learned about authentication methods. This section is about authorization.

For authentication Vault has multiple options or methods that can be enabled and used. Vault always uses the same format for both authorization and policies. All auth methods map identities back to the core policies that are configured with Vault.

Policy Format

Policies are authored in HCL, but are JSON compatible. Here is an example policy:

# Dev servers have version 2 of KV secrets engine mounted by default, so will
# need these paths to grant permissions:
path "secret/data/*" {
  capabilities = ["create", "update"]
}

path "secret/data/foo" {
  capabilities = ["read"]
}

The example policy grants capabilities for a KV version 2 secrets engine. If you are unfamiliar with the paths related to this secrets engine, consult the ACL Rules section of the secrets engine documentation.

With this policy, a user could write any secret to secret/data/, except to secret/data/foo, where only read access is allowed. Policies default to deny, so any access to an unspecified path is not allowed.

The policy format uses a prefix matching system on the API path to determine access control. The most specific defined policy is used, either an exact match or the longest-prefix glob match. Since everything in Vault must be accessed via the API, this gives strict control over every aspect of Vault, including enabling secrets engines, enabling auth methods, authenticating, as well as secret access.

There are some built-in policies that cannot be removed. For example, the root and default policies are required policies and cannot be deleted. The default policy provides a common set of permissions and is included on all tokens by default. The root policy gives a token super admin permissions, similar to a root user on a Linux machine.

View the default policy.

$ vault policy read default

Write a Policy

To write a policy, use vault policy write command. Review the command help.

$ vault policy write -h

Usage: vault policy write [options] NAME PATH

  Uploads a policy with name NAME from the contents of a local file PATH or
  stdin. If PATH is "-", the policy is read from stdin. Otherwise, it is
  loaded from the file at the given path on the local disk.

  Upload a policy named "my-policy" from "/tmp/policy.hcl" on the local disk:

      $ vault policy write my-policy /tmp/policy.hcl

  Upload a policy from stdin:

      $ cat my-policy.hcl | vault policy write my-policy -

   ...snip...

Create the policy named my-policy with the contents from stdin.

$ vault policy write my-policy - << EOF
# Dev servers have version 2 of KV secrets engine mounted by default, so will
# need these paths to grant permissions:
path "secret/data/*" {
  capabilities = ["create", "update"]
}

path "secret/data/foo" {
  capabilities = ["read"]
}
EOF

Successful output example:

Success! Uploaded policy: my-policy

List all the policies.

$ vault policy list

default
my-policy
root

View the contents of the my-policy policy.

$ vault policy read my-policy

# Dev servers have version 2 of KV secrets engine mounted by default, so will
# need these paths to grant permissions:
path "secret/data/*" {
  capabilities = ["create", "update"]
}

path "secret/data/foo" {
  capabilities = ["read"]
}

Test the Policy

The policy you created provides limited management of secrets defined for the KV-V2 secrets engine. Policies are attached to tokens that Vault generates directly or through its various auth methods.

Create a token, add the my-policy policy, and set the token ID as the value of the VAULT_TOKEN environment variable for later use.

$ export VAULT_TOKEN="$(vault token create -field token -policy=my-policy)"

For this tutorial using a dev mode server, a token is created directly from the token auth method for simplicity. Keep in mind that in most production deployments, the token will be returned by an enabled auth method instead.

You can validate that the token ID was exported properly, and has the correct policies attached.

$ vault token lookup | grep policies
policies            [default my-policy]

The policy enables the create and update capabilities for every path within the secret/ engine except one.

Write a secret to the path secret/data/creds.

$ vault kv put -mount=secret creds password="my-long-password"
== Secret Path ==
secret/data/creds

======= Metadata =======
Key              Value
---              -----
created_time     2023-11-12T18:05:42.537496856Z
deletion_time    n/a
destroyed        false
version          1

When you access a KV v2 secrets engine using the vault kv CLI commands, we recommend using the -mount flag syntax (e.g. vault kv get -mount=secret foo) to reference the path to the KV v2 secrets engine. If you use the KV v1-like path prefix syntax (e.g. vault kv get secret/foo), /data will be automatically appended to the secret path, which may cause confusion.

The secret is created successfully.

The policy only enables the read capability for the secret/data/foo path. An attempt to write to this path results in a "permission denied" error.

Attempt to write to the secret/data/foo path.

$ vault kv put -mount=secret foo robot=beepboop

Error writing data to secret/data/foo: Error making API request.

URL: PUT http://localhost:8200/v1/secret/data/foo
Code: 403. Errors:

* 1 error occurred:
  * permission denied

The permission error is displayed.

This policy defines a limited set of paths and capabilities. Without access to sys, commands like vault policy list or vault secrets list will not work.

Associate Policies to Auth Methods

Vault itself is the single policy authority, unlike authentication where you can enable multiple auth methods.

You can configure auth methods to automatically assign a set of policies to tokens created by authenticating with certain auth methods. The way this is done differs depending on the related auth method, but typically involves mapping a role to policies or mapping identities or groups to policies.

For example, you can achieve this with the token_policies parameter when configuring a role for the AppRole auth method.

Use a higher privileged token for the following steps. For a dev mode server you can specify the token ID that is output when you start the server or the one that you set with the -dev-root-token-id= flag. For example, if -dev-root-token-id=root, the following exports the correct root token ID.

$ export VAULT_TOKEN=root

First, check to verify that approle auth method has not been enabled at the path approle/.

$ vault auth list | grep 'approle/'

If this command produces no output (i.e. approle/ is not listed), enable it before proceeding.

$ vault auth enable approle

Successful output example

Success! Enabled approle auth method at: approle/

Enable an AppRole role named "my-role", to configure some basic token options and to attach the previously defined "my-policy" policy to all tokens that it creates when applications authenticate with the role.

$ vault write auth/approle/role/my-role \
    secret_id_ttl=10m \
    token_num_uses=10 \
    token_ttl=20m \
    token_max_ttl=30m \
    secret_id_num_uses=40 \
    token_policies=my-policy

Successful output example:

Success! Data written to: auth/approle/role/my-role

You can validate that this AppRole role is attaching the policy by authenticating with the auth method.

To authenticate with AppRole, first fetch the role ID, and capture its value in a ROLE_ID environment variable.

$ export ROLE_ID="$(vault read -field=role_id auth/approle/role/my-role/role-id)"

Next, get a secret ID (which is similar to a password for applications to use for AppRole authentication), and capture its value in the SECRET_ID environment variable.

$ export SECRET_ID="$(vault write -f -field=secret_id auth/approle/role/my-role/secret-id)"

Finally, authenticate to AppRole with vault write by specifying the role path and passing the role ID and secret ID values with the respective options.

$ vault write auth/approle/login role_id="$ROLE_ID" secret_id="$SECRET_ID"

Successful output example:

Key                     Value
---                     -----
token                   s.Sh9h1wZ9ycATeSaASoOQvovr
token_accessor          xCgUIu6WWLM9opkEkAiNLsRc
token_duration          20m
token_renewable         true
token_policies          ["default" "my-policy"]
identity_policies       []
policies                ["default" "my-policy"]
token_meta_role_name    my-role

Note that "my-policy" policy is contained in the policies and token_policies fields.

About policy fields

As shown in the example output, the token has three similarly named fields, policies, identity_policies, and token_policies. The difference in these fields is that token_policies represent all policies attached to the token by auth methods, and identity_policies represents all policies attached to the token by the Identity secrets engine. The policies field is a correlation of identity_policies and token_policies to show you all available policies for a given token. To learn more, refer to the Identity: Entities and Groups tutorial after completing the Getting Started tutorials.

Next

Policies are an important part of Vault. While using the root token is easiest to get up and running, you will want to restrict access to Vault very quickly, and the policy system is the way to do this.

The syntax and function of policies is easy to understand and work with, and because auth methods all must map to the central policy system, you only have to learn this policy system.

You will learn how to create a Vault server configuration file to customize the server settings.

Last updated