HashiCorp Vault provides a simple and effective way to manage security in cloud infrastructure. The HashiCorp Vault service secures, stores, and tightly controls access to tokens, passwords, certificates, API keys, and other secrets in modern computing.
This course will enable you to recognize, explain, and implement the services and functions provided by the HashiCorp Vault service.
Agenda
In this course we learn to recognize and implement the core HashiCorp Vault services in cloud infrastructure. The topics we cover are as follows:
- Vault architecture and its core components
- Vault policies and how they are used to grant or forbid access to operations in Vault
- Secrets and secret management as performed within Vault
- Vault cubbyholes and how they can be utilized
- Vault dynamic secrets
- Vault authentication and Vault identities
Intended Audience
This course will appeal to anyone looking to extend their knowledge of cloud security best practices, and to learn more about the tools and services available to help manage cloud security. If you are performing any of the roles below, we recommend completing this course.
- Architects and Developers
- System Administrators
- Security specialists
- DevOps specialists
- And anyone else interested in managing and maintaining secrets
Learning Objectives
At the end of this course you will be able to explain and implement the HashiCorp Vault service, and you will also be able to implement the Vault CLI and API to execute tasks related to Vault administration. By completing this course, you will:
- Understand the core principles of Vault, including how Vault can be used to manage and maintain secrets
- Understand the key benefits of using Vault, including how to deploy and configure it within your own environments
- Be able to evaluate and select HashiCorp Vault services
- Know how to implement the Vault CLI and API to execute tasks related to administration and configuration
Prerequisites
We recommend completing the Cloud Academy DevOps Fundamentals Learning Path so you have a basic understanding of system administration and configuration tasks.
Welcome back!
In this lecture we will discuss Vault Policies in detail. Vault Policies are an important security component within the Vault system. Vault Policies provide a declarative way to grant or forbid access to certain paths and operations in Vault. This lecture will review policy workflows and syntaxes. Within this Vault Policy lecture we will cover the following topics access Control Policies, Policy Authoring Workflow, ACL Policy Syntax, Policy Best Practice Considerations, Managing Policies, Associating Policies, and finally, Testing Policies. In this first section we'll introduce you to the basics of Vault Policies and how they can be used to provide role based access control. Vault uses policies to govern the behavior of Vault clients such as, users, machines, or apps. Policies instrument Role-Based Access Control or RBAC, by specifying access privileges for particular operations on paths within the Vault system. In a typical Vault setup, a security team or a privileged user such as an administrator will first establish a set of Vault policies that dictate the Vault permissions and privileges for the wider team. These policies will be uploaded into the Vault server.
The Vault server can be configured with various authentication backends. In this example the Vault setup is configured to use and authenticate users against a corporate LDAP directory. In this scenario the policies are mapped against LDAP groups and/or individual LDAP users. Let's say, an LDAP group named, testing is mapped to a Vault policy named, readonly which grants read only permissions to secrets in their team dedicated namespace. When a tester authenticates into Vault, his or her credentials would be verified against the corporate LDAP server. If the user belongs to the testing team, Vault would generate a token and associate it with the readonly policy. Policies are authored in Hashicorp Configuration Language or HCL, which is a human friendly config format. The policy system is designed to deny by default that is no policy then no authorization. By default the Vault server is pre loaded with two policies, root and default. The root policy is designed to be used only by super users or administrators. The root policy grants all permissions within the Vault server. The default policy on the other hand is much less powerful, containing a subset of common permissions.
Root tokens are tokens that have the root policy attached to them. Root tokens can do anything in Vault, anything. In addition, they are the only type of token within Vault that can be set to never expire without any renewal needed. As a result, it is purposefully hard to create root tokens, in fact, as of version 0.6.1, there are only three ways to create root tokens. One, the initial root token generated at vault initiation time, this token has no expiration. Two, by using another root token, a root token with an expiration cannot create a root token that never expires. Or three, by using vault operator generate-root with the permission of a quorum of unseal key holders. Root tokens are useful in development but should be extremely carefully guarded in production. In fact, the Vault team recommends that root tokens are only used for just enough initial setup usually, setting up auth methods and policies necessary to allow administrators to acquire more limited tokens or in emergencies, and are revoked immediately after they are no longer needed. If a new root token is needed, the operator generate-root command and associated API endpoint can be used to generate one on-the-fly. Running the Vault CLI command vault policy list lists the two pre loaded policies, default and root.
In this section we'll introduce the Vault policy authoring workflow. A typical policy authoring workflow consists of three stages. Stage One, gather the policy requirements. This consists of asking a number of questions such as, who needs to access what? Which paths are to be accessed? What operations must be allowed? And finally, do we need to restrict access on specific parameters and parameter values. Stage Two, Write the Policies. Author the policies to fulfill requirements that came out of Stage One. Implement the rule of least privilege. And finally, upload into Vault. Stage Three, Test the Policies. Test to make sure that the authored policies do not grant too much or too little permission. In this example the Vault policy is created to authorize, admin users to configure and manage auth methods broadly across Vault. Configure and manage secrets engines broadly across Vault. Create and manage policies across Vault. And, read system health check. Additionally the policy is designed to authorize web-app clients to, one, request an AWS credential granting read access into an existing Amazon S3 bucket. And two, read secrets from the secret/apikey/Google path.
In this section we'll go through the process of how to author and construct Vault Policies. Vault policies are simple in structure. As can be seen here, the basic anatomy of a policy consists of a path and a list of capabilities. The specified path should correspond to a Vault API endpoint. Capabilities will grant or deny access to the path in question. Policies are deny by default, so an empty policy grants no permission in the system. Everything in Vault is path based, and policies are no exception. Policies provide a declarative way to grant or forbid access to certain paths and operations in Vault. The path attribute as used within a policy indicates which paths within Vault a user or machine is allowed to access. Policy paths support prefix and suffix globbing. The path secret/team-* would match any path starting with secret/team-. For example this would match secret/team-security and secret/team-devops. Several paths are reserved by the vault system as shown here. Each path must define one or more capabilities which provide fine-grained control over permitted or denied operations. Capabilities are always specified as a list of strings, even if there is only one capability. Capabilities are by design similar to the standard set of HTTP verbs. The possible capabilities that can be used are create or POST/PUT, which allows creating data at the given path. Very few parts of Vault distinguish between create and update, so most operations require both create and update capabilities. Parts of Vault that provide such a distinction are noted in documentation. There's also read or GET, which allows reading the data at the given path. There's update or POST/PUT, which allows changes to the data at the given path. In most parts of Vault, this implicitly includes the ability to create the initial value at the path. There's delete, which allows deleting the data at the given path. And finally, list, which allows listing values at the given path. Note that the keys returned by a list operation are not filtered by policies. Do not encode sensitive information in key names. Not all backends support listing.
Additionally, there are two extra capabilities that can used, sudo and deny. Unlike the previous list of capabilities both sudo and deny do not map to any HTTP verb. Sudo allows access to paths that are root-protected. Tokens are not permitted to interact with these paths unless they have the sudo capability in addition to the other necessary capabilities for performing an operation against that path, such as read or delete. For example, modifying the audit log backends requires a token with sudo privileges. Then there's deny, which disallows access. This always takes precedence regardless of any other defined capabilities, including sudo.
In Vault, data is represented as key/value pairs. Vault policies can optionally further restrict paths based on the keys and data at those keys when evaluating the permissions for a path. The optional finer-grained control options are required_parameters and allowed_parameters. Using the required_parameters attribute allows you to set a list of required parameters that must be specified when performing any of the possible capabilities on the path. In the example as shown here, the path secret/tests/phase1 would require the user to specify named parameters date and owner when creating or updating. In this case, any value can be set against the named parameters date and owner. Using the allowed_parameters attribute allows you to restrict the allowed values that a particular parameter can hold.
In the example as shown here, the path secret/tests/phase2 would require the user to specify a named parameter state which must be set to one of the values stopped, started, starting, or stopping. Additionally this policy would allow any other parameters to be included with any value. In this case, parameter value restriction is placed only on the state parameter. Other parameters can have any value. Denied parameters give you the ability to either blacklist a named parameter from existing period, this is the case when the associated list is empty, or to allow a named parameter to exist but to not be set to any value within the specified non-empty list. In the first example shown here, the owner parameter can exist but cannot be set to any of the values anyone, everyone, or all. In the second example, all parameters regardless of name are denied. Parameter values also support prefix and suffix globbing. In the example shown here, the username parameter is allowed as long as its value starts with test-. A typical policy file will be created with multiple paths, each with its own set of capabilities listed. The policy file by convention is given the HCL file extension short for Hashicorp Configuration Language.
In this section we'll cover some considerations and best practices when creating Policies. When specifying paths you can use the wildcard character to match several paths that share a common path at the front. For example as seen here, the path secret/training/* would match either secret/training/projA or secret/training/test or secret/training/apikey. However this path would not match its parent path secret/training, this needs to be added itself to the policy. Remember, no policy means no permission as the policy system is deny by default. If you are using the wildcard character to match several paths but want to deny a specific matching path, specify a separate deny rule for this path as shown here. In this scenario, secret/training/team-admin is a reserved path that you don't want training users to access it. Following on from the previous slide, this training user can write to both secret/training/test and secret/training/random endpoints due to the fact that the associated policy granted permission on the secret/training/*. However, when the users attempts to write to the secret/training/team-admin endpoint the policy selectively denied permission and disallows all operations on this path. This is helpful when you want to create all except X type permission logic.
In this section we will cover off managing and maintaining policies. The Vault CLI tool allows you to manage and maintain your policies. The vault policy command takes any of the following sub commands. List, which lists the names of the policies that are installed. Write, which adds or update a policy name and its definition. Read, which prints the contents and metadata of a specific policy. Delete, which deletes a specific policy. And finally, format, which formats a local policy file to the policy specification. As can be seen here, working with the vault policy command is simple. Help is available per sub command using the -h argument. The following HTTP verbs are used to converse with the Policy API endpoints. For example sending an HTTP GET to the endpoint /sys/policy lists the names of the policies that are installed. Drilling down further, sending an HTTP GET to the endpoint /sys/policy/policy123 would print the contents and metadata for the policy named policy 123. This example demonstrates how to use the curl utility to craft an HTTP request to the Vault server via the Policy API hosted at vault.hashicorp.rocks. This particular command will create a new policy named admin. The ruleset will be uploaded from the payload.json file located on the local filesystem. The Vault command can be used with either the CLI or API syntax. For example to display the currently loaded policies, you could use the CLI command vault policy list or alternatively you could get the same results by using the API command vault read sys/policy. Using the API based approach requires you to specify the path. In this example we are uploading a new policy named admin, the rules for this policy are stored in the file named admin-policy.hcl stored in the local filesystem. The CLI command is performed by running vault policy write admin with the location to the admin policy file supplied as the last argument. Alternatively, the API command is performed by running vault write sys/policy/admin with the policy argument set to the location of the admin policy file.
In this section we'll cover how a Vault policy is picked and associated when a Vault operation is performed. Vault policies can be associated using either of the following options. One, during the configuration of Vault users, roles, entities, and/or groups. Here policies can be associated using the policies argument. Or two, when creating a token. Policies can be associated using the policy argument. Note, in this case the policy argument can be specified multiple times to attach multiple policies. Finally, it is important to understand that a Vault token in addition to any associated custom policies, is always associated with the default policy.
In this section we'll cover testing procedures for validating correctness of Vault policies. It's important to test and validate any Vault policies you have created to ensure that they meet your intended ACL requirements. You should perform both positive and negative test cases. For example, test whether you can perform the right operations on the endpoints for which the policy has granted access to you. Next, attempt to perform operations on the endpoints for which you have not been granted access to and confirm that you are indeed blocked. When troubleshooting permission denied errors, run the vault token capabilities command, with an existing token and a path. This will display the policy capabilities for the current token on the specified path. Running the vault policy read command, with the name of a policy will display the policies rulesets. This is useful as it allows you to quickly see how it's written and so on.
Okay, that completes this lecture on Vault Policies. Go ahead and close this lecture, and we'll see you shortly in the next one.
Jeremy is a Content Lead Architect and DevOps SME here at Cloud Academy where he specializes in developing DevOps technical training documentation.
He has a strong background in software engineering, and has been coding with various languages, frameworks, and systems for the past 25+ years. In recent times, Jeremy has been focused on DevOps, Cloud (AWS, Azure, GCP), Security, Kubernetes, and Machine Learning.
Jeremy holds professional certifications for AWS, Azure, GCP, Terraform, Kubernetes (CKA, CKAD, CKS).