├── .devcontainer ├── Dockerfile ├── devcontainer.json ├── install │ ├── Dockerfile │ └── devcontainer.json └── run │ ├── Dockerfile │ ├── devcontainer.json │ ├── start-vault.sh │ └── vault.hcl ├── .github └── FUNDING.yml ├── LICENSE ├── README.md └── labs ├── img └── ports.png ├── lab_approle_auth_method.md ├── lab_audit_devices.md ├── lab_install_vault_manually.md ├── lab_integrate_terraform_and_vault.md ├── lab_intro_to_vault.md ├── lab_kubernetes_auth_method.md ├── lab_kv_secrets_engine.md ├── lab_pki_secrets_engine.md ├── lab_response_wrapping.md ├── lab_transit_secrets_engine.md ├── lab_userpass_auth_method.md ├── lab_vault_cli.md ├── lab_vault_init_and_unseal.md ├── lab_vault_policies.md ├── lab_vault_tokens.md └── lab_vault_ui.md /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | # Dockerfile 2 | FROM hashicorp/vault:latest 3 | 4 | # Install git 5 | RUN apk add --no-cache git jq logrotate openssl 6 | 7 | # Download and install latest Terraform 8 | RUN apk add --no-cache curl unzip && \ 9 | LATEST_VERSION=$(curl -s https://api.github.com/repos/hashicorp/terraform/releases/latest | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/') && \ 10 | curl -LO https://releases.hashicorp.com/terraform/${LATEST_VERSION}/terraform_${LATEST_VERSION}_linux_amd64.zip && \ 11 | unzip terraform_${LATEST_VERSION}_linux_amd64.zip -d /usr/local/bin && \ 12 | rm terraform_${LATEST_VERSION}_linux_amd64.zip && \ 13 | apk del curl unzip 14 | 15 | # Set environment variables for dev mode 16 | ENV VAULT_DEV_ROOT_TOKEN_ID=root 17 | ENV VAULT_DEV_LISTEN_ADDRESS=0.0.0.0:8200 18 | 19 | # Expose the default Vault port 20 | EXPOSE 8200 -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Vault Default", 3 | "build": { 4 | "dockerfile": "Dockerfile" 5 | }, 6 | "customizations": { 7 | "vscode": { 8 | "extensions": ["hashicorp.hcl"], 9 | "settings": { 10 | "terminal.integrated.defaultProfile.linux": "bash" 11 | } 12 | } 13 | }, 14 | "remoteEnv": { 15 | "VAULT_ADDR": "http://127.0.0.1:8200", 16 | "VAULT_TOKEN": "root" 17 | }, 18 | // After the container starts, run Vault in dev mode 19 | "postStartCommand": "vault server -dev -dev-root-token-id=root & sleep 2 && vault secrets enable -path=secrets kv && vault auth enable approle", 20 | 21 | // Skip setcap configuration in the container for Codespaces 22 | "containerEnv": { 23 | "SKIP_SETCAP": "true" 24 | }, 25 | 26 | // Port forwarding for Vault 27 | "forwardPorts": [8200] 28 | } -------------------------------------------------------------------------------- /.devcontainer/install/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:22.04 2 | 3 | # Avoid prompts during package installation 4 | ENV DEBIAN_FRONTEND=noninteractive 5 | 6 | # Install necessary packages 7 | RUN apt-get update && apt-get install -y \ 8 | curl \ 9 | gpg \ 10 | lsb-release \ 11 | jq \ 12 | vim \ 13 | sudo \ 14 | wget \ 15 | unzip \ 16 | git \ 17 | software-properties-common \ 18 | && rm -rf /var/lib/apt/lists/* 19 | 20 | # Create non-root user 21 | RUN useradd -m -s /bin/bash vaultuser && \ 22 | echo "vaultuser ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers 23 | -------------------------------------------------------------------------------- /.devcontainer/install/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Vault Install", 3 | "build": { 4 | "dockerfile": "Dockerfile", 5 | }, 6 | "customizations": { 7 | "vscode": { 8 | "extensions": ["hashicorp.hcl"], 9 | "settings": { 10 | "terminal.integrated.defaultProfile.linux": "bash" 11 | } 12 | } 13 | }, 14 | "remoteUser": "vaultuser", 15 | "postCreateCommand": "sudo dnf update -y" 16 | } 17 | -------------------------------------------------------------------------------- /.devcontainer/run/Dockerfile: -------------------------------------------------------------------------------- 1 | # Dockerfile 2 | FROM ubuntu:22.04 3 | 4 | # Avoid prompts during package installation 5 | ENV DEBIAN_FRONTEND=noninteractive 6 | 7 | # Install necessary packages 8 | RUN apt-get update && apt-get install -y \ 9 | curl \ 10 | gpg \ 11 | lsb-release \ 12 | jq \ 13 | vim \ 14 | sudo \ 15 | wget \ 16 | unzip \ 17 | git \ 18 | software-properties-common \ 19 | && rm -rf /var/lib/apt/lists/* 20 | 21 | # Create non-root user 22 | RUN useradd -m -s /bin/bash vaultuser && \ 23 | echo "vaultuser ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers && sudo groupadd vault 24 | 25 | RUN sudo useradd -r -m -g vault -d /home/vault -s /bin/bash -c "Vault user" vault 26 | 27 | COPY vault.hcl /etc/vault.d/ 28 | 29 | RUN mkdir -p /opt/vault/data /etc/vault.d /var/lib/vault /usr/local/bin && \ 30 | chown -R vaultuser:vaultuser /opt/vault /etc/vault.d /var/lib/vault && \ 31 | chmod 640 /etc/vault.d/vault.hcl 32 | 33 | # Download and install Vault 34 | RUN wget https://releases.hashicorp.com/vault/1.18.3/vault_1.18.3_linux_amd64.zip && \ 35 | unzip vault_1.18.3_linux_amd64.zip && \ 36 | mv vault /usr/local/bin/ && \ 37 | chown vaultuser:vaultuser /usr/local/bin/vault && \ 38 | chmod 750 /usr/local/bin/vault && \ 39 | rm vault_1.18.3_linux_amd64.zip 40 | 41 | # Create startup script 42 | COPY start-vault.sh /usr/local/bin/ 43 | RUN chmod +x /usr/local/bin/start-vault.sh && \ 44 | chown vaultuser:vaultuser /usr/local/bin/start-vault.sh 45 | -------------------------------------------------------------------------------- /.devcontainer/run/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Vault Run", 3 | "build": { 4 | "dockerfile": "Dockerfile", 5 | "context": "." 6 | }, 7 | "customizations": { 8 | "vscode": { 9 | "extensions": ["hashicorp.hcl"], 10 | "settings": { 11 | "terminal.integrated.defaultProfile.linux": "bash" 12 | } 13 | } 14 | }, 15 | "remoteUser": "vaultuser", 16 | "remoteEnv": { 17 | "VAULT_ADDR": "http://127.0.0.1:8200" 18 | }, 19 | "postCreateCommand": "/usr/local/bin/start-vault.sh & sleep 5", 20 | "forwardPorts": [8200] 21 | } -------------------------------------------------------------------------------- /.devcontainer/run/start-vault.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | export VAULT_ADDR='http://127.0.0.1:8200' 3 | 4 | # Start Vault in background 5 | vault server -config=/etc/vault.d/vault.hcl > /tmp/vault.log 2>&1 & 6 | 7 | # Wait for Vault to start 8 | sleep 5 9 | 10 | # Check if Vault is running 11 | until curl -fs http://127.0.0.1:8200/v1/sys/health > /dev/null; do 12 | echo "Waiting for Vault to start..." 13 | sleep 2 14 | done 15 | 16 | echo "Vault is running and ready for initialization" 17 | -------------------------------------------------------------------------------- /.devcontainer/run/vault.hcl: -------------------------------------------------------------------------------- 1 | storage "file" { 2 | path = "/opt/vault/data" 3 | } 4 | 5 | listener "tcp" { 6 | address = "0.0.0.0:8200" 7 | tls_disable = 1 8 | } 9 | 10 | api_addr = "http://127.0.0.1:8200" 11 | cluster_addr = "http://127.0.0.1:8201" 12 | 13 | ui = true 14 | disable_mlock = true -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [btkrausen] 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | # Creative Commons Attribution-NonCommercial 4.0 International 2 | 3 | This work is licensed under the Creative Commons Attribution-NonCommercial 4.0 International License. 4 | 5 | You are free to: 6 | * Share — copy and redistribute the material in any medium or format 7 | * Adapt — remix, transform, and build upon the material 8 | 9 | Under the following terms: 10 | * Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. 11 | * NonCommercial — You may not use the material for commercial purposes. 12 | 13 | No additional restrictions — You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits. 14 | 15 | ## Notices: 16 | You do not have to comply with the license for elements of the material in the public domain or where your use is permitted by an applicable exception or limitation. 17 | 18 | No warranties are given. The license may not give you all of the permissions necessary for your intended use. For example, other rights such as publicity, privacy, or moral rights may limit how you use the material. 19 | 20 | Learn more about this license at: https://creativecommons.org/licenses/by-nc/4.0/ 21 | 22 | ## Simple Summary 23 | This means: 24 | 1. You can freely use and modify this work for personal, non-commercial purposes 25 | 2. You must credit the original creator 26 | 3. You cannot use this work for commercial purposes without explicit permission 27 | 4. You cannot prevent others from making use of this work under these same conditions 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### Support My Content Here: 2 | 3 | [![Udemy](https://img.shields.io/badge/Udemy-A435F0?style=for-the-badge&logo=Udemy&logoColor=white)](https://btk.me/vb) [![Github Sponsor](https://img.shields.io/badge/sponsor-30363D?style=for-the-badge&logo=GitHub-Sponsors&logoColor=#EA4AAA)](https://github.com/sponsors/btkrausen?frequency=one-time&sponsor=btkrausen) 4 | 5 | # HashiCorp Vault Labs 6 | 7 | [![Bryan Krausen - badge-generator](https://img.shields.io/static/v1?label=btkrausen&message=Profile&color=blue&logo=github)](https://github.com/btkrausen) 8 | 9 | Welcome to this HashiCorp Vault lab repo, where you can get hands-on experience with **HashiCorp Vault** using GitHub Codespaces. In this repository, you’ll find a variety of [labs](./labs) that walk you through using HashiCorp Vault in different scenarios. 10 | 11 | **Note:** GitHub provides users with 120 core hours for FREE per month. [Check your current consumption of hours here](https://github.com/settings/billing/summary#:~:text=%240.00-,Codespaces,-Included%20quotas%20reset). Additionally, you can [set a limit of spending for Codespaces on your account here](https://github.com/settings/billing/spending_limit#:~:text=Spending%20limit%20alerts-,Codespaces,-Limit%20spending). 12 | 13 | ## What’s Included 14 | 15 | - A **pre-configured** development container that installs and runs Vault in your Codespace. 16 | - Multiple labs, each with its own `README.md` and step-by-step instructions. 17 | - Example files, scripts, and configurations to help you practice Vault’s core features. 18 | 19 | ### Built with: 20 | 21 | 22 | vault 23 | Codespaces 24 | 25 | 26 | ## How to Use 27 | 28 | 1. **Create a Codespace** from this repo (click the button below or go to the “Code” drop-down, select “Codespaces,” and create a new one). 29 | 2. Once the Codespace is running, open the integrated terminal. 30 | 3. Follow the instructions in each **lab** to complete the exercises. 31 | 32 | [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/btkrausen/vault-codespaces) 33 | 34 | ## Labs Overview 35 | 36 | Below are a few example labs you can explore. Each link points to a specific lab file or folder within this repository. 37 | 38 | ## HashiCorp Vault Basics 💻 39 | 40 | | **Lab** | **Description** | **Codespace** | **Link** | 41 | | ------------------------- | ------------------------------------------------ | :-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-----------------------------------------: | 42 | | **Install Vault** | Install Vault from Scratch and Start the Service | [Launch](https://github.com/codespaces/new/btkrausen/vault-codespaces?skip_quickstart=true&machine=basicLinux32gb&repo=907851765&ref=main&devcontainer_path=.devcontainer%2Finstall%2Fdevcontainer.json&geo=UsEast) | [Lab](./labs/lab_install_vault_manually.md) | 43 | | **Intro to Vault** | Learn basic Vault commands. | [Launch](https://codespaces.new/btkrausen/vault-codespaces) | [Lab](./labs/lab_intro_to_vault.md) | 44 | | **Using the Vault UI** | Configure and Manage Vault using the UI | [Launch](https://codespaces.new/btkrausen/vault-codespaces) | [Lab](./labs/lab_vault_ui.md) | 45 | | **Using the Vault CLI** | Practice mananaging Vault using the CLI | [Launch](https://codespaces.new/btkrausen/vault-codespaces)|[Lab](./labs/lab_vault_cli.md) | 46 | | **Initialize and Unseal** | Learn how to initialize and unseal Vault | [Launch](https://github.com/codespaces/new?hide_repo_select=true&ref=main&repo=907851765&skip_quickstart=true&machine=basicLinux32gb&devcontainer_path=.devcontainer%2Frun%2Fdevcontainer.json&geo=UsEast) | [Lab](./labs/lab_vault_init_and_unseal.md) | 47 | 48 | ## Vault Authentication 🪪 49 | 50 | | **Lab** | **Description** | **Codespace** | **Link** | 51 | | --------------------------- | ------------------------------------------------------- | :---------------------------------------------------------: | :-----------------------------------------: | 52 | | **Vault Tokens** | Learn the basics of using Vault tokens to authenticate. | [Launch](https://codespaces.new/btkrausen/vault-codespaces) | [Lab](./labs/lab_vault_tokens.md) | 53 | | **Vault Response Wrapping** | Use Response Wrapping to protect secrets | [Launch](https://codespaces.new/btkrausen/vault-codespaces) | [Lab](./labs/lab_response_wrapping.md) | 54 | | **AppRole Auth Method** | Enable, configure, and use the AppRole Auth Method | [Launch](https://codespaces.new/btkrausen/vault-codespaces) | [Lab](./labs/lab_approle_auth_method.md) | 55 | | **Userpass Auth Method** | Configure the Userpass Auth Method | [Launch](https://codespaces.new/btkrausen/vault-codespaces) | [Lab](./labs/lab_userpass_auth_method.md) | 56 | | **Kubernetes Auth Method** | Learn how to enable and configure the k8s auth method | [Launch](https://codespaces.new/btkrausen/vault-codespaces) | [Lab](./labs/lab_kubernetes_auth_method.md) | 57 | 58 | ## Vault Secrets Engines 🔑 59 | 60 | | **Lab** | **Description** | **Codespace** | **Link** | 61 | | ---------------------------- | ------------------------------------------------------- | :---------------------------------------------------------: | :-----------------------------------------: | 62 | | **Key/Value Secrets Engine** | Create, read, update, and delete secrets in Vault. | [Launch](https://codespaces.new/btkrausen/vault-codespaces) | [Lab](./labs/lab_kv_secrets_engine.md) | 63 | | **Transit Secrets Engine** | Learn how to encrypt data using HashiCorp Vault | [Launch](https://codespaces.new/btkrausen/vault-codespaces) | [Lab](./labs/lab_transit_secrets_engine.md) | 64 | | **PKI Secrets Engine** | Use Vault as a Certificate Authority and generate certs | [Launch](https://codespaces.new/btkrausen/vault-codespaces) | [Lab](./labs/lab_pki_secrets_engine.md) | 65 | 66 | ## Vault Management and Operations ⛭ 67 | 68 | | **Lab** | **Description** | **Codespace** | **Link** | 69 | | -------------------------------- | ---------------------------------------------- | :---------------------------------------------------------: | :------------------------------------------------: | 70 | | **Vault Policies** | Create and assign policies to restrict access. | [Launch](https://codespaces.new/btkrausen/vault-codespaces) | [Lab](./labs/lab_vault_policies.md) | 71 | | **Vault Audit Devices** | Enable and configure an audit device. | [Launch](https://codespaces.new/btkrausen/vault-codespaces) | [Lab](./labs/lab_audit_devices.md) | 72 | | **Integrate Vault w/ Terraform** | Learn how to query Vault when using Terraform | [Launch](https://codespaces.new/btkrausen/vault-codespaces) | [Lab](./labs/lab_integrate_terraform_and_vault.md) | 73 | 74 | --- 75 | 76 | ## Contributing 77 | 78 | If you’d like to add more labs or improve these, feel free to fork this repo or open a pull request. Feedback and contributions are always welcome! 79 | 80 | --- 81 | 82 | Enjoy your journey with Vault! 83 | -------------------------------------------------------------------------------- /labs/img/ports.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/btkrausen/vault-codespaces/1690443ce6aba086b38f745a134e7a109b7cd12b/labs/img/ports.png -------------------------------------------------------------------------------- /labs/lab_approle_auth_method.md: -------------------------------------------------------------------------------- 1 | 2 | # AppRole Authentication Lab 3 | 4 | ## Overview 5 | Learn to configure and use Vault's AppRole auth method for application authentication. 6 | 7 | **Time to Complete**: 20 minutes 8 | 9 | **Preview Mode**: Use `Cmd/Ctrl + Shift + V` in VSCode to see a nicely formatted version of this lab! 10 | 11 | ## How to Use This Hands-On Lab 12 | 13 | 1. **Create a Codespace** from this repo (click the button below). 14 | 2. Once the Codespace is running, open the integrated terminal. 15 | 3. Follow the instructions in each **lab** to complete the exercises. 16 | 17 | [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/btkrausen/vault-codespaces) 18 | 19 | ## Steps 20 | 21 | 1. Enable AppRole auth if not yet enabled: 22 | ```bash 23 | # Log in with a valid token 24 | vault login root 25 | 26 | # Validate that AppRole is already enabled at the approle/ path 27 | vault auth list 28 | 29 | # Enable AppRole if not yet enabled 30 | vault auth enable approle 31 | ``` 32 | 33 | 2. Create policy for the app: 34 | ```bash 35 | vault policy write app-policy - < Note: If you are performing the labs on your own machine, you might need to add `sudo` before the following commands to work. This is not necessary on the Codespace instance since it automatically logs you in as the `root` user. 35 | 36 | ### 2. Enable File Audit Device 37 | Enable the file audit device and configure it to write to a specific file: 38 | ```bash 39 | # Create directory for audit logs with appropriate permissions 40 | mkdir -p /var/log/vault 41 | chown vault:vault /var/log/vault 42 | 43 | # Enable file audit device 44 | vault audit enable file file_path=/var/log/vault/audit.log 45 | 46 | # Verify audit device is enabled 47 | vault audit list 48 | 49 | # View more details about the audit device, including the targeted path/file 50 | vault audit list --detailed 51 | ``` 52 | 53 | ### 3. Generate Audit Events 54 | Perform various operations to generate audit logs: 55 | 56 | a. Create a secret: 57 | ```bash 58 | # Enable KV secrets engine if not already enabled 59 | vault secrets enable -path=secret kv-v2 60 | 61 | # Repeat the step above to purposely create an error 62 | vault secrets enable -path=secret kv-v2 63 | 64 | # Create a test secret 65 | vault kv put secret/test-secret username=admin password=vault-demo 66 | ``` 67 | 68 | b. Read the secret: 69 | ```bash 70 | vault kv get secret/test-secret 71 | ``` 72 | 73 | c. Update the secret: 74 | ```bash 75 | vault kv put secret/test-secret username=admin password=updated-password 76 | ``` 77 | 78 | d. List secrets: 79 | ```bash 80 | vault kv list secret/ 81 | ``` 82 | 83 | e. Delete the secret: 84 | ```bash 85 | vault kv delete secret/test-secret 86 | ``` 87 | 88 | ### 4. Examine Audit Logs 89 | Review and analyze the generated audit logs: 90 | ```bash 91 | # View raw audit logs 92 | cat /var/log/vault/audit.log 93 | 94 | # Parse JSON logs with jq (if installed) 95 | cat /var/log/vault/audit.log | jq '.' 96 | 97 | # Search for specific operations performed above 98 | grep "secret/test-secret" /var/log/vault/audit.log | jq '.' 99 | ``` 100 | 101 | ### 5. Understanding Audit Log Structure 102 | Each audit log entry contains: 103 | - timestamp 104 | - type (request/response) 105 | - auth information 106 | - request/response data 107 | - error information (if applicable) 108 | 109 | Example analysis tasks: 110 | ```bash 111 | # Find all KV secret operations 112 | grep "secret/" /var/log/vault/audit.log | jq '.' 113 | 114 | # Look for specific authentication events 115 | grep "login" /var/log/vault/audit.log | jq '.' 116 | 117 | # Find error events 118 | grep "error" /var/log/vault/audit.log | jq '.' 119 | ``` 120 | 121 | ### 6. Log Rotation Practice 122 | Set up basic log rotation: 123 | ```bash 124 | # Create logrotate configuration 125 | tee /etc/logrotate.d/vault < to get the command prompt back 117 | ``` 118 | 119 | 2. Set environment variable: 120 | 121 | ```bash 122 | export VAULT_ADDR='http://127.0.0.1:8200' 123 | ``` 124 | 125 | 3. Verify Vault is running: 126 | 127 | ```bash 128 | # Check if Vault is responding 129 | curl http://127.0.0.1:8200/v1/sys/health | jq 130 | ``` 131 | 132 | 4. Verify Vault is running and responding to commands: 133 | 134 | ```bash 135 | vault status 136 | ``` 137 | 138 | ## 🚀 Congrats, you've successfully installed HashiCorp Vault manually 139 | 140 | ## ❗ Important Notes 141 | 142 | 1. **Security Considerations** 143 | - This setup uses `tls_disable = 1` - not for production 144 | - Uses `disable_mlock = true` - not for production 145 | - Store unseal keys securely in production 146 | - Enable audit logging in production 147 | 148 | ## 🎯 Success Criteria 149 | 150 | You've completed the lab when you can: 151 | 152 | - [x] Successfully install Vault 153 | - [x] Configure system user and directories 154 | - [x] Start Vault server process 155 | 156 | ## ❓ Troubleshooting 157 | 158 | 1. **Server Won't Start** 159 | 160 | - Check if process is running: `ps aux | grep vault` 161 | - Check ownership of directories 162 | - Verify configuration file syntax 163 | 164 | 2. **Cannot Connect** 165 | 166 | - Verify VAULT_ADDR is set 167 | - Check if process is running 168 | - Ensure Vault is unsealed 169 | - Test with curl: `curl http://127.0.0.1:8200/v1/sys/health` 170 | 171 | 3. **Permission Issues** 172 | - Check ownership: `ls -l /usr/local/bin/vault` 173 | - Verify directory permissions: `ls -l /opt/vault/data` 174 | 175 | ## 📚 Additional Resources 176 | 177 | - [Vault Documentation](https://www.vaultproject.io/docs) 178 | - [Production Hardening](https://www.vaultproject.io/docs/concepts/production-hardening) 179 | - [Binary Downloads](https://www.vaultproject.io/downloads) 180 | 181 | --- 182 | 183 | _Happy Vault Installing! 🔐_ 184 | -------------------------------------------------------------------------------- /labs/lab_integrate_terraform_and_vault.md: -------------------------------------------------------------------------------- 1 | # Hands-on Lab: Integrating HashiCorp Vault with Terraform 2 | 3 | ## Overview 4 | In this lab, you will learn how to integrate HashiCorp Vault with Terraform using proper authentication and authorization. You will create a new Key-Value secrets engine, write secrets to it, create a dedicated policy and token for Terraform, and then use Terraform to access and output these secrets. 5 | 6 | **Time Required:** ~45 minutes 7 | 8 | **Preview Mode**: Use `Cmd/Ctrl + Shift + V` in VSCode to see a nicely formatted version of this lab! 9 | 10 | ## How to Use This Hands-On Lab 11 | 12 | 1. **Create a Codespace** from this repo (click the button below). 13 | 2. Once the Codespace is running, open the integrated terminal. 14 | 3. Follow the instructions in each **lab** to complete the exercises. 15 | 16 | [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/btkrausen/vault-codespaces) 17 | 18 | ## Steps 19 | 20 | ### Step 1: Verify Vault Status 21 | 22 | 1. Open your terminal, authenticate, and verify Vault is running in dev mode: 23 | ```bash 24 | # Log in with a valid token 25 | vault login root 26 | 27 | # Check the status of Vault 28 | vault status 29 | ``` 30 | 31 | You should see output indicating Vault is initialized and unsealed. 32 | 33 | ### Step 2: Create a New KV Secrets Engine 34 | 35 | 1. Enable a new KV version 2 secrets engine: 36 | ```bash 37 | vault secrets enable -path=kv kv-v2 38 | ``` 39 | 40 | 2. Write some example secrets: 41 | ```bash 42 | # Write a database credential secret 43 | vault kv put kv/database/config username="db_user" password="db_password123" 44 | 45 | # Write an API key secret 46 | vault kv put kv/api/keys development="dev_api_key_123" production="prod_api_key_456" 47 | ``` 48 | 49 | 3. Verify the secrets were written correctly: 50 | ```bash 51 | vault kv get kv/database/config 52 | vault kv get kv/api/keys 53 | ``` 54 | 55 | ### Step 3: Create a Vault Policy for Terraform 56 | 57 | 1. In VSCode, create a new file named `terraform-policy.hcl` (right click in the left navigation pane): 58 | ```hcl 59 | # Configure access to KV v2 secrets engine 60 | path "kv/data/database/config" { 61 | capabilities = ["read"] 62 | } 63 | 64 | path "kv/data/api/keys" { 65 | capabilities = ["read"] 66 | } 67 | 68 | # Allow listing available secrets 69 | path "kv/metadata/*" { 70 | capabilities = ["list"] 71 | } 72 | ``` 73 | 74 | 2. Write the policy to Vault: 75 | ```bash 76 | vault policy write terraform terraform-policy.hcl 77 | ``` 78 | 79 | 3. Verify the policy was created: 80 | ```bash 81 | vault policy read terraform 82 | ``` 83 | 84 | ### Step 4: Create a Token for Terraform 85 | 86 | 1. Create a token with the terraform policy: 87 | ```bash 88 | vault token create \ 89 | -policy=terraform \ 90 | -display-name=terraform-config \ 91 | -metadata=purpose="terraform-infrastructure" \ 92 | -metadata=environment="dev" \ 93 | -metadata=owner="infrastructure-team" 94 | ``` 95 | 96 | 2. Save the token value from the output. You'll need this later. The output will look something like: 97 | ``` 98 | Key Value 99 | --- ----- 100 | token hvs.CAESIEJ9-xWawVtRW9G7d3A... 101 | token_accessor qROJGbssISX3NaRx3JaOh9X6 102 | token_duration 768h 103 | token_renewable true 104 | token_policies ["default" "terraform"] 105 | identity_policies [] 106 | policies ["default" "terraform"] 107 | token_meta_purpose terraform-infrastructure 108 | token_meta_environment dev 109 | token_meta_owner infrastructure-team 110 | ``` 111 | 112 | ### Step 5: Create Terraform Configuration Files 113 | 114 | 1. Using the CLI, create a new directory for your Terraform configuration: 115 | ```bash 116 | mkdir vault-terraform-lab 117 | cd vault-terraform-lab 118 | ``` 119 | 120 | 2. Create a new file named `provider.tf` (right click the `vault-terraform-lab` directory in the left navigation pane): 121 | ```hcl 122 | terraform { 123 | required_providers { 124 | vault = { 125 | source = "hashicorp/vault" 126 | version = "~> 4.5.0" 127 | } 128 | } 129 | } 130 | 131 | provider "vault" { 132 | # Token will be loaded from environment variable VAULT_TOKEN 133 | # Vault address and port - running locally on the GitHub Codespace 134 | address = "http://127.0.0.1:8200" 135 | } 136 | ``` 137 | 138 | 3. Create a new file named `main.tf`: 139 | ```hcl 140 | # Read database secrets from Vault 141 | data "vault_kv_secret_v2" "database_creds" { 142 | mount = "kv" 143 | name = "database/config" 144 | } 145 | 146 | # Read API Keys from Vault 147 | data "vault_kv_secret_v2" "api_keys" { 148 | mount = "kv" 149 | name = "api/keys" 150 | } 151 | 152 | # Example resource that would use the secrets 153 | resource "null_resource" "example" { 154 | provisioner "local-exec" { 155 | command = "echo 'This is where you would use the secrets in your actual infrastructure'" 156 | } 157 | } 158 | ``` 159 | 160 | 4. Create a new file named `outputs.tf`: 161 | ```hcl 162 | output "database_username" { 163 | value = data.vault_kv_secret_v2.database_creds.data["username"] 164 | sensitive = true 165 | } 166 | 167 | output "database_password" { 168 | value = data.vault_kv_secret_v2.database_creds.data["password"] 169 | sensitive = true 170 | } 171 | 172 | output "dev_api_key" { 173 | value = data.vault_kv_secret_v2.api_keys.data["development"] 174 | sensitive = true 175 | } 176 | 177 | output "prod_api_key" { 178 | value = data.vault_kv_secret_v2.api_keys.data["production"] 179 | sensitive = true 180 | } 181 | ``` 182 | 183 | ### Step 6: Initialize and Apply Terraform Configuration 184 | 185 | 1. Set the required environment variables: 186 | ```bash 187 | export VAULT_TOKEN='' # Use the token created in Step 4.2 above 188 | ``` 189 | > If you didn't save the token from Step 4.2, simply run it again to create another token 190 | 191 | 2. Initialize the Terraform working directory: 192 | ```bash 193 | terraform init 194 | ``` 195 | 196 | 3. Verify the plan works with the restricted token: 197 | ```bash 198 | terraform plan 199 | ``` 200 | 201 | 4. Apply the Terraform configuration and confirm by typing `yes` (notice the secrets are marked as sensitive): 202 | ```bash 203 | terraform apply 204 | ``` 205 | 206 | 5. View the outputs defined in the `outputs.tf` ((notice the secrets are marked as sensitive)): 207 | ```bash 208 | terraform output 209 | ``` 210 | 211 | Note: The outputs will be shown as sensitive values. To see the actual values, you can use: 212 | ```bash 213 | terraform output database_username 214 | terraform output database_password 215 | terraform output dev_api_key 216 | terraform output prod_api_key 217 | ``` 218 | 219 | ### 🎉 Congrats, you've successfully integrated HashiCorp Terraform and Vault. Terraform was able to obtain secrets from Vault to use within the Terraform configuration. 220 | 221 | ## Challenge Exercises 222 | 223 | 1. Modify the policy to allow Terraform to write secrets as well as read them. Update the Terraform configuration to write a new secret. 224 | 225 | 2. Create a new KV secrets engine at a different path and update the policy and Terraform configuration to read secrets from both KV engines. 226 | 227 | 3. Implement token rotation by creating a new token with the same policy and updating your Terraform configuration to use it. 228 | 229 | 4. Add metadata to your secrets and modify the policy to allow Terraform to read the metadata. 230 | 231 | ## Clean Up 232 | 233 | 1. Unset the VAULT_TOKEN environment variable 234 | ```bash 235 | unset VAULT_TOKEN 236 | ``` 237 | 238 | 2. Revoke the Terraform token: 239 | ```bash 240 | vault token revoke 241 | ``` 242 | 243 | 3. Delete the policy: 244 | ```bash 245 | vault policy delete terraform 246 | ``` 247 | 248 | 4. Destroy the Terraform resources: 249 | ```bash 250 | terraform destroy 251 | ``` 252 | 253 | 5. Delete the secrets from Vault: 254 | ```bash 255 | vault kv delete kv/database/config 256 | vault kv delete kv/api/keys 257 | ``` 258 | 259 | 6. Disable the KV secrets engine: 260 | ```bash 261 | vault secrets disable kv 262 | ``` 263 | 264 | ## Conclusion 265 | 266 | In this lab, you learned how to: 267 | - Create and manage secrets in Vault's KV secrets engine 268 | - Create a restricted policy for Terraform access 269 | - Generate and use a dedicated token for Terraform 270 | - Configure Terraform to authenticate with Vault 271 | - Use Terraform to read secrets from Vault 272 | - Output sensitive values safely using Terraform's output blocks 273 | 274 | These practices form the foundation of secure secret management in a production environment. Key takeaways include: 275 | - Always use the principle of least privilege when creating policies 276 | - Use dedicated tokens with appropriate policies for service authentication 277 | - Implement proper token rotation and revocation procedures 278 | - Be cautious with sensitive output values 279 | 280 | ## Additional Resources 281 | 282 | - [Vault Provider Documentation](https://registry.terraform.io/providers/hashicorp/vault/latest/docs) 283 | - [Vault KV Secrets Engine Documentation](https://www.vaultproject.io/docs/secrets/kv/kv-v2) 284 | - [Vault Policy Documentation](https://www.vaultproject.io/docs/concepts/policies) 285 | - [Vault Token Documentation](https://www.vaultproject.io/docs/concepts/tokens) 286 | - [Best Practices for Using Vault with Terraform](https://www.hashicorp.com/resources/best-practices-using-hashicorp-terraform-with-hashicorp-vault) -------------------------------------------------------------------------------- /labs/lab_intro_to_vault.md: -------------------------------------------------------------------------------- 1 | # Introduction to Vault CLI Commands Lab 2 | 3 | ## Overview 4 | In this lab, you'll learn the fundamental Vault CLI commands to check the status of your Vault server, view enabled features, and understand basic Vault operations. 5 | 6 | **Time to Complete**: 15-20 minutes 7 | 8 | **Preview Mode**: Use `Cmd/Ctrl + Shift + V` in VSCode to see a nicely formatted version of this lab! 9 | 10 | ## How to Use This Hands-On Lab 11 | 12 | 1. **Create a Codespace** from this repo (click the button below). 13 | 2. Once the Codespace is running, open the integrated terminal. 14 | 3. Follow the instructions in each **lab** to complete the exercises. 15 | 16 | [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/btkrausen/vault-codespaces) 17 | 18 | ## Steps 19 | 20 | ### Part 1: Basic Server Status 21 | 22 | 1. Check the status of your Vault server: 23 | ```bash 24 | vault status 25 | ``` 26 | This shows: 27 | - Seal Status 28 | - Initialize Status 29 | - Server Version 30 | - Storage Type 31 | - HA Status 32 | 33 | 2. Authenticate to Vault using the root token: 34 | ```bash 35 | vault login root 36 | ``` 37 | 38 | ### Part 2: Secret Engines 39 | 40 | 1. List enabled secret engines: 41 | ```bash 42 | vault secrets list 43 | ``` 44 | Notice there are several secrets engines already enabled, including a KV store at `secrets/` 45 | 46 | 2. Get information about a specific secrets engine: 47 | ```bash 48 | vault secrets list -detailed 49 | ``` 50 | 51 | ### Part 3: Authentication Methods 52 | 53 | 1. List enabled auth methods: 54 | ```bash 55 | vault auth list 56 | ``` 57 | Notice that several auth methods are available, including `AppRole` 58 | 59 | 2. Get detailed auth method information: 60 | ```bash 61 | vault auth list -detailed 62 | ``` 63 | 64 | ### Part 4: Basic Key-Value Operations 65 | 66 | 1. Write a secret: 67 | ```bash 68 | vault kv put secret/first hello=world 69 | vault kv put secret/my-secret username=admin password=secret123 70 | ``` 71 | 72 | 2. Read a secret: 73 | ```bash 74 | vault kv get secret/first 75 | vault kv get -field=hello secret/first 76 | ``` 77 | 78 | 3. List secrets in a path: 79 | ```bash 80 | vault kv list secret/ 81 | ``` 82 | 83 | 4. Delete a secret: 84 | ```bash 85 | vault kv delete secret/first 86 | ``` 87 | 88 | ### Part 5: Token Information 89 | 90 | 1. View current token information: 91 | ```bash 92 | vault token lookup 93 | ``` 94 | 95 | 2. View token capabilities: 96 | ```bash 97 | vault token capabilities secret/first 98 | ``` 99 | 100 | 3. Create a new token: 101 | ```bash 102 | vault token create -ttl=1h 103 | ``` 104 | 105 | ## Challenge Exercise 106 | 107 | 1. Use JSON format for secret data: 108 | ```bash 109 | vault kv put secret/user - < mock-ca.crt 39 | ``` 40 | # Create mock JWT token 41 | ```bash 42 | echo "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6InRlc3Qtc2EiLCJpYXQiOjE1MTYyMzkwMjJ9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c" > jwt.txt 43 | ``` 44 | 45 | 2. Enable auth method: 46 | ```bash 47 | # Log in with a valid token 48 | vault login root 49 | 50 | # Enable the Kubernetes auth method 51 | vault auth enable kubernetes 52 | ``` 53 | 54 | 3. Configure Kubernetes auth configuration (this is a per cluster configuration): 55 | ```bash 56 | 57 | # Configure Kubernetes auth 58 | vault write auth/kubernetes/config \ 59 | kubernetes_host="https://mock-k8s:8443" \ 60 | token_reviewer_jwt=@jwt.txt \ 61 | kubernetes_ca_cert=@mock-ca.crt \ 62 | issuer="https://kubernetes.default.svc.cluster.local" 63 | ``` 64 | 65 | 4. Create app policy: 66 | ```bash 67 | vault policy write my-app-policy - < root_ca.json 46 | 47 | cat root_ca.json | jq -r .data.certificate > root_ca.pem 48 | ``` 49 | 50 | 3. Configure the CA and CRL URLs: 51 | ```bash 52 | vault write pki_root/config/urls \ 53 | issuing_certificates="http://vault.lab:8200/v1/pki_root/ca" \ 54 | crl_distribution_points="http://vault.lab:8200/v1/pki_root/crl" 55 | ``` 56 | 57 | ### Step 3: Create Intermediate CA 58 | 59 | 1. Enable a PKI secrets engine for the intermediate CA: 60 | ```bash 61 | vault secrets enable -path=pki_int pki 62 | ``` 63 | 64 | 2. Set a shorter max TTL for the intermediate CA (5 years): 65 | ```bash 66 | vault secrets tune -max-lease-ttl=43800h pki_int 67 | ``` 68 | 69 | 3. Generate and view the intermediate CSR directly: 70 | ```bash 71 | vault write pki_int/intermediate/generate/internal \ 72 | common_name="Lab Intermediate CA" \ 73 | ttl=43800h 74 | ``` 75 | 76 | 4. Generate it again and save to a file: 77 | ```bash 78 | vault write -format=json pki_int/intermediate/generate/internal \ 79 | common_name="Lab Intermediate CA" \ 80 | ttl=43800h > intermediate.json 81 | 82 | cat intermediate.json | jq -r .data.csr > intermediate.csr 83 | ``` 84 | 85 | 5. Sign the intermediate CSR with the root CA and save to a file: 86 | ```bash 87 | vault write -format=json pki_root/root/sign-intermediate \ 88 | csr=@intermediate.csr \ 89 | format=pem_bundle \ 90 | ttl=43800h > signed_intermediate.json 91 | 92 | cat signed_intermediate.json | jq -r .data.certificate > signed_intermediate.pem 93 | ``` 94 | 95 | 7. Import the signed certificate back into the Vault Intermediate: 96 | ```bash 97 | vault write pki_int/intermediate/set-signed \ 98 | certificate=@signed_intermediate.pem 99 | ``` 100 | 101 | ### Step 4: Create a Role for Issuing Certificates 102 | 103 | 1. Create a role for issuing certificates for a webapp: 104 | ```bash 105 | vault write pki_int/roles/webapp \ 106 | allowed_domains="lab.local" \ 107 | allow_subdomains=true \ 108 | max_ttl=720h \ 109 | key_type="rsa" \ 110 | key_bits=2048 \ 111 | allowed_uri_sans="dns://lab.local" \ 112 | require_cn=true \ 113 | basic_constraints_valid_for_non_ca=true 114 | ``` 115 | 116 | ### Step 5: Generate a Certificate for the webapp: 117 | 118 | 1. Generate and view a certificate directly in the CLI: 119 | ```bash 120 | vault write pki_int/issue/webapp \ 121 | common_name="webapp.lab.local" \ 122 | ttl=72h 123 | ``` 124 | 125 | This will display: 126 | - The certificate 127 | - The private key (Vault will only output the private key once) 128 | - CA chain 129 | - Serial number 130 | - Other metadata 131 | 132 | 2. Issue a certificate and save it to files (useful for deploying to services): 133 | ```bash 134 | vault write -format=json pki_int/issue/webapp \ 135 | common_name="webapp.lab.local" \ 136 | ttl=72h > webapp_cert.json 137 | 138 | # Extract each component to its own file 139 | cat webapp_cert.json | jq -r .data.certificate > webapp_cert.pem 140 | cat webapp_cert.json | jq -r .data.private_key > webapp_key.pem 141 | cat webapp_cert.json | jq -r .data.ca_chain[] > webapp_ca_chain.pem 142 | 143 | # [Optional] View each file to see the contents 144 | cat webapp_cert.pem 145 | cat webapp_key.pem 146 | cat webapp_ca_chain.pem 147 | ``` 148 | 149 | ### Step 6: Verify the Certificate 150 | 151 | 1. View the certificate details: 152 | ```bash 153 | # For the CLI-generated certificate, copy the certificate content to a file first 154 | # For the file-based certificate: 155 | openssl x509 -in webapp_cert.pem -text -noout 156 | ``` 157 | 158 | ### Step 7: Working with Certificate Revocation 159 | 160 | 1. View a certificate's serial number: 161 | ```bash 162 | # Directly from CLI output when generating 163 | vault write pki_int/issue/webapp common_name="temp.lab.local" ttl=72h 164 | 165 | # Or from a saved certificate 166 | openssl x509 -in webapp_cert.pem -noout -serial 167 | ``` 168 | 169 | 2. Revoke a certificate: 170 | ```bash 171 | vault write pki_int/revoke \ 172 | serial_number= 173 | ``` 174 | 175 | 3. Generate a new CRL: 176 | ```bash 177 | vault write pki_int/config/urls \ 178 | issuing_certificates="http://vault.lab:8200/v1/pki_int/ca" \ 179 | crl_distribution_points="http://vault.lab:8200/v1/pki_int/crl" 180 | ``` 181 | 182 | ## Create a Vault Policy for the Application named `webapp` to Generate a PKI Certificate 183 | 184 | 1. Create a new file named `webapp-policy.hcl` 185 | 186 | **Right-click** in the left navigation pane or use the command `touch webapp-policy.hcl` 187 | 188 | ```hcl 189 | # Permit reading the configured certificates 190 | path "pki_int/cert/*" { 191 | capabilities = ["read", "list"] 192 | } 193 | 194 | # Permit creating certificates from the webapp role 195 | path "pki_int/issue/webapp" { 196 | capabilities = ["create", "update"] 197 | } 198 | 199 | # Allow reading the CRL and CA certificate 200 | path "pki_int/cert/ca" { 201 | capabilities = ["read"] 202 | } 203 | 204 | path "pki_int/cert/crl" { 205 | capabilities = ["read"] 206 | } 207 | ``` 208 | 209 | 2. Write the policy to Vault: 210 | ```bash 211 | vault policy write policy-webapp-pki webapp-policy.hcl 212 | ``` 213 | > Note: In production, you would most likely attach this policy to your webapp's authentication role to give it the authorization to generate certificates (among other permissions it might need). 214 | 215 | ## Challenge Exercises 216 | 217 | 1. Create certificates with different parameters: 218 | - Generate a certificate with multiple Subject Alternative Names (SANs): 219 | ```bash 220 | vault write pki_int/issue/webapp \ 221 | common_name="webapp.lab.local" \ 222 | alt_names="app.lab.local,api.lab.local" \ 223 | ttl=72h 224 | ``` 225 | - Save the multi-SAN certificate to files 226 | - Compare the CLI output with the saved files 227 | 228 | 2. Create a wildcard certificate: 229 | ```bash 230 | vault write pki_int/issue/webapp \ 231 | common_name="*.lab.local" \ 232 | ttl=72h 233 | ``` 234 | 235 | 3. Implement certificate rotation: 236 | - Issue a certificate with a 1-hour TTL 237 | - Write a script to check expiration and auto-renew 238 | - Handle both CLI output and file-based storage 239 | 240 | ## Clean Up 241 | 242 | 1. Revoke all certificates issued by the intermediate CA: 243 | ```bash 244 | vault write pki_int/tidy \ 245 | tidy_cert_store=true \ 246 | tidy_revoked_certs=true \ 247 | safety_buffer=72h 248 | ``` 249 | 250 | 2. Disable the PKI secrets engines: 251 | ```bash 252 | vault secrets disable pki_root 253 | vault secrets disable pki_int 254 | ``` 255 | 256 | 3. Remove generated files: 257 | ```bash 258 | rm *.json *.pem *.csr 259 | ``` 260 | 261 | ## Best Practices 262 | 263 | 1. **Certificate Generation**: 264 | - Use CLI output for testing and verification 265 | - Use file-based storage for production deployments 266 | - Always secure private key files with appropriate permissions 267 | 268 | 2. **Root CA Management**: 269 | - Keep the root CA offline when not in use 270 | - Use long validity periods for root CAs 271 | - Maintain secure backups of root CA private keys 272 | 273 | 3. **Intermediate CA**: 274 | - Use intermediate CAs for day-to-day certificate issuance 275 | - Implement regular rotation of intermediate CA certificates 276 | - Maintain separate intermediates for different environments 277 | 278 | 4. **Monitoring and Auditing**: 279 | - Regular monitoring of certificate expiration 280 | - Audit of certificate issuance and revocation 281 | - Monitoring of CRL and OCSP availability 282 | 283 | ## Conclusion 284 | 285 | In this lab, you learned how to: 286 | - Set up a complete PKI infrastructure using Vault 287 | - Generate and manage root and intermediate CAs 288 | - Issue certificates using both CLI and file-based methods 289 | - Implement certificate management best practices 290 | 291 | ## Additional Resources 292 | 293 | - [Vault PKI Secrets Engine Documentation](https://www.vaultproject.io/docs/secrets/pki) 294 | - [OpenSSL Documentation](https://www.openssl.org/docs/) 295 | - [PKI Best Practices](https://www.hashicorp.com/blog/certificate-management-with-vault) 296 | - [Automated Certificate Management](https://learn.hashicorp.com/tutorials/vault/pki-engine) -------------------------------------------------------------------------------- /labs/lab_response_wrapping.md: -------------------------------------------------------------------------------- 1 | # Response Wrapping Lab: Secret Retrieval 2 | 3 | ## Overview 4 | Learn how to create and use response wrapping tokens to securely share Vault secrets. 5 | 6 | **Time to Complete**: 10 minutes 7 | 8 | **Preview Mode**: Use `Cmd/Ctrl + Shift + V` in VSCode to see a nicely formatted version of this lab! 9 | 10 | ## How to Use This Hands-On Lab 11 | 12 | 1. **Create a Codespace** from this repo (click the button below). 13 | 2. Once the Codespace is running, open the integrated terminal. 14 | 3. Follow the instructions in each **lab** to complete the exercises. 15 | 16 | [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/btkrausen/vault-codespaces) 17 | 18 | ## Steps 19 | 20 | 1. Create a secret: 21 | ```bash 22 | # Log in with a valid token 23 | vault login root 24 | 25 | # Create the secret 26 | vault kv put secret/demo username=admin password=secret123 27 | ``` 28 | 29 | 2. Read secret normally: 30 | ```bash 31 | vault kv get secret/demo 32 | ``` 33 | 34 | 3. Create a wrapped token for reading the same secret: 35 | ```bash 36 | vault kv get -wrap-ttl=1h -format=json secret/demo 37 | # Save the wrapping_token from output 38 | ``` 39 | 40 | 4. Use wrapped token to retrieve the secret: 41 | ```bash 42 | vault unwrap 43 | ``` 44 | 45 | 5. Try unwrapping again (will fail since wrapping tokens can only be used once): 46 | ```bash 47 | vault unwrap 48 | ``` 49 | 50 | ## Testing Different Scenarios 51 | 52 | 1. Short TTL wrap: 53 | ```bash 54 | vault kv get -wrap-ttl=30s secret/demo 55 | sleep 31 56 | vault unwrap # Should fail as token is now expired 57 | ``` 58 | 59 | 2. Wrap specific field: 60 | ```bash 61 | vault kv get -wrap-ttl=1h -field=password secret/demo 62 | vault unwrap # Returns only password 63 | ``` 64 | 65 | ## Challenge Exercise 66 | 67 | 1. Create multi-step wrapping: 68 | - Create a secret 69 | - Wrap it with 1h TTL 70 | - Create policy allowing unwrap 71 | - Create token with policy 72 | - Pass wrapped token to new token 73 | 74 | ## Cleanup 75 | ```bash 76 | vault kv delete secret/credentials 77 | vault kv delete secret/short-lived 78 | ``` -------------------------------------------------------------------------------- /labs/lab_transit_secrets_engine.md: -------------------------------------------------------------------------------- 1 | # Transit Secrets Engine Lab 2 | 3 | ## Overview 4 | Learn to use Vault's Transit secrets engine for encryption operations. 5 | 6 | **Time to Complete**: 20-25 minutes 7 | 8 | **Preview Mode**: Use `Cmd/Ctrl + Shift + V` in VSCode to see a nicely formatted version of this lab! 9 | 10 | ## How to Use This Hands-On Lab 11 | 12 | 1. **Create a Codespace** from this repo (click the button below). 13 | 2. Once the Codespace is running, open the integrated terminal. 14 | 3. Follow the instructions in each **lab** to complete the exercises. 15 | 16 | [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/btkrausen/vault-codespaces) 17 | 18 | ## Steps 19 | 20 | 1. Enable the Transit engine: 21 | ```bash 22 | # Log in with a valid token 23 | vault login root 24 | 25 | # Enable the Transit secrets engine 26 | vault secrets enable transit 27 | ``` 28 | 29 | 2. Create an encryption key: 30 | ```bash 31 | vault write -f transit/keys/my-app 32 | ``` 33 | 34 | ## Part 1: Basic Encryption/Decryption 35 | 36 | 1. Encrypt data: 37 | ```bash 38 | # Encode data in base64 39 | echo -n "sensitive data" | base64 40 | 41 | # Encrypt the data 42 | vault write transit/encrypt/my-app plaintext=$(echo -n "sensitive data" | base64) 43 | ``` 44 | 45 | 2. Decrypt data: 46 | ```bash 47 | # Store the ciphertext from previous step 48 | CIPHER="vault:v1:abc123..." # Use your actual ciphertext 49 | 50 | # Decrypt 51 | vault write transit/decrypt/my-app ciphertext=$CIPHER 52 | ``` 53 | 54 | 3. Decode the result: 55 | ```bash 56 | echo "base64-output" | base64 -d # Replace with actual output 57 | ``` 58 | 59 | ## Part 2: Key Rotation 60 | 61 | 1. Rotate the encryption key: 62 | ```bash 63 | vault write -f transit/keys/my-app/rotate 64 | ``` 65 | 66 | 2. Check key details: 67 | ```bash 68 | vault read transit/keys/my-app 69 | ``` 70 | 71 | 3. Encrypt new data (uses latest key version): 72 | ```bash 73 | vault write transit/encrypt/my-app plaintext=$(echo -n "new data" | base64) 74 | ``` 75 | 76 | ## Part 3: Key Management 77 | 78 | 1. Update key configuration: 79 | ```bash 80 | # Set minimum decryption version 81 | vault write transit/keys/my-app/config min_decryption_version=1 82 | 83 | # Set minimum encryption version 84 | vault write transit/keys/my-app/config min_encryption_version=1 85 | 86 | # Enable key deletion 87 | vault write transit/keys/my-app/config deletion_allowed=true 88 | ``` 89 | 90 | 2. Create key with specific parameters: 91 | ```bash 92 | vault write transit/keys/my-app-2 \ 93 | type="aes256-gcm96" \ 94 | exportable=false \ 95 | deletion_allowed=true 96 | ``` 97 | 98 | ## Part 4: Data Key Generation 99 | 100 | 1. Generate data key: 101 | ```bash 102 | vault write -f transit/datakey/plaintext/my-app 103 | ``` 104 | 105 | 2. Generate wrapped data key: 106 | ```bash 107 | vault write -f transit/datakey/wrapped/my-app 108 | ``` 109 | 110 | ## Challenge Exercise 111 | 112 | Create an encryption workflow: 113 | 1. Create new encryption key 114 | 2. Encrypt 3 pieces of data 115 | 3. Rotate the key 116 | 4. Encrypt new data 117 | 5. Verify old data still decrypts 118 | 6. List all key versions 119 | 120 | ## Cleanup 121 | ```bash 122 | vault delete transit/keys/my-app 123 | vault delete transit/keys/my-app-2 124 | vault secrets disable transit 125 | ``` 126 | 127 | ## Key Features 128 | - Key rotation 129 | - Configurable key types 130 | - Versioning support 131 | - Data key generation 132 | - Secure key storage -------------------------------------------------------------------------------- /labs/lab_userpass_auth_method.md: -------------------------------------------------------------------------------- 1 | # Vault Authentication Methods Labs 2 | 3 | ## Lab 1: UserPass Authentication 4 | 5 | ### Overview 6 | Configure and test username/password authentication. 7 | 8 | **Time to Complete**: 15-20 minutes 9 | 10 | **Preview Mode**: Use `Cmd/Ctrl + Shift + V` in VSCode to see a nicely formatted version of this lab! 11 | 12 | ## How to Use This Hands-On Lab 13 | 14 | 1. **Create a Codespace** from this repo (click the button below). 15 | 2. Once the Codespace is running, open the integrated terminal. 16 | 3. Follow the instructions in each **lab** to complete the exercises. 17 | 18 | [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/btkrausen/vault-codespaces) 19 | 20 | ## Steps 21 | 22 | 1. Enable the auth method: 23 | ```bash 24 | # Log in with a valid token 25 | vault login root 26 | 27 | # Enable the auth method 28 | vault auth enable userpass 29 | 30 | # Validate that the KV secrets engines are enabled: 31 | vault secrets list 32 | 33 | # Enable KV secrets engine if NOT already enabled: 34 | vault secrets enable -path=secret kv-v2 35 | ``` 36 | 37 | 2. Create users: 38 | ```bash 39 | # Create admin user 40 | vault write auth/userpass/users/admin \ 41 | password="admin123" \ 42 | policies="admin-policy" 43 | 44 | # Create regular user 45 | vault write auth/userpass/users/user1 \ 46 | password="user123" \ 47 | policies="basic-policy" 48 | ``` 49 | 50 | 3. Create basic policies: 51 | ```bash 52 | # Create admin policy 53 | vault policy write admin-policy - < app-policy.hcl << EOF 101 | path "prd-secrets/data/myapp/*" { 102 | capabilities = ["read", "list"] 103 | } 104 | path "prd-secrets/metadata/myapp/*" { 105 | capabilities = ["list", "read"] 106 | } 107 | EOF 108 | 109 | # Write policy to Vault 110 | vault policy write app-reader app-policy.hcl 111 | 112 | # View policy 113 | vault policy read app-reader 114 | 115 | # List all policies 116 | vault policy list 117 | ``` 118 | 119 | ### Part 4: Auth Methods 120 | 121 | 1. **Enable UserPass Auth** 122 | ```bash 123 | # Enable userpass auth method 124 | vault auth enable userpass 125 | 126 | # Create a user 127 | vault write auth/userpass/users/myapp \ 128 | password="password123" \ 129 | policies="app-reader" 130 | 131 | # List users 132 | vault list auth/userpass/users 133 | ``` 134 | 135 | 2. **Login with UserPass** 136 | ```bash 137 | # Login and save token 138 | VAULT_TOKEN=$(vault login -method=userpass \ 139 | username=myapp \ 140 | password=password123 \ 141 | -format=json | jq -r '.auth.client_token') 142 | 143 | # Verify token and permissions 144 | vault token lookup 145 | ``` 146 | 147 | ### Part 5: Advanced Operations 148 | 149 | 1. **Secret Versioning** 150 | ```bash 151 | # Update secret multiple times 152 | vault kv put prd-secrets/myapp/config message="version 1" 153 | vault kv put prd-secrets/myapp/config message="version 2" 154 | vault kv put prd-secrets/myapp/config message="version 3" 155 | 156 | # Soft delete latest version 157 | vault kv delete prd-secrets/myapp/config 158 | 159 | # Undelete version 160 | vault kv undelete -versions=3 prd-secrets/myapp/config 161 | ``` 162 | 163 | 2. **Metadata Operations** 164 | ```bash 165 | # Add custom metadata and set the maximum versions of the secret 166 | vault kv metadata put \ 167 | -max-versions 5 \ 168 | -custom-metadata "environment=development" \ 169 | prd-secrets/myapp/config 170 | 171 | # Read metadata and see versions of secrets 172 | vault kv metadata get prd-secrets/myapp/config 173 | ``` 174 | 175 | ## 🔍 Practice Exercises 176 | 177 | Try these exercises to reinforce your learning: 178 | 179 | 1. **Basic Operations** 180 | - Create a new secret with multiple key-value pairs 181 | - Read specific fields from the secret 182 | - Update only one field using patch 183 | - Delete and undelete the secret 184 | 185 | 2. **Policy Practice** 186 | - Create a policy that allows create and update but not delete 187 | - Create a new user with this policy 188 | - Test the permissions work as expected 189 | 190 | 3. **Advanced Tasks** 191 | - Enable a new secrets engine at a custom path 192 | - Configure custom metadata for a secret 193 | - Work with secret versioning 194 | 195 | ## 🎯 Success Criteria 196 | You've completed the lab when you can: 197 | - [x] Manage secrets using the CLI 198 | - [x] Create and apply policies 199 | - [x] Work with authentication methods 200 | - [x] Handle secret versioning 201 | - [x] Perform metadata operations 202 | 203 | ## 📚 Common CLI Options 204 | - `-format=json`: Output in JSON format 205 | - `-field=key`: Extract specific field 206 | - `-mount=path`: Specify mount path 207 | - `-namespace=ns`: Work in specific namespace (Enterprise) 208 | 209 | ## ❓ Troubleshooting 210 | 211 | **Common Issues:** 212 | 1. **Permission Denied**: Check your token's policies 213 | 2. **Connection Failed**: Verify VAULT_ADDR is set correctly 214 | 3. **Token Expired**: Login again to get a new token 215 | 216 | ## 🔍 Additional CLI Tips 217 | 218 | 1. **Environment Variables** 219 | ```bash 220 | # Common Vault environment variables 221 | export VAULT_ADDR='http://127.0.0.1:8200' 222 | export VAULT_TOKEN='your-token' 223 | export VAULT_NAMESPACE='admin' # Enterprise only 224 | export VAULT_FORMAT='json' # Always output in JSON 225 | ``` 226 | 227 | 2. **Using jq with Vault** 228 | ```bash 229 | # Extract specific fields from JSON output 230 | vault kv get -format=json prd-secrets/myapp/config | jq -r '.data.data.api_key' 231 | 232 | # Process multiple secrets 233 | vault kv list -format=json prd-secrets/myapp/ | jq -r '.data.keys[]' 234 | ``` 235 | 236 | ## 📚 Additional Resources 237 | - [Vault CLI Documentation](https://www.vaultproject.io/docs/commands) 238 | - [Vault Policy Documentation](https://www.vaultproject.io/docs/concepts/policies) 239 | - [Vault Auth Methods](https://www.vaultproject.io/docs/auth) -------------------------------------------------------------------------------- /labs/lab_vault_init_and_unseal.md: -------------------------------------------------------------------------------- 1 | # Hands-on Lab: Vault Initialization and Unsealing 2 | 3 | ## Overview 4 | In this lab, you will learn how to initialize and unseal a Vault server using Shamir's Secret Sharing. You'll create 5 unseal keys with a threshold of 3, meaning any 3 keys are required to unseal Vault. 5 | 6 | **Time Required:** ~20 minutes 7 | 8 | **Preview Mode**: Use `Cmd/Ctrl + Shift + V` in VSCode to see a nicely formatted version of this lab! 9 | 10 | ## How to Use This Hands-On Lab 11 | 12 | 1. **Create a Codespace** from this repo (click the button below). 13 | 2. Once the Codespace is running, open the integrated terminal. 14 | 3. Follow the instructions in each **lab** to complete the exercises. 15 | 16 | [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://github.com/codespaces/new?hide_repo_select=true&ref=main&repo=907851765&skip_quickstart=true&machine=basicLinux32gb&devcontainer_path=.devcontainer%2Frun%2Fdevcontainer.json&geo=UsEast) 17 | 18 | ## Steps 19 | 20 | ### Step 1: Check Vault Status 21 | 22 | 1. Verify Vault's current status: 23 | ```bash 24 | vault status 25 | ``` 26 | 27 | You should see that Vault is not initialized: 28 | ``` 29 | Key Value 30 | --- ----- 31 | Seal Type shamir 32 | Initialized false <--- not yet initialized 33 | Sealed true 34 | ... 35 | ``` 36 | 37 | ### Step 2: Initialize Vault 38 | 39 | 1. Initialize Vault with 5 key shares and a threshold of 3 (_this is the default but practice using the flags_): 40 | ```bash 41 | vault operator init \ 42 | -key-shares=5 \ 43 | -key-threshold=3 44 | ``` 45 | 46 | 2. The output will show: 47 | - 5 unseal keys 48 | - Initial root token 49 | 50 | IMPORTANT: In a production environment, these keys should be distributed to different individuals. Save these keys securely - you'll need them to unseal Vault. 51 | 52 | Example output: 53 | ``` 54 | Unseal Key 1: a4GtR2/Ko... 55 | Unseal Key 2: Jsd9Ksli... 56 | Unseal Key 3: PSYt0dLx... 57 | Unseal Key 4: xhn1Cht9... 58 | Unseal Key 5: 123abcDE... 59 | 60 | Initial Root Token: hvs.UZx... 61 | ``` 62 | 63 | ### Step 3: Unseal Vault 64 | 65 | 1. Unseal Vault using three of the five keys. You'll need to run the unseal command three times, using a different key each time: 66 | 67 | Run the unseal command: 68 | ```bash 69 | vault operator unseal 70 | ``` 71 | When prompted, enter one of the unseal keys (_it doesn't matter which one_). 72 | 73 | Run the unseal command again: 74 | ```bash 75 | vault operator unseal 76 | ``` 77 | When prompted, enter another unseal key (_can be any other key, just don't reuse any keys during this process_). 78 | 79 | Run the unseal command one last time (_because we required a threshold of three_): 80 | ```bash 81 | vault operator unseal 82 | ``` 83 | When prompted, enter the third unseal key. 84 | 85 | 2. Check the status again: 86 | ```bash 87 | vault status 88 | ``` 89 | 90 | You should now see: 91 | ``` 92 | Key Value 93 | --- ----- 94 | Seal Type shamir 95 | Initialized true <--- initialized 96 | Sealed false <--- and now unsealed 97 | ... 98 | ``` 99 | 100 | ### Step 4: Login with Root Token 101 | 102 | 1. Copy the Initial Root Token from the `vault operator init` command and login: 103 | ```bash 104 | vault login # press enter 105 | ``` 106 | When prompted, enter the root token that was generated during initialization. 107 | 108 | 2. Run a command to ensure you can interact with Vault: 109 | ```bash 110 | vault secrets list 111 | ``` 112 | 113 | ## Challenge Exercise 114 | 115 | 1. Seal the vault again: 116 | ```bash 117 | vault operator seal 118 | ``` 119 | 120 | 2. Unseal it using a different combination of three keys than you used before. 121 | 122 | ## Best Practices 123 | 124 | 1. **Key Distribution**: 125 | - Never store all unseal keys in the same place 126 | - Distribute keys to different trusted individuals 127 | - Consider using PGP encryption for key distribution 128 | 129 | 2. **Root Token**: 130 | - Store the initial root token securely 131 | - Create alternate administrative tokens 132 | - Consider revoking the initial root token after setup 133 | 134 | 3. **Unsealing Process**: 135 | - Implement proper procedures for unsealing 136 | - Document the process for authorized individuals 137 | - Consider auto-unseal for production environments 138 | 139 | ## Additional Resources 140 | 141 | - [Vault Initialization Documentation](https://www.vaultproject.io/docs/commands/operator/init) 142 | - [Vault Seal/Unseal Documentation](https://www.vaultproject.io/docs/concepts/seal) 143 | - [Auto-unseal Documentation](https://www.vaultproject.io/docs/configuration/seal) -------------------------------------------------------------------------------- /labs/lab_vault_policies.md: -------------------------------------------------------------------------------- 1 | # Vault Policies Hands-on Lab 2 | 3 | ## Overview 4 | In this lab, you will learn how to create and manage HashiCorp Vault policies. Policies are used to define what actions users and entities can perform within Vault. You'll create different types of policies and test their effectiveness using the Vault CLI. 5 | 6 | **Time to Complete**: 30-45 minutes 7 | 8 | **Preview Mode**: Use `Cmd/Ctrl + Shift + V` in VSCode to see a nicely formatted version of this lab! 9 | 10 | ## How to Use This Hands-On Lab 11 | 12 | 1. **Create a Codespace** from this repo (click the button below). 13 | 2. Once the Codespace is running, open the integrated terminal. 14 | 3. Follow the instructions in each **lab** to complete the exercises. 15 | 16 | [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/btkrausen/vault-codespaces) 17 | 18 | ## Objectives 19 | By completing this lab, you will learn how to: 20 | 1. Create and manage Vault policies 21 | 2. Test policy permissions 22 | 3. Assign policies to tokens 23 | 4. Use policy path templating 24 | 5. Understand policy precedence 25 | 26 | ## Steps 27 | 28 | ### Part 1: Creating Your First Policy 29 | 30 | 1. First, verify that Vault is running and you're authenticated: 31 | ```bash 32 | # Log in with a valid token 33 | vault login root 34 | 35 | # Check the status of the service 36 | vault status 37 | ``` 38 | 39 | 2. Create a new file called `readonly-policy.hcl` in your VS Code editor with these contents: 40 | ```hcl 41 | # Allow read-only access to secrets in the 'secret' path 42 | path "secret/data/*" { 43 | capabilities = ["read", "list"] 44 | } 45 | 46 | path "secret/metadata/*" { 47 | capabilities = ["list"] 48 | } 49 | ``` 50 | 51 | 3. Write this policy to Vault: 52 | ```bash 53 | vault policy write readonly-policy readonly-policy.hcl 54 | ``` 55 | 56 | 4. Verify the policy was created: 57 | ```bash 58 | vault policy list 59 | vault policy read readonly-policy 60 | ``` 61 | 62 | ### Part 2: Testing Policy Restrictions 63 | 64 | 1. Create some test secrets: 65 | ```bash 66 | # Create two test secrets 67 | vault kv put secret/test-1 password="secret123" 68 | vault kv put secret/test-2 api_key="abc123" 69 | ``` 70 | 71 | 2. Create a token with the readonly policy: 72 | ```bash 73 | vault token create -policy=readonly-policy 74 | ``` 75 | 76 | 3. Copy the token value and set it in your environment: 77 | ```bash 78 | export VAULT_TOKEN="" 79 | ``` 80 | 81 | 4. Test the policy restrictions: 82 | ```bash 83 | # These should work 84 | vault kv get secret/test-1 85 | vault kv list secret/ 86 | 87 | # These should fail 88 | vault kv put secret/test-3 password="newpass" 89 | vault kv delete secret/test-1 90 | ``` 91 | 92 | 5. When you're finished, log back in as root: 93 | ```bash 94 | unset VAULT_TOKEN 95 | vault login root 96 | ``` 97 | 98 | ### Part 3: Creating a More Complex Policy with Entity Templating 99 | 100 | 1. Create the Policy 101 | 102 | Create a file called `app-policy.hcl` with the following contents: 103 | 104 | ```hcl 105 | # Allow management of app-specific secrets 106 | path "secret/data/app/{{identity.entity.name}}/*" { 107 | capabilities = ["create", "read", "update", "delete", "list"] 108 | } 109 | 110 | # Allow listing of secret mount 111 | path "secret/metadata/*" { 112 | capabilities = ["list"] 113 | } 114 | ``` 115 | 116 | 2. Then, write the policy: 117 | ```bash 118 | vault policy write app-policy app-policy.hcl 119 | ``` 120 | 121 | 3. Enable and Configure the Userpass Auth Method: 122 | ```bash 123 | vault auth enable userpass 124 | ``` 125 | 126 | 4. Get the Userpass Accessor and set to a variable: 127 | ```bash 128 | USERPASS_ACCESSOR=$(vault auth list -format=json | jq -r '."userpass/".accessor') 129 | ``` 130 | 131 | 5. Create an entity used to map the user to the policy: 132 | ```bash 133 | vault write identity/entity name="app1" policies="app-policy" 134 | ``` 135 | Note the entity ID in the output. 136 | 137 | 6. Create the Entity Alias for the Userpass user: 138 | ```bash 139 | vault write identity/entity-alias \ 140 | name="app1" \ 141 | mount_accessor="$USERPASS_ACCESSOR" \ 142 | canonical_id="" 143 | ``` 144 | Use the entity ID from the previous step in this command. 145 | 146 | 7. Create the Userpass User 147 | ```bash 148 | vault write auth/userpass/users/app1 \ 149 | password="password123" 150 | ``` 151 | 152 | 8. Test Login and Permissions using the Templated Policy: 153 | ```bash 154 | # Login as the user 155 | vault login -method=userpass \ 156 | username=app1 \ 157 | password=password123 158 | 159 | # These should succeed 160 | vault kv put secret/app/app1/config api_key="test123" 161 | vault kv get secret/app/app1/config 162 | 163 | # These should fail with 403 164 | vault kv put secret/app/other-app/config api_key="test123" 165 | vault kv put secret/test-3 password="newpass" 166 | ``` 167 | 168 | 9. When you're finished, log back in as root: 169 | ```bash 170 | unset VAULT_TOKEN 171 | vault login root 172 | ``` 173 | 174 | ### Part 4: Understanding Policy Precedence 175 | 176 | 1. Create a new file called `mixed-policy.hcl`: 177 | ```hcl 178 | # Grant some permissions 179 | path "secret/data/shared/*" { 180 | capabilities = ["create", "read", "update", "list"] 181 | } 182 | 183 | # But deny specific paths 184 | path "secret/data/shared/restricted/*" { 185 | capabilities = ["deny"] 186 | } 187 | ``` 188 | 189 | 2. Write and test the policy: 190 | ```bash 191 | vault policy write mixed-policy mixed-policy.hcl 192 | vault token create -policy=mixed-policy 193 | 194 | # Set your token to the new one 195 | export VAULT_TOKEN="" 196 | 197 | # Test the permissions 198 | vault kv put secret/shared/public data="public-info" # Should work 199 | vault kv put secret/shared/restricted/secret data="sensitive" # Should fail 200 | ``` 201 | 202 | ## Cleanup 203 | 1. Return to your root token: 204 | ```bash 205 | export VAULT_TOKEN="root" 206 | ``` 207 | 208 | 2. Remove the policies and secrets: 209 | ```bash 210 | vault policy delete readonly-policy 211 | vault policy delete app-policy 212 | vault policy delete mixed-policy 213 | vault kv delete secret/test-1 214 | vault kv delete secret/test-2 215 | vault kv delete secret/app/app1/config 216 | vault kv delete secret/shared/public 217 | ``` 218 | 219 | ## Challenge Exercise 220 | Create a policy that: 221 | - Allows read access to all secrets in `secret/data/team-a/*` 222 | - Allows write access only to `secret/data/team-a/projects/*` 223 | - Denies access to `secret/data/team-a/admin/*` 224 | - Allows listing capabilities on all paths 225 | 226 | ## Learning Resources 227 | - [Vault Policies Documentation](https://developer.hashicorp.com/vault/docs/concepts/policies) 228 | - [Policy Syntax Documentation](https://developer.hashicorp.com/vault/docs/concepts/policies#policy-syntax) 229 | - [Policy Templates Documentation](https://developer.hashicorp.com/vault/docs/concepts/policies#policy-templates) 230 | -------------------------------------------------------------------------------- /labs/lab_vault_tokens.md: -------------------------------------------------------------------------------- 1 | # Vault Token Management Lab 2 | 3 | ## Overview 4 | Learn different token types and their management in Vault. 5 | 6 | **Time to Complete**: 25 minutes 7 | 8 | **Preview Mode**: Use `Cmd/Ctrl + Shift + V` in VSCode to see a nicely formatted version of this lab! 9 | 10 | ## How to Use This Hands-On Lab 11 | 12 | 1. **Create a Codespace** from this repo (click the button below). 13 | 2. Once the Codespace is running, open the integrated terminal. 14 | 3. Follow the instructions in each **lab** to complete the exercises. 15 | 16 | [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/btkrausen/vault-codespaces) 17 | 18 | ## Steps 19 | 20 | ## Part 1: Service Tokens 21 | 22 | 1. Create basic service token: 23 | ```bash 24 | # Log in with a valid token 25 | vault login root 26 | 27 | # Create a token 28 | vault token create 29 | ``` 30 | 31 | 2. Create token with policy: 32 | ```bash 33 | vault token create \ 34 | -policy="default" \ 35 | -ttl="1h" \ 36 | -explicit-max-ttl="2h" 37 | ``` 38 | 39 | ## Part 2: Batch Tokens 40 | 41 | 1. Create batch token: 42 | ```bash 43 | vault token create -type=batch \ 44 | -ttl="1h" \ 45 | -policy="default" 46 | ``` 47 | 48 | 2. Compare properties: 49 | ```bash 50 | # Lookup service token 51 | vault token lookup 52 | 53 | # Lookup batch token (notice fewer properties) 54 | vault token lookup 55 | ``` 56 | 57 | ## Part 3: Periodic Tokens 58 | 59 | 1. Create periodic token: 60 | ```bash 61 | vault token create -period="24h" \ 62 | -policy="default" 63 | ``` 64 | 65 | 2. Renew periodic token: 66 | ```bash 67 | vault token renew 68 | ``` 69 | 70 | ## Part 4: Orphan Tokens 71 | 72 | 1. Create orphan token: 73 | ```bash 74 | vault token create -orphan \ 75 | -policy="default" \ 76 | -ttl="1h" 77 | ``` 78 | 79 | 2. View token hierarchy: 80 | ```bash 81 | # Create child of service token 82 | VAULT_TOKEN= vault token create 83 | 84 | # Create orphan - no parent relationship 85 | vault token create -orphan 86 | ``` 87 | 88 | ## Part 5: Token Roles 89 | 90 | 1. Create token role: 91 | ```bash 92 | vault write auth/token/roles/app-role \ 93 | allowed_policies="default" \ 94 | orphan=true \ 95 | token_period="1h" \ 96 | renewable=true 97 | ``` 98 | 99 | 2. Create token from role: 100 | ```bash 101 | vault token create -role=app-role 102 | ``` 103 | 104 | ## Challenge Exercises 105 | 106 | 1. Token Lifecycle: 107 | - Create periodic token 108 | - Renew it multiple times 109 | - Verify period remains constant 110 | 111 | 2. Token Hierarchy: 112 | - Create parent token 113 | - Create child tokens 114 | - Revoke parent 115 | - Check child status 116 | 117 | ## Key Differences 118 | - Service Tokens: Default, renewable 119 | - Batch Tokens: Lightweight, non-renewable 120 | - Periodic Tokens: Auto-renewable indefinitely 121 | - Orphan Tokens: No parent relationship 122 | 123 | ## Cleanup 124 | ```bash 125 | export VAULT_TOKEN="root" 126 | 127 | # Revoke tokens 128 | vault token revoke 129 | 130 | # Remove token role 131 | vault delete auth/token/roles/app-role 132 | ``` -------------------------------------------------------------------------------- /labs/lab_vault_ui.md: -------------------------------------------------------------------------------- 1 | # HashiCorp Vault UI Lab 2 | 3 | ## Overview 4 | Learn how to use the Vault UI to configure and manage HashiCorp Vault 5 | 6 | **Time to Complete**: 25 minutes 7 | 8 | **Preview Mode**: Use `Cmd/Ctrl + Shift + V` in VSCode to see a nicely formatted version of this lab! 9 | 10 | ## How to Use This Hands-On Lab 11 | 12 | 1. **Create a Codespace** from this repo (click the button below). 13 | 2. Once the Codespace is running, open the integrated terminal. 14 | 3. Follow the instructions in each **lab** to complete the exercises. 15 | 16 | [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/btkrausen/vault-codespaces) 17 | 18 | ## Steps 19 | 20 | ## Part 1: Accessing the Vault UI 21 | 22 | 1. After your Codespace starts, click on the "Ports" tab in the bottom panel 23 | 24 | 25 | 26 | 2. You should see port 8200 forwarded 27 | 3. Click on the "Open in Browser" icon (globe) for port 8200 28 | 4. You'll be directed to the Vault UI login page 29 | 5. Log in using the token: `root` 30 | 31 | ## Part 2: Exploring the UI 32 | 33 | 1. **Dashboard Overview** 34 | - Observe the main dashboard components 35 | - Note the status of your Vault instance 36 | - Check the server configuration details 37 | 38 | 2. **Enable a Secrets Engine** 39 | - Click on "Secrets" in the left navigation 40 | - Click "Enable new engine" 41 | - Select "KV" (Key-Value) 42 | - Use path: "kv" 43 | - Choose Version 2 44 | - Click "Enable Engine" 45 | 46 | 3. **Create Secrets** 47 | - Navigate to your new KV secrets engine 48 | - Create a new secret path called "webapp" 49 | - Add the following key-value pairs: 50 | ``` 51 | database_url: "postgresql://localhost:5432/myapp" 52 | api_key: "your-secret-key-123" 53 | ``` 54 | - Save the secret 55 | 56 | 4. **Create a Policy** 57 | - Navigate to "Policies" → "ACL Policies" 58 | - Create a new policy named "webapp-readonly" 59 | - Add the following policy: 60 | ```hcl 61 | path "kv/data/webapp" { 62 | capabilities = ["read"] 63 | } 64 | ``` 65 | 66 | 5. **Enable and Configure Auth Method** 67 | - Go to "Access" → "Auth Methods" 68 | - Enable the "Username & Password" auth method 69 | - Create a new user: 70 | - Username: "webapp-user" 71 | - Password: "password123" 72 | - Assign the "webapp-readonly" policy (expand "Tokens" and add the policy under "Generated Token's Policies) 73 | 74 | ## Part 3: Testing Access 75 | 76 | 1. Log out of the root account 77 | 2. Log back in using the webapp-user credentials 78 | 3. Try to: 79 | - Read the webapp secrets (should succeed) 80 | - Create new secrets (should fail) 81 | - Modify existing secrets (should fail) 82 | 83 | ## 🔍 Exploration Tasks 84 | 85 | Try these additional tasks to deepen your understanding: 86 | 87 | 1. Enable the AWS secrets engine and explore its configuration options 88 | 2. Create a new mount point for another KV secrets engine 89 | 3. Generate and rotate credentials 90 | 4. Explore the built-in help documentation 91 | 92 | ## 🎯 Success Criteria 93 | 94 | You've completed the lab when you can: 95 | - [x] Successfully access the Vault UI 96 | - [x] Create and manage secrets 97 | - [x] Create and apply policies 98 | - [x] Configure authentication 99 | - [x] Understand the different UI sections and their purposes 100 | 101 | ## 📚 Additional Resources 102 | - [Vault Documentation](https://www.vaultproject.io/docs) 103 | - [Vault UI Introduction](https://www.vaultproject.io/docs/configuration/ui) 104 | - [Vault Policies](https://www.vaultproject.io/docs/concepts/policies) 105 | 106 | ## ❓ Troubleshooting 107 | 108 | **Common Issues:** 109 | 1. **Can't access UI**: Ensure port 8200 is properly forwarded in your Codespace 110 | 2. **Login fails**: Verify you're using the correct token or credentials 111 | 3. **Permission denied**: Check the policy assignments and capabilities 112 | 113 | Need help? Open an issue in the repository or contact the lab administrator. 114 | 115 | --- 116 | *Happy Secret Managing! 🔐* 117 | --------------------------------------------------------------------------------