Methodology for Vault Design and Implementation in an Organization

Iman Kurniawan
DKatalis
Published in
4 min readJun 22, 2021

Vault is a secret management product from Hashicorp. Every organization needs to use it for managing their secret (password, private key, token, etc). But sometimes an organization face a problem during the design and implementation because the Vault has many objects (secret engine, authentication backend, role, policy, etc) that relate to each other.

I want to help with the methodology of the Vault design and implementation.
The methodology that I suggest is to start with the organization structure and map to a Vault configuration. The implementation is using terraform. Terraform works very well to configure Vault to provide a stateful configuration.

We can divide Vault objects into two big objects (secret engine and authentication backend). The secret engine is the What and the authentication backend is the Who. The authentication can have multiple roles. This same with us in our social life. We can have a role as the father at home or manager at the office. The policy (permission) is also different for a different role. For an analogy, as a father role we can have entered our home but not the office, and vice versa as a manager. One role can have multiple policies.

I have created a terraform configuration with this concept in mind. So we can understand Vault objects as small puzzle pieces that relate to each other and make a beautiful picture. I can achieve this with object variable and HCL (Hashicorp Configuration Language).

Understanding HCL is a bit of a challenge (at least for me), with the looping, nested looping, if then else condition. So with a framework of data-driven configuration will help others to speed up the implementation. They can populate the data (variable value), then the configuration will be created automatically. The Vault objects will have and follow the naming convention set by the Terraform configuration.

Let’s start with the step

Like I mentioned above, we need to structure the secret engine according to the organizational structure. It will help us to write a policy. Usually, organizations divide into multiple departments. Departments will have few applications. Applications will have few environments. Each environment will have a different secret engine (kv, database, ssh, cloud provider, etc).
You need to put all the secret engines that each application has. Some secret engines need an initial setup that needs a credential, such as a database secret engine. In this case, you need to run a command line or set it up through UI. You cannot put a secret into configuration then it will defeat the purpose of setting up Vault from the first time.

Vault uses a file system-like structure for its object. It is better to map organization structure to vault structure. It will give better visibility on the ownership of the object.

Example: An organization (org.com) has 5 departments (marketing, hr, finance, operation, and IT)

Step 2: Policy
You need to plan about policy, what can you do with the secret (list, read, write, or update).
Example: KV secret engine for Marketing department has 2 policy, read-secret and write-secret

Step 3: Role
You need to plan about the role as well. Some secret engine, such as database, does not have a policy. The role is attached with creation_statement that you can consider as policy. Because creation_statement defines what role can do in the database.

Sometimes people get confused about the naming for roles and policy, below are some hints regarding naming

Role: noun word (it is a flat list, so we need to add a prefix of secret engine mount path
Policy: verb-noun pattern
Example: Database secret engine for Marketing has 2 roles, admin (with read/write access to the database) and normal user (with select access to the database)

Step 4: Authentication backend

You need to specify user/group and app (machine) that needs to access the Vault. Similar to the secret engine, there is some authentication backend (for example OIDC and Kubernetes)that needs to set up with passing credentials. It needs to run manually or do it from the UI. You can set up roles and policies as well in the authentication backend. You might be questioning what is the difference between role and policy at the secret engine. The policy can be assigned to a role (app) or user/group. In the case of the JWT auth backend, I can attach the role that was created on the secret engine or create a new one. I prefer to create a new one then attach to the new role.

You might ask how to use GSuite (OIDC) for end-user authentication (group base). It is a challenge for me to set up it properly, but finally, I can set up by putting the correct `groups_claims` and `bound_claims` as below. I have not incorporated to fix to my latest code.

vault write auth/oidc/role/your_default_role -<<EOF
{
"allowed_redirect_uris": "http://localhost:8200/ui/vault/auth/oidc/oidc/callback,http://localhost:8250/oidc/callback,http://127.0.0.1:8200/ui/vault/auth/oidc/oidc/callback",
"user_claim": "email",
"oidc_scopes": "email,https://www.googleapis.com/auth/admin.directory.group.readonly",
"groups_claim": "groups",
"policies": ["default"],
"bound_claims": {
"groups": ["manager.group@org.com"]
}
}
EOF

Final word, you can check my configuration in my github repo. Feel free to contact me if you have any feedback.

--

--