I work as an IT consultant. Over the past two years, we've been working with our client on a for /
For configuring your Vault, I would generally recommend going for Terraform/OpenTofu, which takes the declarative approach as opposed to Pulumi. Pulumi is a good solution when you have lots of dependencies in a complex system, which need to be handled programmatically.
We started off on our Vault journey by simply documenting how we configured our secrets engines, auth methods and policies. So when we had to set up a new Vault, that meant going through that documentation and running the commands one-by-one. We at some point (painfully) changed to Terraform/OpenTofu, and it directly opened up many doors for us:
- Writing a testing framework, where we would test the access to Vault paths by simulating the components in our system, allowing us to check for any regressions
- Reusing the IaC to configure Vaults in multiple environments
- Integrate with CI pipelines to automate updates to our Vaults
There's many more advantages. Point is, start with IaC directly, so you don't have to go through the same process as we did, of integrating an already configured Vault with IaC. In case you have to: under secrets/, used to store secret recipes under the recipes/ subpath. The following policy could be the "head chef" policy, allowing the head chef to browse the entire secrets engine and update any of the secret recipes:
vault policy write head-chef - <<EOF
# browse secrets
path "secrets/metadata/*" {
capabilities = ["read", "list"]
}
# manage recipes
path "secrets/data/recipes/*" {
capabilities = ["create", "update", "read", "delete"]
}
EOF
We would then attach this policy to a role with:
vault write auth/approle/role/head-chef token_policies=head-chef
Here we decided that the name of the policy would match the role, namely head-chef. This works, but we have found that as policies become larger and more roles are added to the Vault, breaking down policies into smaller, more meaningful sets of permissions becomes increasingly important. Policy names should also describe the permissions encapsulated, and should not refer back to the role that uses it.
To help breaking down policies, it is useful to decide on a naming standard for your policies. An example would be <verb>-<subject of policy>, like read-nuclear-codes. In this example we would have to break down the policy a bit more in order for our convention to apply. Let's split the head-chef policy into two policies, browse-secrets and manage-recipes:
vault policy write browse-secrets - <<EOF
# browse secrets
path "secrets/metadata/*" {
capabilities = ["read", "list"]
}
EOF
vault policy write manage-recipes - <<EOF
# manage recipes
path "secrets/data/recipes/*" {
capabilities = ["create", "update", "read", "delete"]
}
EOF
vault write auth/approle/role/head-chef token_policies=browse-secrets,manage-recipes
It is now much more transparent what permissions are associated with this role. In addition, breaking down the policy made parts of the policy reusable, as we could now do something like the following, reusing the browse-secrets policy:
vault policy write manage-greek-recipes - <<EOF
# manage greek recipes
path "secrets/data/recipes/greek/*" {
capabilities = ["create", "update", "read", "delete"]
}
EOF
vault write auth/approle/role/chef-george token_policies=browse-secrets,manage-greek-recipes
Deciding on this naming convention for our policies allowed us to scale to many more roles in our Vault. One thing to consider though, is that paths may end up overlapping among the policies assigned to a role. This requires being aware of how Vault's
(or . This is often the cleanest solution, and has a big advantage of reducing the amount of configuration.
sys/policy. This subfolder must be disjoint from the policies granted to employee-manager, and employee-manager should not be able to update its own role.create permissions on anything under sys/policy, and employee-manager should not be able to update its own role.There may be more mitigation options, but the point of this chapter is to consider the event of a breach and be aware of the effective permissions that you may be giving to your system components.
That's all the tips for now. Thanks for reading, I hope you learned something, and stay tuned for the second half and other posts to come.
SOCIAL SHARE CARD GENERATOR