├── .gitignore ├── README.md ├── exercises ├── 01-installing-vault │ ├── instructions.md │ └── solution │ │ ├── imgs │ │ └── vault-ui-signin-token.png │ │ └── solution.md ├── 02-auth-method-manage │ ├── instructions.md │ └── solution │ │ └── solution.md ├── 03-auth-method-use │ ├── instructions.md │ └── solution │ │ ├── imgs │ │ ├── vault-ui-signin-username.png │ │ └── vault-ui-signout.png │ │ └── solution.md ├── 04-policy-manage │ ├── instructions.md │ └── solution │ │ ├── imgs │ │ ├── vault-ui-policies.png │ │ ├── vault-ui-policy-details.png │ │ └── vault-ui-policy-edit.png │ │ └── solution.md ├── 05-policy-assign │ ├── instructions.md │ └── solution │ │ └── solution.md ├── 06-service-batch-token │ ├── instructions.md │ └── solution │ │ └── solution.md ├── 07-secrets-engine-kv-manage │ ├── instructions.md │ └── solution │ │ └── solution.md ├── 08-secrets-engine-kv-use │ ├── instructions.md │ └── solution │ │ └── solution.md ├── 09-secret-engine-aws-lease │ ├── instructions.md │ └── solution │ │ ├── imgs │ │ └── aws-users.png │ │ └── solution.md ├── 10-vault-server-init-unseal │ ├── instructions.md │ └── solution │ │ ├── solution.md │ │ └── vault-server-config.hcl ├── 11-response-wrapping │ ├── instructions.md │ └── solution │ │ └── solution.md └── 12-transit-engine-encryption │ ├── instructions.md │ └── solution │ └── solution.md ├── prerequisites └── instructions.md └── slides.pdf /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Certified Vault Associate (CVA) Crash Course 2 | 3 | As organizations migrate to the cloud, secret management is of the utmost importance. HashiCorp Vault is a tool for storing, controlling, and accessing secrets and sensitive data in a centralized and secure fashion. The multiple-choice Vault Associate certification exam evaluates knowledge of Vault’s architecture, use of the command line and user interface to interact with the Vault server, and creating, configuring, and accessing secrets for real-world scenarios. Successful completion of the exam validates proficiency at the associate level. 4 | 5 | Join expert and [Certified Vault Associate](https://www.credly.com/badges/7e935870-6de7-46e2-8956-78bb2009041e) Benjamin Muschko to walk through all the topics covered in the exam and hear about his personal experience with preparing for all of the exam’s ins and outs. 6 | 7 | ## Prerequisites 8 | 9 | All exercises in this repository practice a self-contained portion of the [CVA curriculum](https://www.hashicorp.com/certification/vault-associate). Please make sure to follow the [instructions](./prerequisites/instructions.md) for setting up your environment before joining the training. 10 | 11 | ## Exercises 12 | 13 | All [exercises](./exercises) are numbered and live in dedicated directories starting with the name `exercise-`. You'll find instructions for each exercise in each folder. Solutions are available in the `solution` folder. Try to solve each exercise yourself before having a look at the solution. 14 | 15 | ## Additional Resources 16 | 17 | * 📚 [LeanPub: HashiCorp Vault Certified Associate Preparation Guide](https://leanpub.com/vault-certified/) 18 | * 🎞️ [Pluralsight: HashiCorp Certified: Vault Associate](https://app.pluralsight.com/paths/certificate/hashicorp-certified-vault-associate) 19 | * 🧪 [Udemy: HashiCorp Certified: Vault Associate - Practice Exam - 2023](https://www.udemy.com/course/hashicorp-certified-vault-associate-practice-exam/) 20 | -------------------------------------------------------------------------------- /exercises/01-installing-vault/instructions.md: -------------------------------------------------------------------------------- 1 | # Exercise 1 2 | 3 | In this exercise, you will install the Vault binary on your machine. Afterward, you will run the command for starting the local development server and interact with it. 4 | 5 | 1. Install the latest Vault binary on your machine. Choose the most fitting [installation method](https://developer.hashicorp.com/vault/tutorials/getting-started/getting-started-install) based on operating system and personal preference. 6 | 2. Run the command `vault version` to determine the version of the executable. 7 | 3. Run the command `vault -help` and explore the output. 8 | 4. Run the command `vault server -dev` to start the development server. 9 | 5. Export the environment variable `VAULT_ADDR` and assign the Vault server address. Export the the environment variable `VAULT_TOKEN` and assign the Vault root token. 10 | 6. Open a browser, navigate to the URL for development server, and log in with the root token. Explore the UI. 11 | 7. Make a `curl` call to the Vault API endpoint `$VAULT_ADDR/v1/sys/host-info`. Use the root token to authenticate. -------------------------------------------------------------------------------- /exercises/01-installing-vault/solution/imgs/vault-ui-signin-token.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bmuschko/cva-crash-course/560fe305686e8f32fe75a02d2468a4ca354132db/exercises/01-installing-vault/solution/imgs/vault-ui-signin-token.png -------------------------------------------------------------------------------- /exercises/01-installing-vault/solution/solution.md: -------------------------------------------------------------------------------- 1 | # Solution 2 | 3 | Follow the instructions on the Vault page to install the binary. Verify that Vault has been installed properly. As shown in the output below, Vault 1.12.1 has been installed. 4 | 5 | ``` 6 | $ vault version 7 | Vault v1.12.1 ('e34f8a14fb7a88af4640b09f3ddbb5646b946d9c+CHANGES'), built 2022-10-27T12:32:05Z 8 | ``` 9 | 10 | The `-help` and `-h` command line options render the usage pattern of the executable. You will get the same output if you just run the `vault` command. 11 | 12 | ``` 13 | $ vault -help 14 | Usage: vault [args] 15 | 16 | Common commands: 17 | read Read data and retrieves secrets 18 | write Write data, configuration, and secrets 19 | delete Delete secrets and configuration 20 | list List data or secrets 21 | login Authenticate locally 22 | agent Start a Vault agent 23 | server Start a Vault server 24 | status Print seal and HA status 25 | unwrap Unwrap a wrapped secret 26 | 27 | Other commands: 28 | audit Interact with audit devices 29 | auth Interact with auth methods 30 | debug Runs the debug command 31 | kv Interact with Vault's Key-Value storage 32 | lease Interact with leases 33 | monitor Stream log messages from a Vault server 34 | namespace Interact with namespaces 35 | operator Perform operator-specific tasks 36 | path-help Retrieve API help for paths 37 | plugin Interact with Vault plugins and catalog 38 | policy Interact with policies 39 | print Prints runtime configurations 40 | secrets Interact with secrets engines 41 | ssh Initiate an SSH session 42 | token Interact with tokens 43 | version-history Prints the version history of the target Vault server 44 | ``` 45 | 46 | Start the local development server with the following command. As you can see in the output, the URL is `http://127.0.0.1:8200`, the root token is `hvs.1dx0yCjCNZFQQOfUljLyRukq`. 47 | 48 | ``` 49 | $ vault server -dev 50 | ... 51 | WARNING! dev mode is enabled! In this mode, Vault runs entirely in-memory 52 | and starts unsealed with a single unseal key. The root token is already 53 | authenticated to the CLI, so you can immediately begin using Vault. 54 | 55 | You may need to set the following environment variables: 56 | 57 | $ export VAULT_ADDR='http://127.0.0.1:8200' 58 | 59 | The unseal key and root token are displayed below in case you want to 60 | seal/unseal the Vault or re-authenticate. 61 | 62 | Unseal Key: 9RTyd8gBLtfUXWG3mp/dl23CWfe1Xe+0/BQ62bSBOk0= 63 | Root Token: hvs.1dx0yCjCNZFQQOfUljLyRukq 64 | 65 | Development mode should NOT be used in production installations! 66 | ``` 67 | 68 | Export the Vault URL and root token as environment variables. 69 | 70 | ``` 71 | $ export VAULT_ADDR='http://127.0.0.1:8200' 72 | $ export VAULT_TOKEN=hvs.1dx0yCjCNZFQQOfUljLyRukq 73 | ``` 74 | 75 | Open a browser and enter the URL [http://127.0.0.1:8200](http://127.0.0.1:8200). That will bring up the Vault UI. Use the "Token" authentication method. Enter the root token value into the field "Token". Pressing the "Sign In" button will successfully log you into Vault. 76 | 77 | ![vault-ui-signin-token](./imgs/vault-ui-signin-token.png) 78 | 79 | You can make a call to the API using the `curl` command. Make sure to set the root token as a header. Use the Vault address that points to the local development server. 80 | 81 | ``` 82 | $ curl -H "X-Vault-Token: $VAULT_TOKEN" -X GET $VAULT_ADDR/v1/sys/host-info 83 | {"request_id":"c96b4c0e-bc38-b638-1864-e1c2e30c1e7e","lease_id":"","renewable":false,"lease_duration":0,"data":{"cpu":[{"cpu":0,"vendorId":"GenuineIntel","family":"6","model":"158","stepping":13,"physicalId":"","coreId":"","cores":8,"modelName":"Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz","mhz":2400,"cacheSize":256,"flags":["fpu","vme","de","pse","tsc","msr","pae","mce","cx8","apic","sep","mtrr","pge","mca","cmov","pat","pse36","clfsh","ds","acpi","mmx","fxsr","sse","sse2","ss","htt","tm","pbe","sse3","pclmulqdq","dtes64","mon","dscpl","vmx","est","tm2","ssse3","fma","cx16","tpr","pdcm","sse4.1","sse4.2","x2apic","movbe","popcnt","aes","pcid","xsave","osxsave","seglim64","tsctmr","avx1.0","rdrand","f16c","rdwrfsgs","tsc_thread_offset","sgx","bmi1","avx2","smep","bmi2","erms","invpcid","fpu_csds","mpx","rdseed","adx","smap","clfsopt","ipt","sgxlc","mdclear","ibrs","stibp","l1df","acapmsr","ssbd","syscall","xd","1gbpage","em64t","lahf","lzcnt","prefetchw","rdtscp","tsci"],"microcode":""}],"disk":[{"path":"/","fstype":"apfs","total":2000796545024,"free":1733629157376,"used":267167387648,"usedPercent":13.353051229144103,"inodesTotal":4292537898,"inodesUsed":502068,"inodesFree":4292035830,"inodesUsedPercent":0.011696297433598105},{"path":"/dev","fstype":"devfs","total":198144,"free":0,"used":198144,"usedPercent":100,"inodesTotal":670,"inodesUsed":670,"inodesFree":0,"inodesUsedPercent":100},{"path":"/System/Volumes/VM","fstype":"apfs","total":2000796545024,"free":1733629157376,"used":267167387648,"usedPercent":13.353051229144103,"inodesTotal":16929972244,"inodesUsed":4,"inodesFree":16929972240,"inodesUsedPercent":2.3626736903940312e-8},{"path":"/System/Volumes/Preboot","fstype":"apfs","total":2000796545024,"free":1733629157376,"used":267167387648,"usedPercent":13.353051229144103,"inodesTotal":16929977412,"inodesUsed":5172,"inodesFree":16929972240,"inodesUsedPercent":0.000030549361491374915},{"path":"/System/Volumes/Update","fstype":"apfs","total":2000796545024,"free":1733629157376,"used":267167387648,"usedPercent":13.353051229144103,"inodesTotal":16929972258,"inodesUsed":18,"inodesFree":16929972240,"inodesUsedPercent":1.0632031597981134e-7},{"path":"/System/Volumes/Data","fstype":"apfs","total":2000796545024,"free":1733629157376,"used":267167387648,"usedPercent":13.353051229144103,"inodesTotal":16932256587,"inodesUsed":2284347,"inodesFree":16929972240,"inodesUsedPercent":0.013491096052453177},{"path":"/System/Volumes/Data/home","fstype":"autofs","total":0,"free":0,"used":0,"usedPercent":0,"inodesTotal":0,"inodesUsed":0,"inodesFree":0,"inodesUsedPercent":0}],"host":{"hostname":"ascent.local","uptime":3015847,"bootTime":1666636149,"procs":690,"os":"darwin","platform":"darwin","platformFamily":"Standalone Workstation","platformVersion":"12.6","kernelVersion":"21.6.0","kernelArch":"x86_64","virtualizationSystem":"","virtualizationRole":"","hostid":"07d34ca1-6e03-5efb-ad0a-36e490827daa"},"memory":{"total":68719476736,"available":40838901760,"used":27880574976,"usedPercent":40.57157635688782,"free":23292813312,"active":16516403200,"inactive":17546088448,"wired":5833060352,"laundry":0,"buffers":0,"cached":0,"writeback":0,"dirty":0,"writebacktmp":0,"shared":0,"slab":0,"sreclaimable":0,"sunreclaim":0,"pagetables":0,"swapcached":0,"commitlimit":0,"committedas":0,"hightotal":0,"highfree":0,"lowtotal":0,"lowfree":0,"swaptotal":0,"swapfree":0,"mapped":0,"vmalloctotal":0,"vmallocused":0,"vmallocchunk":0,"hugepagestotal":0,"hugepagesfree":0,"hugepagesize":0},"timestamp":"2022-11-28T16:13:16.64764Z"},"wrap_info":null,"warnings":["cpu_times: not implemented yet"],"auth":null} 84 | ``` 85 | 86 | Congratulations! You are ready to use the Vault in the next exercises. 87 | -------------------------------------------------------------------------------- /exercises/02-auth-method-manage/instructions.md: -------------------------------------------------------------------------------- 1 | # Exercise 2 2 | 3 | In this exercise, you will two authentication methods, an Userpass, and an AppRole. Feel free to use the CLI or the UI to achieve the goal. 4 | 5 | 1. Log into Vault with the root token. 6 | 2. List the existing authentication methods. Which authentication method should you see listed? 7 | 3. Enable an Userpass authentication method. Do not specify any custom configuration. 8 | 4. Enable an AppRole authentication method on the path `global` with a max lease TTL of 30 mins. 9 | 5. List the existing authentication methods. Identify the authentication methods you created. 10 | 6. Tune the Userpass and AppRole authentication method you created. Provide a description for both. You can pick any description you'd like. 11 | 7. Create the user `johndoe` with the password `pwd` for the Userpass authentication method. 12 | 8. Create the AppRole `servicebot`. Provide the role name `ci`. -------------------------------------------------------------------------------- /exercises/02-auth-method-manage/solution/solution.md: -------------------------------------------------------------------------------- 1 | # Solution 2 | 3 | Log in with the root token. You can simply use the environment variables we set in an earlier exercise or provide the plain-text values with the `login` command. 4 | 5 | ``` 6 | $ vault login -address=$VAULT_ADDR $VAULT_TOKEN 7 | WARNING! The VAULT_TOKEN environment variable is set! The value of this 8 | variable will take precedence; if this is unwanted please unset VAULT_TOKEN or 9 | update its value accordingly. 10 | 11 | Success! You are now authenticated. The token information displayed below 12 | is already stored in the token helper. You do NOT need to run "vault login" 13 | again. Future Vault requests will automatically use this token. 14 | 15 | Key Value 16 | --- ----- 17 | token hvs.1dx0yCjCNZFQQOfUljLyRukq 18 | token_accessor 6UqLKI9h3mCIWZrUkRFj2s2Z 19 | token_duration ∞ 20 | token_renewable false 21 | token_policies ["root"] 22 | identity_policies [] 23 | policies ["root"] 24 | ``` 25 | 26 | Initially, you start out with a single authentication method. That is the root token. You can list the authentication method with the following command. 27 | 28 | ``` 29 | $ vault auth list 30 | Path Type Accessor Description Version 31 | ---- ---- -------- ----------- ------- 32 | token/ token auth_token_4e0f2b43 token based credentials n/a 33 | ``` 34 | 35 | Enable the Userpass and AppRole authentication methods. The first command uses the default configuration for the Userpass authentication method. Custom configuration, such as the path and max lease TTL, has been provided for the AppRole authentication method. 36 | 37 | ``` 38 | $ vault auth enable userpass 39 | Success! Enabled userpass auth method at: userpass 40 | $ vault auth enable -path=global -max-lease-ttl=30m approle 41 | Success! Enabled approle auth method at: global/ 42 | ``` 43 | 44 | The newly-created authentication methods will be listed when running the `auth list` command. At this time, the Userpass and AppRole authentication methods do not render a description. 45 | 46 | ``` 47 | $ vault auth list 48 | Path Type Accessor Description Version 49 | ---- ---- -------- ----------- ------- 50 | global/ approle auth_approle_df462445 n/a n/a 51 | token/ token auth_token_4e0f2b43 token based credentials n/a 52 | userpass/ userpass auth_userpass_ab2f32b6 n/a n/a 53 | ``` 54 | 55 | You can add a description for both authentication methods by tuning them. Refer to the authentication method by path when running the `auth tune` command. 56 | 57 | ``` 58 | $ vault auth tune -description="Username and password" userpass/ 59 | Success! Tuned the auth method at: userpass/ 60 | $ vault auth tune -description="Role-based credentials" global/ 61 | Success! Tuned the auth method at: global/ 62 | ``` 63 | 64 | The tuned authentication method now show the provided description. 65 | 66 | ``` 67 | $ vault auth list 68 | Path Type Accessor Description Version 69 | ---- ---- -------- ----------- ------- 70 | global/ approle auth_approle_df462445 Role-based credentials n/a 71 | token/ token auth_token_4e0f2b43 token based credentials n/a 72 | userpass/ userpass auth_userpass_ab2f32b6 Username and password n/a 73 | ``` 74 | 75 | Use the `write` command and the corresponding path to create a user and a named AppRole. 76 | 77 | ``` 78 | $ vault write auth/userpass/users/johndoe password=pwd 79 | Success! Data written to: auth/userpass/users/johndoe 80 | $ vault write auth/global/role/servicebot role_name="ci" 81 | Success! Data written to: auth/global/role/servicebot 82 | ``` 83 | 84 | To verify the entries, check them by running the `list` command for the corresponding paths. 85 | 86 | ``` 87 | $ vault list auth/userpass/users 88 | Keys 89 | ---- 90 | johndoe 91 | $ vault list auth/global/role 92 | Keys 93 | ---- 94 | servicebot 95 | ``` -------------------------------------------------------------------------------- /exercises/03-auth-method-use/instructions.md: -------------------------------------------------------------------------------- 1 | # Exercise 3 2 | 3 | In this exercise, you will use a user and named AppRole to sign in with Vault through the API and UI and then to make a call to the API. Finally, you will disable the Userpass and AppRole authentication methods. 4 | 5 | 1. Sign into Vault with the CLI. Authenticate with the user `johndoe`. This user has been created in the previous exercise. 6 | 2. Use the client token of the user to make a `curl` call to the endpoint `$VAULT_ADDR/v1/secret?help=1`. 7 | 3. Sign out of the Vault UI. 8 | 4. From the CLI, sign back in with the root token. 9 | 5. Retrieve the role ID and secret ID for the named AppRole `global`. 10 | 6. Generate a token by providing the role ID and secret ID. 11 | 7. Use the client token of the AppRole to make a `curl` call to the endpoint `$VAULT_ADDR/v1/secret?help=1`. 12 | 8. Disable both authentication methods. -------------------------------------------------------------------------------- /exercises/03-auth-method-use/solution/imgs/vault-ui-signin-username.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bmuschko/cva-crash-course/560fe305686e8f32fe75a02d2468a4ca354132db/exercises/03-auth-method-use/solution/imgs/vault-ui-signin-username.png -------------------------------------------------------------------------------- /exercises/03-auth-method-use/solution/imgs/vault-ui-signout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bmuschko/cva-crash-course/560fe305686e8f32fe75a02d2468a4ca354132db/exercises/03-auth-method-use/solution/imgs/vault-ui-signout.png -------------------------------------------------------------------------------- /exercises/03-auth-method-use/solution/solution.md: -------------------------------------------------------------------------------- 1 | # Solution 2 | 3 | Use the `login` command to log in with the authentication method of type Userpass. Here, we are setting the `userpass` method and provide the `username` parameter for the user `johndoe`. Enter the password you used in the previous exercise when creating the user. The command will return a client token you can use for calls to the API. 4 | 5 | ``` 6 | $ vault login -method=userpass username=johndoe 7 | Password (will be hidden): 8 | WARNING! The VAULT_TOKEN environment variable is set! The value of this 9 | variable will take precedence; if this is unwanted please unset VAULT_TOKEN or 10 | update its value accordingly. 11 | 12 | Success! You are now authenticated. The token information displayed below 13 | is already stored in the token helper. You do NOT need to run "vault login" 14 | again. Future Vault requests will automatically use this token. 15 | 16 | Key Value 17 | --- ----- 18 | token hvs.CAESIPz3LATfaO-jqmfcpK2yn2dI9r31MDID7CMTtaaePbf0Gh4KHGh2cy5ZU2plVzhmQVRIUDRpSFUzQjFtdEpGb24 19 | token_accessor HUguw48LAa5Bjmh8z6N0VXGw 20 | token_duration 768h 21 | token_renewable true 22 | token_policies ["default"] 23 | identity_policies [] 24 | policies ["default"] 25 | token_meta_username johndoe 26 | ``` 27 | 28 | The client token for the Userpass authentication method is `hvs.CAESIPz3LATfaO-jqmfcpK2yn2dI9r31MDID7CMTtaaePbf0Gh4KHGh2cy5ZU2plVzhmQVRIUDRpSFUzQjFtdEpGb24`. Provide the token in the header of a `curl` command. The response body provides information about a key-value store backend. 29 | 30 | ``` 31 | $ curl -H "X-Vault-Token: hvs.CAESIPz3LATfaO-jqmfcpK2yn2dI9r31MDID7CMTtaaePbf0Gh4KHGh2cy5ZU2plVzhmQVRIUDRpSFUzQjFtdEpGb24" $VAULT_ADDR/v1/secret\?help\=1 32 | ... 33 | ``` 34 | 35 | You can sign in with either the "Username" method or the generated token for the Userpass authentication method. The screenshot below shows the sign in shows the usage of the "Username" method. 36 | 37 | ![vault-ui-signin-username](./imgs/vault-ui-signin-username.png) 38 | 39 | You can find the sign out option in the drop down menu in the top-right corner. Select "Sign out". You will be redirected to the sign in screen. 40 | 41 | ![vault-ui-signout](./imgs/vault-ui-signout.png) 42 | 43 | Run the `login` command with the root token to sign back in. 44 | 45 | ``` 46 | $ vault login -address=$VAULT_ADDR $VAULT_TOKEN 47 | WARNING! The VAULT_TOKEN environment variable is set! The value of this 48 | variable will take precedence; if this is unwanted please unset VAULT_TOKEN or 49 | update its value accordingly. 50 | 51 | Success! You are now authenticated. The token information displayed below 52 | is already stored in the token helper. You do NOT need to run "vault login" 53 | again. Future Vault requests will automatically use this token. 54 | 55 | Key Value 56 | --- ----- 57 | token hvs.1dx0yCjCNZFQQOfUljLyRukq 58 | token_accessor 6UqLKI9h3mCIWZrUkRFj2s2Z 59 | token_duration ∞ 60 | token_renewable false 61 | token_policies ["root"] 62 | identity_policies [] 63 | policies ["root"] 64 | ``` 65 | 66 | There are two calls you need to make from the CLI to retrieve the role ID and secret ID for the named AppRole `global`. The first call returns the role ID, the second call generates a secret ID. 67 | 68 | ``` 69 | $ vault read auth/global/role/servicebot/role-id 70 | Key Value 71 | --- ----- 72 | role_id 6202f935-b1e3-f2cc-0e6f-b0b42233ae84 73 | $ vault write -force auth/global/role/servicebot/secret-id 74 | Key Value 75 | --- ----- 76 | secret_id aeece79d-a75a-7230-3720-d7c71d0c3281 77 | secret_id_accessor e1901819-4f30-54d2-0d94-cc9b84154f4b 78 | secret_id_num_uses 0 79 | secret_id_ttl 0s 80 | ``` 81 | 82 | You can now log in with the role ID and secret ID. The call will provide you with the client token. 83 | 84 | ``` 85 | $ vault write auth/global/login role_id=6202f935-b1e3-f2cc-0e6f-b0b42233ae84 secret_id=aeece79d-a75a-7230-3720-d7c71d0c3281 86 | WARNING! The following warnings were returned from Vault: 87 | 88 | * TTL of "768h" exceeded the effective max_ttl of "30m"; TTL value is capped 89 | accordingly 90 | 91 | Key Value 92 | --- ----- 93 | token hvs.CAESIAy6eh7Oe6I4p5U-8jGhjsublDl-xM-wnvnD-hsg8mjwGh4KHGh2cy54R0xQVVR0d0VUSVpFTkVDRUhSQUs3R1Q 94 | token_accessor AMqtjjMZueHfb2g3HFvmlvC3 95 | token_duration 30m 96 | token_renewable true 97 | token_policies ["default"] 98 | identity_policies [] 99 | policies ["default"] 100 | token_meta_role_name servicebot 101 | ``` 102 | 103 | We can use the client token to make a call to the API endpoint. This token will be valid for 30 minutes. 104 | 105 | ``` 106 | $ curl -H "X-Vault-Token: hvs.CAESIAy6eh7Oe6I4p5U-8jGhjsublDl-xM-wnvnD-hsg8mjwGh4KHGh2cy54R0xQVVR0d0VUSVpFTkVDRUhSQUs3R1Q" $VAULT_ADDR/v1/secret\?help\=1 107 | ... 108 | ``` 109 | 110 | Disable both authentication methods with the `disable` command. 111 | 112 | ``` 113 | $ vault auth disable userpass/ 114 | Success! Disabled the auth method (if it existed) at: userpass/ 115 | $ vault auth disable global/ 116 | Success! Disabled the auth method (if it existed) at: global/ 117 | ``` 118 | 119 | We are back to the initial state of available authentication methods. Only the token authentication method is enabled. 120 | 121 | ``` 122 | $ vault auth list 123 | Path Type Accessor Description Version 124 | ---- ---- -------- ----------- ------- 125 | token/ token auth_token_4e0f2b43 token based credentials n/a 126 | ``` 127 | -------------------------------------------------------------------------------- /exercises/04-policy-manage/instructions.md: -------------------------------------------------------------------------------- 1 | # Exercise 4 2 | 3 | In this exercise, you will manage a policy without assigning it yet. You will define and format the contents of a policy file, and then create the policy in Vault. As part of the exercise, you will also list available policies and update the rules of an existing policy from the CLI and UI. 4 | 5 | 1. Log in with the root token. 6 | 2. List the current policies available. 7 | 3. Create a policy file named `mounts-list.hcl`. Define a rule for the path `sys/mounts` with the capability `read`. 8 | 4. Ensure that the format of the policy file follows the official style conventions. 9 | 5. Create the policy with the name `mounts-list`. 10 | 6. List all available policies. You should see the new policy. Render the details of the policy. 11 | 7. Sign into the Vault UI with the root token. Find the policy and inspect its details. 12 | 8. Update the policy by defining another rule. For the path `sys/mounts/*` add the capabilities `read`, `list`, and `sudo`. Add the new rule _before_ the existing rule. -------------------------------------------------------------------------------- /exercises/04-policy-manage/solution/imgs/vault-ui-policies.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bmuschko/cva-crash-course/560fe305686e8f32fe75a02d2468a4ca354132db/exercises/04-policy-manage/solution/imgs/vault-ui-policies.png -------------------------------------------------------------------------------- /exercises/04-policy-manage/solution/imgs/vault-ui-policy-details.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bmuschko/cva-crash-course/560fe305686e8f32fe75a02d2468a4ca354132db/exercises/04-policy-manage/solution/imgs/vault-ui-policy-details.png -------------------------------------------------------------------------------- /exercises/04-policy-manage/solution/imgs/vault-ui-policy-edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bmuschko/cva-crash-course/560fe305686e8f32fe75a02d2468a4ca354132db/exercises/04-policy-manage/solution/imgs/vault-ui-policy-edit.png -------------------------------------------------------------------------------- /exercises/04-policy-manage/solution/solution.md: -------------------------------------------------------------------------------- 1 | # Solution 2 | 3 | Run the `login` command with the root token to sign in. 4 | 5 | ``` 6 | $ vault login -address=$VAULT_ADDR $VAULT_TOKEN 7 | WARNING! The VAULT_TOKEN environment variable is set! The value of this 8 | variable will take precedence; if this is unwanted please unset VAULT_TOKEN or 9 | update its value accordingly. 10 | 11 | Success! You are now authenticated. The token information displayed below 12 | is already stored in the token helper. You do NOT need to run "vault login" 13 | again. Future Vault requests will automatically use this token. 14 | 15 | Key Value 16 | --- ----- 17 | token hvs.1dx0yCjCNZFQQOfUljLyRukq 18 | token_accessor 6UqLKI9h3mCIWZrUkRFj2s2Z 19 | token_duration ∞ 20 | token_renewable false 21 | token_policies ["root"] 22 | identity_policies [] 23 | policies ["root"] 24 | ``` 25 | 26 | List the current policies shows the `default` and `root` policy. 27 | 28 | ``` 29 | $ vault policy list 30 | default 31 | root 32 | ``` 33 | 34 | Create the policy file named `mounts-list.hcl` and add the following contents. 35 | 36 | ```hcl 37 | path "sys/mounts" { 38 | capabilities = ["read"] 39 | } 40 | ``` 41 | 42 | Before creating a policy from the HCL file, format its contents to follow the style conventions. Use the `policy fmt` command to achieve the automatic formatting of the file. 43 | 44 | ``` 45 | $ vault policy fmt mounts-list.hcl 46 | Success! Formatted policy: mounts-list.hcl 47 | ``` 48 | 49 | Create the policy using the `policy write` command and point to the HCL file. 50 | 51 | ``` 52 | $ vault policy write mounts-list mounts-list.hcl 53 | Success! Uploaded policy: mounts-list 54 | ``` 55 | 56 | List the policies again. The new policy will be rendered as part of the policy list. 57 | 58 | ``` 59 | $ vault policy list 60 | default 61 | mounts-list 62 | root 63 | ``` 64 | 65 | At any time, you can have a look at the rules of a policy with the `policy read` command. The output of the command will simply render the contents of the uploaded HCL file. 66 | 67 | ``` 68 | $ vault policy read mounts-list 69 | path "sys/mounts" { 70 | capabilities = ["read"] 71 | } 72 | ``` 73 | 74 | You can find the list of policies under the menu item "Policies". 75 | 76 | ![vault-ui-policies](./imgs/vault-ui-policies.png) 77 | 78 | For details, simply click on the policy name. You will see the contents of the uploaded policy file. 79 | 80 | ![vault-ui-policy-details](./imgs/vault-ui-policy-details.png) 81 | 82 | You can directly edit the policy from the UI. Click the option "Edit policy". Press the "Save" button to let the changes take effect. 83 | 84 | ![vault-ui-policy-edit](./imgs/vault-ui-policy-edit.png) 85 | 86 | Alternatively, you can also update the policy from the CLI. First, you need to modify the policy file with the following contents: 87 | 88 | ```hcl 89 | path "sys/mounts/*" { 90 | capabilities = ["read", "list", "sudo"] 91 | } 92 | 93 | path "sys/mounts" { 94 | capabilities = ["read"] 95 | } 96 | ``` 97 | 98 | Then use the `policy write` command to apply the changes. 99 | 100 | ``` 101 | $ vault policy write mounts-list mounts-list.hcl 102 | Success! Uploaded policy: mounts-list 103 | ``` -------------------------------------------------------------------------------- /exercises/05-policy-assign/instructions.md: -------------------------------------------------------------------------------- 1 | # Exercise 5 2 | 3 | In this exercise, you will assign the policy to a user created with the Userpass authentication method. Logged in as the user, you will make a call to the API path we allowed it to call. 4 | 5 | > **_NOTE:_** You can find more information about the `sys/mounts` endpoint in the [API documentation](https://developer.hashicorp.com/vault/api-docs/system/mounts). 6 | 7 | 1. Log in with the root token. 8 | 2. Enable the Userpass authentication method and create a user `jill`. Assign the password `123`. 9 | 3. Log in with the user `jill`. 10 | 4. Make an API call to the endpoint `sys/mounts`. What's the response you see? 11 | 5. Log in with the root token. 12 | 6. Assign the policy `mounts-list` created in the last exercise to the user `jill`. 13 | 7. Log in with the user `jill`. 14 | 8. Make an API call to the endpoint `sys/mounts`. Does the API call succeed? 15 | 9. Delete the policy `mounts-list`. 16 | 10. Make another API call to the endpoint `sys/mounts`. The call should fail. -------------------------------------------------------------------------------- /exercises/05-policy-assign/solution/solution.md: -------------------------------------------------------------------------------- 1 | # Solution 2 | 3 | Run the `login` command with the root token to sign in. 4 | 5 | ``` 6 | $ vault login -address=$VAULT_ADDR $VAULT_TOKEN 7 | WARNING! The VAULT_TOKEN environment variable is set! The value of this 8 | variable will take precedence; if this is unwanted please unset VAULT_TOKEN or 9 | update its value accordingly. 10 | 11 | Success! You are now authenticated. The token information displayed below 12 | is already stored in the token helper. You do NOT need to run "vault login" 13 | again. Future Vault requests will automatically use this token. 14 | 15 | Key Value 16 | --- ----- 17 | token hvs.1dx0yCjCNZFQQOfUljLyRukq 18 | token_accessor 6UqLKI9h3mCIWZrUkRFj2s2Z 19 | token_duration ∞ 20 | token_renewable false 21 | token_policies ["root"] 22 | identity_policies [] 23 | policies ["root"] 24 | ``` 25 | 26 | Enable the Userpass authentication methods and add the user named `jill`. 27 | 28 | ``` 29 | $ vault auth enable userpass 30 | Success! Enabled userpass auth method at: userpass/ 31 | $ vault write auth/userpass/users/jill password=123 32 | Success! Data written to: auth/userpass/users/jill 33 | ``` 34 | 35 | Log in with the user `jill`. 36 | 37 | ``` 38 | $ vault login -method=userpass username=jill 39 | Password (will be hidden): 40 | WARNING! The VAULT_TOKEN environment variable is set! The value of this 41 | variable will take precedence; if this is unwanted please unset VAULT_TOKEN or 42 | update its value accordingly. 43 | 44 | Success! You are now authenticated. The token information displayed below 45 | is already stored in the token helper. You do NOT need to run "vault login" 46 | again. Future Vault requests will automatically use this token. 47 | 48 | Key Value 49 | --- ----- 50 | token hvs.CAESIDkislQE4FQ_WAvfEMAB3NjmGNmYo4MmyJw1IJ-b1ZjkGh4KHGh2cy5sNmU3SE5KN20wMzdwbDh0aU90eUp3a0g 51 | token_accessor 7vsdQFhfc3Ol0aGZbbzcjZl8 52 | token_duration 768h 53 | token_renewable true 54 | token_policies ["default"] 55 | identity_policies [] 56 | policies ["default"] 57 | token_meta_username jill 58 | ``` 59 | 60 | Make an API call to the endpoint `sys/mounts`. The endpoint lists all the mounted secrets engines. The user `jill` does not have the read permissions for this endpoint. 61 | 62 | ``` 63 | $ curl -H "X-Vault-Token: hvs.CAESIDkislQE4FQ_WAvfEMAB3NjmGNmYo4MmyJw1IJ-b1ZjkGh4KHGh2cy5sNmU3SE5KN20wMzdwbDh0aU90eUp3a0g" $VAULT_ADDR/v1/sys/mounts 64 | {"errors":["1 error occurred:\n\t* permission denied\n\n"]} 65 | ``` 66 | 67 | Switch back to the using the root token. 68 | 69 | ``` 70 | $ vault login -address=$VAULT_ADDR $VAULT_TOKEN 71 | WARNING! The VAULT_TOKEN environment variable is set! The value of this 72 | variable will take precedence; if this is unwanted please unset VAULT_TOKEN or 73 | update its value accordingly. 74 | 75 | Success! You are now authenticated. The token information displayed below 76 | is already stored in the token helper. You do NOT need to run "vault login" 77 | again. Future Vault requests will automatically use this token. 78 | 79 | Key Value 80 | --- ----- 81 | token hvs.1dx0yCjCNZFQQOfUljLyRukq 82 | token_accessor 6UqLKI9h3mCIWZrUkRFj2s2Z 83 | token_duration ∞ 84 | token_renewable false 85 | token_policies ["root"] 86 | identity_policies [] 87 | policies ["root"] 88 | ``` 89 | 90 | Assign the policy to the user. 91 | 92 | ``` 93 | $ vault write auth/userpass/users/jill token_policies="mounts-list" 94 | Success! Data written to: auth/userpass/users/jill 95 | ``` 96 | 97 | When logging back in with the user `jill`, you will see that the list of policies now contains `mounts-list`. 98 | 99 | ``` 100 | $ vault login -method=userpass username=jill 101 | Password (will be hidden): 102 | WARNING! The VAULT_TOKEN environment variable is set! The value of this 103 | variable will take precedence; if this is unwanted please unset VAULT_TOKEN or 104 | update its value accordingly. 105 | 106 | Success! You are now authenticated. The token information displayed below 107 | is already stored in the token helper. You do NOT need to run "vault login" 108 | again. Future Vault requests will automatically use this token. 109 | 110 | Key Value 111 | --- ----- 112 | token hvs.CAESIMaHUkthWF-6oG-6TgeINxojiU_VhOGUn8uaHY0SiOZgGh4KHGh2cy55alhIZmFYNGFUOWFKdEl3VWtOSUs2OEU 113 | token_accessor w40weSfaqcxtqQ94TvX2oL7i 114 | token_duration 768h 115 | token_renewable true 116 | token_policies ["default" "mounts-list"] 117 | identity_policies [] 118 | policies ["default" "mounts-list"] 119 | token_meta_username jill 120 | ``` 121 | 122 | Make an API call to the endpoint `sys/mounts`. The user is now allowed to run the operation. 123 | 124 | ``` 125 | $ curl -H "X-Vault-Token: hvs.CAESIMaHUkthWF-6oG-6TgeINxojiU_VhOGUn8uaHY0SiOZgGh4KHGh2cy55alhIZmFYNGFUOWFKdEl3VWtOSUs2OEU" $VAULT_ADDR/v1/sys/mounts 126 | {"sys/":{"accessor":"system_47c5e1dd","config":{"default_lease_ttl":0,"force_no_cache":false,"max_lease_ttl":0,"passthrough_request_headers":["Accept"]},"description":"system endpoints used for control, policy and debugging","external_entropy_access":false,"local":false,"options":null,"plugin_version":"","running_plugin_version":"v1.12.1+builtin.vault","running_sha256":"","seal_wrap":true,"type":"system","uuid":"2b70709f-b1d5-c0c1-a9cb-86caf7c12720"},"identity/":{"accessor":"identity_3b6c23eb","config":{"default_lease_ttl":0,"force_no_cache":false,"max_lease_ttl":0,"passthrough_request_headers":["Authorization"]},"description":"identity store","external_entropy_access":false,"local":false,"options":null,"plugin_version":"","running_plugin_version":"v1.12.1+builtin.vault","running_sha256":"","seal_wrap":false,"type":"identity","uuid":"9936e20d-7ef5-32dd-7dc7-41127e06b7c8"},"cubbyhole/":{"accessor":"cubbyhole_e03aff1a","config":{"default_lease_ttl":0,"force_no_cache":false,"max_lease_ttl":0},"description":"per-token private secret storage","external_entropy_access":false,"local":true,"options":null,"plugin_version":"","running_plugin_version":"v1.12.1+builtin.vault","running_sha256":"","seal_wrap":false,"type":"cubbyhole","uuid":"3362a1bd-15e6-e683-6428-b9678b8a46f8"},"secret/":{"accessor":"kv_d0adb6b0","config":{"default_lease_ttl":0,"force_no_cache":false,"max_lease_ttl":0},"deprecation_status":"supported","description":"key/value secret storage","external_entropy_access":false,"local":false,"options":{"version":"2"},"plugin_version":"","running_plugin_version":"v0.13.0+builtin","running_sha256":"","seal_wrap":false,"type":"kv","uuid":"9cf3e8fc-ca46-deff-0384-d2ef08d5b88b"},"request_id":"d73a81a9-58cd-b7fa-62e6-9e0a0cb05361","lease_id":"","renewable":false,"lease_duration":0,"data":{"cubbyhole/":{"accessor":"cubbyhole_e03aff1a","config":{"default_lease_ttl":0,"force_no_cache":false,"max_lease_ttl":0},"description":"per-token private secret storage","external_entropy_access":false,"local":true,"options":null,"plugin_version":"","running_plugin_version":"v1.12.1+builtin.vault","running_sha256":"","seal_wrap":false,"type":"cubbyhole","uuid":"3362a1bd-15e6-e683-6428-b9678b8a46f8"},"identity/":{"accessor":"identity_3b6c23eb","config":{"default_lease_ttl":0,"force_no_cache":false,"max_lease_ttl":0,"passthrough_request_headers":["Authorization"]},"description":"identity store","external_entropy_access":false,"local":false,"options":null,"plugin_version":"","running_plugin_version":"v1.12.1+builtin.vault","running_sha256":"","seal_wrap":false,"type":"identity","uuid":"9936e20d-7ef5-32dd-7dc7-41127e06b7c8"},"secret/":{"accessor":"kv_d0adb6b0","config":{"default_lease_ttl":0,"force_no_cache":false,"max_lease_ttl":0},"deprecation_status":"supported","description":"key/value secret storage","external_entropy_access":false,"local":false,"options":{"version":"2"},"plugin_version":"","running_plugin_version":"v0.13.0+builtin","running_sha256":"","seal_wrap":false,"type":"kv","uuid":"9cf3e8fc-ca46-deff-0384-d2ef08d5b88b"},"sys/":{"accessor":"system_47c5e1dd","config":{"default_lease_ttl":0,"force_no_cache":false,"max_lease_ttl":0,"passthrough_request_headers":["Accept"]},"description":"system endpoints used for control, policy and debugging","external_entropy_access":false,"local":false,"options":null,"plugin_version":"","running_plugin_version":"v1.12.1+builtin.vault","running_sha256":"","seal_wrap":true,"type":"system","uuid":"2b70709f-b1d5-c0c1-a9cb-86caf7c12720"}},"wrap_info":null,"warnings":null,"auth":null} 127 | ``` 128 | 129 | Individual secret engines can be queried for by path. The following path is `secret`. 130 | 131 | ``` 132 | $ curl -H "X-Vault-Token: hvs.CAESIMaHUkthWF-6oG-6TgeINxojiU_VhOGUn8uaHY0SiOZgGh4KHGh2cy55alhIZmFYNGFUOWFKdEl3VWtOSUs2OEU" $VAULT_ADDR/v1/sys/mounts/secret 133 | {"running_sha256":"","type":"kv","description":"key/value secret storage","local":false,"seal_wrap":false,"external_entropy_access":false,"options":{"version":"2"},"running_plugin_version":"v0.13.0+builtin","config":{"default_lease_ttl":0,"force_no_cache":false,"max_lease_ttl":0},"accessor":"kv_d0adb6b0","uuid":"9cf3e8fc-ca46-deff-0384-d2ef08d5b88b","plugin_version":"","deprecation_status":"supported","request_id":"cedb69a2-aaef-00a9-4d68-08edc57999d2","lease_id":"","renewable":false,"lease_duration":0,"data":{"accessor":"kv_d0adb6b0","config":{"default_lease_ttl":0,"force_no_cache":false,"max_lease_ttl":0},"deprecation_status":"supported","description":"key/value secret storage","external_entropy_access":false,"local":false,"options":{"version":"2"},"plugin_version":"","running_plugin_version":"v0.13.0+builtin","running_sha256":"","seal_wrap":false,"type":"kv","uuid":"9cf3e8fc-ca46-deff-0384-d2ef08d5b88b"},"wrap_info":null,"warnings":null,"auth":null} 134 | ``` 135 | 136 | Delete the policy with the `policy delete` command. 137 | 138 | ``` 139 | $ vault policy delete mounts-list 140 | Success! Deleted policy: mounts-list 141 | ``` 142 | 143 | The user cannot access the data anymore. 144 | 145 | ``` 146 | $ curl -H "X-Vault-Token: hvs.CAESIMaHUkthWF-6oG-6TgeINxojiU_VhOGUn8uaHY0SiOZgGh4KHGh2cy55alhIZmFYNGFUOWFKdEl3VWtOSUs2OEU" $VAULT_ADDR/v1/sys/mounts 147 | {"errors":["1 error occurred:\n\t* permission denied\n\n"]} 148 | ``` -------------------------------------------------------------------------------- /exercises/06-service-batch-token/instructions.md: -------------------------------------------------------------------------------- 1 | # Exercise 6 2 | 3 | In this exercise, you will create a service and a batch token. Moreover, you will use other operations for token, e.g. renewal and revocation. 4 | 5 | 1. Log in with the root token. 6 | 2. Create a service token that uses the `default` policy and defines a TTL of 24 hours. 7 | 3. Look up the details of the new token by ID and accessor. 8 | 4. Revoke the token using the accessor. 9 | 5. Create a batch token that uses the `default` policy and defines a TTL of 60 minutes. 10 | 6. Look up the details of the new token by ID. Can you look up token details by accessor? 11 | 7. Renew the batch token. What's the result? -------------------------------------------------------------------------------- /exercises/06-service-batch-token/solution/solution.md: -------------------------------------------------------------------------------- 1 | # Solution 2 | 3 | Run the `login` command with the root token to sign in. 4 | 5 | ``` 6 | $ vault login -address=$VAULT_ADDR $VAULT_TOKEN 7 | WARNING! The VAULT_TOKEN environment variable is set! The value of this 8 | variable will take precedence; if this is unwanted please unset VAULT_TOKEN or 9 | update its value accordingly. 10 | 11 | Success! You are now authenticated. The token information displayed below 12 | is already stored in the token helper. You do NOT need to run "vault login" 13 | again. Future Vault requests will automatically use this token. 14 | 15 | Key Value 16 | --- ----- 17 | token hvs.1dx0yCjCNZFQQOfUljLyRukq 18 | token_accessor 6UqLKI9h3mCIWZrUkRFj2s2Z 19 | token_duration ∞ 20 | token_renewable false 21 | token_policies ["root"] 22 | identity_policies [] 23 | policies ["root"] 24 | ``` 25 | 26 | Create a child token using the root token. The assigned policies can be specified with the `-policy` option, time-to-live can be defined using the `-ttl` option. 27 | 28 | ``` 29 | $ vault token create -policy=default -ttl=24h 30 | Key Value 31 | --- ----- 32 | token hvs.CAESIAmmsG7F20HTbztkJyrjPOxXgyZYW_NRtnx4h4imXRXQGh4KHGh2cy5ndmlocjJYaHNRejdIcGFpOTVteVV0U2Q 33 | token_accessor pTMjI5kDqmFazJOCCoQTNgdb 34 | token_duration 24h 35 | token_renewable true 36 | token_policies ["default"] 37 | identity_policies [] 38 | policies ["default"] 39 | ``` 40 | 41 | You can look up the details of the newly-created token. You will find that the TTL started to count down based on the specified max TTL. The type of the token is `service`. 42 | 43 | ``` 44 | $ vault token lookup hvs.CAESIAmmsG7F20HTbztkJyrjPOxXgyZYW_NRtnx4h4imXRXQGh4KHGh2cy5ndmlocjJYaHNRejdIcGFpOTVteVV0U2Q 45 | Key Value 46 | --- ----- 47 | accessor pTMjI5kDqmFazJOCCoQTNgdb 48 | creation_time 1669824999 49 | creation_ttl 24h 50 | display_name token 51 | entity_id n/a 52 | expire_time 2022-12-01T09:16:39.722267-07:00 53 | explicit_max_ttl 0s 54 | id hvs.CAESIAmmsG7F20HTbztkJyrjPOxXgyZYW_NRtnx4h4imXRXQGh4KHGh2cy5ndmlocjJYaHNRejdIcGFpOTVteVV0U2Q 55 | issue_time 2022-11-30T09:16:39.72227-07:00 56 | meta 57 | num_uses 0 58 | orphan false 59 | path auth/token/create 60 | policies [default] 61 | renewable true 62 | ttl 23h57m55s 63 | type service 64 | ``` 65 | 66 | Similar information can be retrieved using the accessor. In this case, the accessor is `pTMjI5kDqmFazJOCCoQTNgdb`. Note that the ID does not get rendered. 67 | 68 | ``` 69 | $ vault token lookup -accessor pTMjI5kDqmFazJOCCoQTNgdb 70 | Key Value 71 | --- ----- 72 | accessor pTMjI5kDqmFazJOCCoQTNgdb 73 | creation_time 1669824999 74 | creation_ttl 24h 75 | display_name token 76 | entity_id n/a 77 | expire_time 2022-12-01T09:16:39.722267-07:00 78 | explicit_max_ttl 0s 79 | id n/a 80 | issue_time 2022-11-30T09:16:39.72227-07:00 81 | meta 82 | num_uses 0 83 | orphan false 84 | path auth/token/create 85 | policies [default] 86 | renewable true 87 | ttl 23h56m9s 88 | type service 89 | ``` 90 | 91 | Revoke the token using the accessor. 92 | 93 | ``` 94 | $ vault token revoke -accessor pTMjI5kDqmFazJOCCoQTNgdb 95 | Success! Revoked token (if it existed) 96 | ``` 97 | 98 | Create a batch token by specifying the type `batch`. You can see in the output that a batch token does not provide an accessor. 99 | 100 | ``` 101 | $ vault token create -type=batch -policy=default -ttl=60m 102 | Key Value 103 | --- ----- 104 | token hvb.AAAAAQIsoyQpX8TS2KiDv2CSpapgRihMKbT1HboYLsTRNojmO-Qak4aRrzMeeTgoDo8rBsAVxOaXcO-wZCmArlgyDzne6B0ZJ4b6rfxOtJgwkk-rkUswqcb8eOOBjmsRRtlSXKSRcbnWJrOzQB029vtOwi9SLZis2g 105 | token_accessor n/a 106 | token_duration 1h 107 | token_renewable false 108 | token_policies ["default"] 109 | identity_policies [] 110 | policies ["default"] 111 | ``` 112 | 113 | Looking up the token will expose its type. 114 | 115 | ``` 116 | $ vault token lookup hvb.AAAAAQIsoyQpX8TS2KiDv2CSpapgRihMKbT1HboYLsTRNojmO-Qak4aRrzMeeTgoDo8rBsAVxOaXcO-wZCmArlgyDzne6B0ZJ4b6rfxOtJgwkk-rkUswqcb8eOOBjmsRRtlSXKSRcbnWJrOzQB029vtOwi9SLZis2g 117 | Key Value 118 | --- ----- 119 | accessor n/a 120 | creation_time 1669826890 121 | creation_ttl 1h 122 | display_name token 123 | entity_id n/a 124 | expire_time 2022-11-30T10:48:10-07:00 125 | explicit_max_ttl 0s 126 | id hvb.AAAAAQIsoyQpX8TS2KiDv2CSpapgRihMKbT1HboYLsTRNojmO-Qak4aRrzMeeTgoDo8rBsAVxOaXcO-wZCmArlgyDzne6B0ZJ4b6rfxOtJgwkk-rkUswqcb8eOOBjmsRRtlSXKSRcbnWJrOzQB029vtOwi9SLZis2g 127 | issue_time 2022-11-30T09:48:10-07:00 128 | meta 129 | num_uses 0 130 | orphan false 131 | path auth/token/create 132 | policies [default] 133 | renewable false 134 | ttl 57m43s 135 | type batch 136 | ``` 137 | 138 | Trying to renew a batch token will not allow the operation. 139 | 140 | ``` 141 | $ vault token renew hvb.AAAAAQIsoyQpX8TS2KiDv2CSpapgRihMKbT1HboYLsTRNojmO-Qak4aRrzMeeTgoDo8rBsAVxOaXcO-wZCmArlgyDzne6B0ZJ4b6rfxOtJgwkk-rkUswqcb8eOOBjmsRRtlSXKSRcbnWJrOzQB029vtOwi9SLZis2g 142 | Error renewing token: Error making API request. 143 | 144 | URL: PUT http://127.0.0.1:8200/v1/auth/token/renew 145 | Code: 400. Errors: 146 | 147 | * batch tokens cannot be renewed 148 | ``` 149 | -------------------------------------------------------------------------------- /exercises/07-secrets-engine-kv-manage/instructions.md: -------------------------------------------------------------------------------- 1 | # Exercise 7 2 | 3 | In this exercise, you will enable and configure a kv secrets engine. 4 | 5 | 1. Log in with the root token. 6 | 2. List all available secret engines. 7 | 3. Enable the kv secrets engine with the path `app-kv` and version 1. 8 | 4. List all available secret engines again. You should see the kv secrets engine at the path `app-kv/`. 9 | 5. Read the current configuration of the kv secrets engine for the path `sys/mounts/app-kv/tune`. 10 | 6. For the kv secrets engine set the description to `Application kv secrets engine`, and the maximum lease TTL to `120h`. -------------------------------------------------------------------------------- /exercises/07-secrets-engine-kv-manage/solution/solution.md: -------------------------------------------------------------------------------- 1 | # Solution 2 | 3 | Run the `login` command with the root token to sign in. 4 | 5 | ``` 6 | $ vault login -address=$VAULT_ADDR $VAULT_TOKEN 7 | WARNING! The VAULT_TOKEN environment variable is set! The value of this 8 | variable will take precedence; if this is unwanted please unset VAULT_TOKEN or 9 | update its value accordingly. 10 | 11 | Success! You are now authenticated. The token information displayed below 12 | is already stored in the token helper. You do NOT need to run "vault login" 13 | again. Future Vault requests will automatically use this token. 14 | 15 | Key Value 16 | --- ----- 17 | token hvs.1dx0yCjCNZFQQOfUljLyRukq 18 | token_accessor 6UqLKI9h3mCIWZrUkRFj2s2Z 19 | token_duration ∞ 20 | token_renewable false 21 | token_policies ["root"] 22 | identity_policies [] 23 | policies ["root"] 24 | ``` 25 | 26 | List all available secret engines. You will be presented with the default secret engines and any engines you may have created before. The following output shows the default secret engines `cubbyhole`, `identity`, and `sys`. If you are running the Vault development server then you will also see the `secret` kv secrets engine. 27 | 28 | ``` 29 | $ vault secrets list 30 | Path Type Accessor Description 31 | ---- ---- -------- ----------- 32 | cubbyhole/ cubbyhole cubbyhole_e03aff1a per-token private secret storage 33 | identity/ identity identity_3b6c23eb identity store 34 | secret/ kv kv_d0adb6b0 key/value secret storage 35 | sys/ system system_47c5e1dd system endpoints used for control, policy and debugging 36 | ``` 37 | 38 | Enable the secrets engine with the following command. The secrets engine became available on path `app-kv/`. The version of the kv engine is 1. With the current version of Vault, not providing a `-version` option will fall back to version 1. 39 | 40 | ``` 41 | $ vault secrets enable -path=app-kv -version=1 kv 42 | Success! Enabled the kv secrets engine at: app-kv/ 43 | ``` 44 | 45 | Checking the list of enabled secrets engines will now render the freshly-enabled kv engine. 46 | 47 | ``` 48 | $ vault secrets list 49 | Path Type Accessor Description 50 | ---- ---- -------- ----------- 51 | app-kv/ kv kv_de1bd426 n/a 52 | cubbyhole/ cubbyhole cubbyhole_e03aff1a per-token private secret storage 53 | identity/ identity identity_3b6c23eb identity store 54 | secret/ kv kv_d0adb6b0 key/value secret storage 55 | sys/ system system_47c5e1dd system endpoints used for control, policy and debugging 56 | ``` 57 | 58 | You can read the tunable attributes using the `read` command and pointing to the path. 59 | 60 | ``` 61 | $ vault read sys/mounts/app-kv/tune 62 | Key Value 63 | --- ----- 64 | default_lease_ttl 768h 65 | description n/a 66 | force_no_cache false 67 | max_lease_ttl 768h 68 | options map[version:1] 69 | ``` 70 | 71 | Tune the attributes using the `secrets tune` command. See the [documentation](https://developer.hashicorp.com/vault/docs/commands/secrets/tune) for a full list of options. 72 | 73 | ``` 74 | $ vault secrets tune -description="Application kv secrets engine" -max-lease-ttl="120h" app-kv 75 | Success! Tuned the secrets engine at: app-kv/ 76 | ``` 77 | 78 | To verify the change of configuration, re-read the attributes of the kv secrets engine. 79 | 80 | ``` 81 | $ vault read sys/mounts/app-kv/tune 82 | Key Value 83 | --- ----- 84 | default_lease_ttl 768h 85 | description Application kv secrets engine 86 | force_no_cache false 87 | max_lease_ttl 120h 88 | options map[version:1] 89 | ``` -------------------------------------------------------------------------------- /exercises/08-secrets-engine-kv-use/instructions.md: -------------------------------------------------------------------------------- 1 | # Exercise 8 2 | 3 | In this exercise, you will interact with a kv secrets engine by adding, updating, and deleting new secrets. Use the `vault kv` command for each of the steps. 4 | 5 | 1. Use the `kv` command to create a new secret at the path `app-kv/ext-service`. The secret creates a single key-value pair `api-key=iRJgazGtbjC9pLZCZnTMRtPk`. 6 | 2. Use the `kv` command to read the secret at the path `app-kv/ext-service`. Furthermore, try to just get the value of the key `api-key` with a single command. 7 | 3. Change the value of the key `api-key` to `new` and verify that the operation has been performed properly by printing out the command again. How many versions of the entries are available? 8 | 4. Change the kv secrets engine to version 2. What's the current version of the entry? 9 | 5. Use the `kv patch` command to change the value of the `api-key` to `patched`. 10 | 6. Render the current key-value pairs at the path `app-kv/ext-service`. Try to run another command to get back to version 1 of the entry. 11 | 7. Destroy version 2 of the secret at the path `app-kv/ext-service` permanently. Can you retrieve the version again? 12 | -------------------------------------------------------------------------------- /exercises/08-secrets-engine-kv-use/solution/solution.md: -------------------------------------------------------------------------------- 1 | # Solution 2 | 3 | Run the `login` command with the root token to sign in. 4 | 5 | ``` 6 | $ vault login -address=$VAULT_ADDR $VAULT_TOKEN 7 | WARNING! The VAULT_TOKEN environment variable is set! The value of this 8 | variable will take precedence; if this is unwanted please unset VAULT_TOKEN or 9 | update its value accordingly. 10 | 11 | Success! You are now authenticated. The token information displayed below 12 | is already stored in the token helper. You do NOT need to run "vault login" 13 | again. Future Vault requests will automatically use this token. 14 | 15 | Key Value 16 | --- ----- 17 | token hvs.1dx0yCjCNZFQQOfUljLyRukq 18 | token_accessor 6UqLKI9h3mCIWZrUkRFj2s2Z 19 | token_duration ∞ 20 | token_renewable false 21 | token_policies ["root"] 22 | identity_policies [] 23 | policies ["root"] 24 | ``` 25 | 26 | Create a new secret using the `kv put` command. 27 | 28 | ``` 29 | $ vault kv put app-kv/ext-service api-key=iRJgazGtbjC9pLZCZnTMRtPk 30 | Success! Data written to: app-kv/ext-service 31 | ``` 32 | 33 | You can view the secret using the `kv get` command. 34 | 35 | ``` 36 | $ vault kv get app-kv/ext-service 37 | ===== Data ===== 38 | Key Value 39 | --- ----- 40 | api-key iRJgazGtbjC9pLZCZnTMRtPk 41 | ``` 42 | 43 | Individual fields can be accessed by providing the `-field` option. 44 | 45 | ``` 46 | $ vault kv get -field=api-key app-kv/ext-service 47 | iRJgazGtbjC9pLZCZnTMRtPk 48 | ``` 49 | 50 | Adding a new value for the key `api-key` will overwrite the existing entry. 51 | 52 | ``` 53 | $ vault kv put app-kv/ext-service api-key=new 54 | Success! Data written to: app-kv/ext-service 55 | ``` 56 | 57 | You can see the result by running the `kv get` command again. 58 | 59 | ``` 60 | $ vault kv get app-kv/ext-service 61 | ===== Data ===== 62 | Key Value 63 | --- ----- 64 | api-key new 65 | ``` 66 | 67 | Right now, the kv secrets engine is based on version 1. You can enable version for the secrets engine with the following command. The existing entries will be stored as version 1 of the secret. 68 | 69 | ``` 70 | $ vault kv enable-versioning app-kv 71 | Success! Tuned the secrets engine at: app-kv/ 72 | ``` 73 | 74 | Adding a new value for the key `api-key` will create version 2 of the entry. 75 | 76 | ``` 77 | $ vault kv patch app-kv/ext-service api-key=patched 78 | ===== Secret Path ===== 79 | app-kv/data/ext-service 80 | 81 | ======= Metadata ======= 82 | Key Value 83 | --- ----- 84 | created_time 2022-12-05T23:30:01.180985Z 85 | custom_metadata 86 | deletion_time n/a 87 | destroyed false 88 | version 2 89 | ``` 90 | 91 | You can find the current version in the metadata. 92 | 93 | ``` 94 | $ vault kv get app-kv/ext-service 95 | ===== Secret Path ===== 96 | app-kv/data/ext-service 97 | 98 | ======= Metadata ======= 99 | Key Value 100 | --- ----- 101 | created_time 2022-12-05T23:30:01.180985Z 102 | custom_metadata 103 | deletion_time n/a 104 | destroyed false 105 | version 2 106 | 107 | ===== Data ===== 108 | Key Value 109 | --- ----- 110 | api-key patched 111 | ``` 112 | 113 | To get back to version 1 of the secret, simply provide the version as CLI option. 114 | 115 | ``` 116 | $ vault kv get -field=api-key -version=1 app-kv/ext-service 117 | new 118 | ``` 119 | 120 | Destroying a specific version with the `kv destroy` command will permanently delete the entry. It cannot be undeleted anymore. If that's the intention, then you should use the `kv delete` command. 121 | 122 | ``` 123 | $ vault kv destroy -versions=2 app-kv/ext-service 124 | Success! Data written to: app-kv/destroy/ext-service 125 | ``` 126 | 127 | The metadata of the secret will reveal that version 2 has been destroyed, and the oldest available version is 1. 128 | 129 | ``` 130 | $ vault kv metadata get app-kv/ext-service 131 | ====== Metadata Path ====== 132 | app-kv/metadata/ext-service 133 | 134 | ========== Metadata ========== 135 | Key Value 136 | --- ----- 137 | cas_required false 138 | created_time 2022-12-05T23:27:15.907152Z 139 | current_version 2 140 | custom_metadata 141 | delete_version_after 0s 142 | max_versions 0 143 | oldest_version 1 144 | updated_time 2022-12-05T23:30:01.180985Z 145 | 146 | ====== Version 1 ====== 147 | Key Value 148 | --- ----- 149 | created_time 2022-12-05T23:27:15.907152Z 150 | deletion_time n/a 151 | destroyed false 152 | 153 | ====== Version 2 ====== 154 | Key Value 155 | --- ----- 156 | created_time 2022-12-05T23:30:01.180985Z 157 | deletion_time n/a 158 | destroyed true 159 | ``` -------------------------------------------------------------------------------- /exercises/09-secret-engine-aws-lease/instructions.md: -------------------------------------------------------------------------------- 1 | # Exercise 9 2 | 3 | In this exercise, you will enable the AWS secrets engine in Vault. You will then create a dynamic secret in the secrets store and inspect its properties. Reference the relevant [Vault documentation](https://developer.hashicorp.com/vault/docs/secrets/aws) for more information. 4 | 5 | > **_NOTE:_** You will need a [AWS account](https://aws.amazon.com/) for this exercise. I recommend signing up for the free tier which lets you use the account without accruing costs. 6 | 7 | 1. Log in with the root token. 8 | 2. Enable the AWS secrets engine with the path `aws`. 9 | 3. Configure the credentials that Vault uses to communicate with AWS to generate the IAM credentials using the `write aws/config/root` path. Set the region to `us-west-2`. 10 | 4. Configure a Vault role that maps to a set of permissions in AWS as well as an AWS credential type. The path should be `aws/roles/foo`. Provide the following policy document: 11 | 12 | ```json 13 | { 14 | "Version": "2012-10-17", 15 | "Statement": [ 16 | { 17 | "Effect": "Allow", 18 | "Action": "ec2:*", 19 | "Resource": "*" 20 | } 21 | ] 22 | } 23 | ``` 24 | 25 | 5. Generate a new credential by reading from the `aws/creds` endpoint with the name of the role. 26 | 6. Change the lease configuration by setting `lease` to 30m and `lease_max` to 30m. 27 | 7. Generate a new credential and check the lease configuration. 28 | 8. List all available leases and see how many you have available. 29 | 9. Revoke all leases for AWS credentials. -------------------------------------------------------------------------------- /exercises/09-secret-engine-aws-lease/solution/imgs/aws-users.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bmuschko/cva-crash-course/560fe305686e8f32fe75a02d2468a4ca354132db/exercises/09-secret-engine-aws-lease/solution/imgs/aws-users.png -------------------------------------------------------------------------------- /exercises/09-secret-engine-aws-lease/solution/solution.md: -------------------------------------------------------------------------------- 1 | # Solution 2 | 3 | Run the `login` command with the root token to sign in. 4 | 5 | ``` 6 | $ vault login -address=$VAULT_ADDR $VAULT_TOKEN 7 | WARNING! The VAULT_TOKEN environment variable is set! The value of this 8 | variable will take precedence; if this is unwanted please unset VAULT_TOKEN or 9 | update its value accordingly. 10 | 11 | Success! You are now authenticated. The token information displayed below 12 | is already stored in the token helper. You do NOT need to run "vault login" 13 | again. Future Vault requests will automatically use this token. 14 | 15 | Key Value 16 | --- ----- 17 | token hvs.1dx0yCjCNZFQQOfUljLyRukq 18 | token_accessor 6UqLKI9h3mCIWZrUkRFj2s2Z 19 | token_duration ∞ 20 | token_renewable false 21 | token_policies ["root"] 22 | identity_policies [] 23 | policies ["root"] 24 | ``` 25 | 26 | Enable the AWS secrets engine with the following command. 27 | 28 | ``` 29 | $ vault secrets enable -path=aws aws 30 | Success! Enabled the aws secrets engine at: aws/ 31 | ``` 32 | 33 | Provide the AWS access key and secret key. Replace your credentials with the ones assigned by the CLI options `access_key` and `secret_key`. The ones you see in the command below are example values. 34 | 35 | ``` 36 | $ vault write aws/config/root access_key=dJhcRgfknWEEbC8jsQJXdFgX secret_key=oyaNMNdmskYUiMDnDW2toYQR 37 | Success! Data written to: aws/config/root 38 | ``` 39 | 40 | Configure a Vault role using the `write` command. Provide the path `aws/roles/foo`. 41 | 42 | ``` 43 | $ vault write aws/roles/foo credential_type=iam_user policy_document=-< 70 | ``` 71 | 72 | You will be able to view the credentials in the AWS dashboard under _IAM > Access Management > Users_. Every entry will have the prefix `vault-`. 73 | 74 | ![aws-users](./imgs/aws-users.png) 75 | 76 | Change the configuration for AWS leases with the following command. 77 | 78 | ``` 79 | $ vault write aws/config/lease lease=30m lease_max=30m 80 | Success! Data written to: aws/config/lease 81 | ``` 82 | 83 | Every new lease will use this configuration. As you can see in the output below, the `lease_duration` is set to 30m. 84 | 85 | ``` 86 | $ vault read aws/creds/foo 87 | Key Value 88 | --- ----- 89 | lease_id aws/creds/foo/wWM6zTdIOBwo538bXinUH8hF 90 | lease_duration 30m 91 | lease_renewable true 92 | access_key dJhcRgfknWEEbC8jsQJXdFgX 93 | secret_key gzrBkDjPkSwppgbjQTeIWOxylGSzMU40j46FOlof 94 | security_token 95 | ``` 96 | 97 | You now have two leases which you can list with the `list` command. 98 | 99 | ``` 100 | $ vault list sys/leases/lookup/aws/creds/foo 101 | Keys 102 | ---- 103 | XBAkA3DY6qSVuTcbFCwkgdjK 104 | mnsqFf3duo3VnpJJzopMSx24 105 | ``` 106 | 107 | Use the `-prefix` to revoke all leases by path. 108 | 109 | ``` 110 | $ vault lease revoke -prefix aws/creds/foo 111 | All revocation operations queued successfully! 112 | ``` 113 | 114 | All AWS leases have been deleted. 115 | 116 | ``` 117 | $ vault list sys/leases/lookup/aws/creds/foo 118 | No value found at sys/leases/lookup/aws/creds/foo 119 | ``` 120 | -------------------------------------------------------------------------------- /exercises/10-vault-server-init-unseal/instructions.md: -------------------------------------------------------------------------------- 1 | # Exercise 10 2 | 3 | In this exercise, you will start the Vault server with a given HCL configuration file. Once up and running, you will initialize and unseal the Vault. 4 | 5 | 1. Create the configuration file named `vault-server-config.hcl`. The TCP listener should point to `127.0.0.1:8200`. TLS should be disabled. Define a filesystem storage handler pointing to the directory `./vault/data`. The UI needs to become accessible. 6 | 2. Start the Vault server with the configuration file. 7 | 3. Initialize the Vault so that three unseal keys are created. Only two of those unseal keys should be required to unseal it. 8 | 4. Unseal the Vault. 9 | 5. Open the server URL in the browser. 10 | 6. Log in with the root token. -------------------------------------------------------------------------------- /exercises/10-vault-server-init-unseal/solution/solution.md: -------------------------------------------------------------------------------- 1 | # Solution 2 | 3 | Create the server configuration file. You can find an example of such a file [here](vault-server-config.hcl). 4 | 5 | Before starting the server, create the directory for the storage backend. 6 | 7 | ``` 8 | $ mkdir -p ./vault/data 9 | ``` 10 | 11 | Start the server by pointing to the configuration file. 12 | 13 | ``` 14 | $ vault server -config=vault-server-config.hcl 15 | WARNING! mlock is not supported on this system! An mlockall(2)-like syscall to 16 | prevent memory from being swapped to disk is not supported on this system. For 17 | better security, only run Vault on systems where this call is supported. If 18 | you are running Vault in a Docker container, provide the IPC_LOCK cap to the 19 | container. 20 | ==> Vault server configuration: 21 | 22 | Api Address: http://127.0.0.1:8200 23 | Cgo: disabled 24 | Cluster Address: https://127.0.0.1:8201 25 | Go Version: go1.19.3 26 | Listener 1: tcp (addr: "127.0.0.1:8200", cluster address: "127.0.0.1:8201", max_request_duration: "1m30s", max_request_size: "33554432", tls: "disabled") 27 | Log Level: info 28 | Mlock: supported: false, enabled: false 29 | Recovery Mode: false 30 | Storage: file 31 | Version: Vault v1.12.1, built 2022-10-27T12:32:05Z 32 | Version Sha: e34f8a14fb7a88af4640b09f3ddbb5646b946d9c+CHANGES 33 | 34 | ==> Vault server started! Log data will stream in below: 35 | 36 | 2022-12-16T11:32:07.596-0700 [INFO] proxy environment: http_proxy="" https_proxy="" no_proxy="" 37 | 2022-12-16T11:32:07.596-0700 [INFO] core: Initializing version history cache for core 38 | ``` 39 | 40 | Ensure to export the environment variable `VAULT_ADDR` pointing to the HTTP address of the server. Initialize the Vault with 3 unseal keys and a key threshold of 2. 41 | 42 | ``` 43 | $ export VAULT_ADDR='http://127.0.0.1:8200' 44 | $ vault operator init -key-shares=3 -key-threshold=2 45 | Unseal Key 1: CEKE8VSHj0dozR7248+7YHLT0+MznmXC1/15yYlt/nxq 46 | Unseal Key 2: cDo8pMltJqmpPqZQr/cptVgCpPYno0do68GSUAYz65fQ 47 | Unseal Key 3: 2ZNvyBPjaQHX4PXikwgOdSzk8MyZ/n+wMhiYrFeE0Z2Q 48 | 49 | Initial Root Token: hvs.ogeZ5LjMVQZDwLj2k1MWndyu 50 | 51 | Vault initialized with 3 key shares and a key threshold of 2. Please securely 52 | distribute the key shares printed above. When the Vault is re-sealed, 53 | restarted, or stopped, you must supply at least 2 of these keys to unseal it 54 | before it can start servicing requests. 55 | 56 | Vault does not store the generated root key. Without at least 2 keys to 57 | reconstruct the root key, Vault will remain permanently sealed! 58 | 59 | It is possible to generate new unseal keys, provided you have a quorum of 60 | existing unseal keys shares. See "vault operator rekey" for more information. 61 | ``` 62 | 63 | Execute the `operator unseal` command two times. Provide different unseal keys per invocation. 64 | 65 | ``` 66 | $ vault operator unseal 67 | Unseal Key (will be hidden): CEKE8VSHj0dozR7248+7YHLT0+MznmXC1/15yYlt/nxq 68 | Key Value 69 | --- ----- 70 | Seal Type shamir 71 | Initialized true 72 | Sealed true 73 | Total Shares 3 74 | Threshold 2 75 | Unseal Progress 1/2 76 | Unseal Nonce 2149894b-2de6-af6f-bb76-eabcdd0ea64a 77 | Version 1.12.1 78 | Build Date 2022-10-27T12:32:05Z 79 | Storage Type file 80 | HA Enabled false 81 | $ vault operator unseal 82 | Unseal Key (will be hidden): cDo8pMltJqmpPqZQr/cptVgCpPYno0do68GSUAYz65fQ 83 | Key Value 84 | --- ----- 85 | Seal Type shamir 86 | Initialized true 87 | Sealed false 88 | Total Shares 3 89 | Threshold 2 90 | Version 1.12.1 91 | Build Date 2022-10-27T12:32:05Z 92 | Storage Type file 93 | Cluster Name vault-cluster-c7fc4948 94 | Cluster ID 5696e522-4fab-309f-4a3c-105828e0f41c 95 | HA Enabled false 96 | ``` 97 | 98 | Open the browser at [http://127.0.0.1:8200](http://127.0.0.1:8200). Select the method "Token" and enter the intial root token value. In this case, the value is `hvs.ogeZ5LjMVQZDwLj2k1MWndyu`. Click on the "Sign In" button. -------------------------------------------------------------------------------- /exercises/10-vault-server-init-unseal/solution/vault-server-config.hcl: -------------------------------------------------------------------------------- 1 | listener "tcp" { 2 | address = "127.0.0.1:8200" 3 | tls_disable = 1 4 | } 5 | 6 | storage "file" { 7 | path = "./vault/data" 8 | } 9 | 10 | api_addr = "http://127.0.0.1:8200" 11 | ui = true -------------------------------------------------------------------------------- /exercises/11-response-wrapping/instructions.md: -------------------------------------------------------------------------------- 1 | # Exercise 11 2 | 3 | In this exercise, you will use the response wrapping concept for a secret in the kv secrets engine. 4 | 5 | 1. Log in with the root token. 6 | 2. Enable the kv secrets engine. 7 | 3. Add the entry `hello=world` to the engine at the path `kv/app`. 8 | 4. Create a wrapping token for the secret. Set a TTL of 60 minutes. 9 | 5. Unwrap the secret with the wrapping token. 10 | 6. Try to unwrap the secret again with the same wrapping token. -------------------------------------------------------------------------------- /exercises/11-response-wrapping/solution/solution.md: -------------------------------------------------------------------------------- 1 | # Solution 2 | 3 | Run the `login` command with the root token to sign in. 4 | 5 | ``` 6 | $ vault login -address=$VAULT_ADDR $VAULT_TOKEN 7 | WARNING! The VAULT_TOKEN environment variable is set! The value of this 8 | variable will take precedence; if this is unwanted please unset VAULT_TOKEN or 9 | update its value accordingly. 10 | 11 | Success! You are now authenticated. The token information displayed below 12 | is already stored in the token helper. You do NOT need to run "vault login" 13 | again. Future Vault requests will automatically use this token. 14 | 15 | Key Value 16 | --- ----- 17 | token hvs.1dx0yCjCNZFQQOfUljLyRukq 18 | token_accessor 6UqLKI9h3mCIWZrUkRFj2s2Z 19 | token_duration ∞ 20 | token_renewable false 21 | token_policies ["root"] 22 | identity_policies [] 23 | policies ["root"] 24 | ``` 25 | 26 | Enable the secrets engine with the following command. The secrets engine became available on path `kv/`. 27 | 28 | ``` 29 | $ vault secrets enable kv 30 | Success! Enabled the kv secrets engine at: kv/ 31 | ``` 32 | 33 | Create a new secret using the `kv put` command. 34 | 35 | ``` 36 | $ vault kv put kv/app hello=world 37 | Success! Data written to: kv/app 38 | ``` 39 | 40 | Wrap the kv secret with the following command. 41 | 42 | ``` 43 | $ vault kv get -wrap-ttl=60m kv/app 44 | Key Value 45 | --- ----- 46 | wrapping_token: hvs.CAESILn8XOKS-lZ-UtiedlzqqrdxcxST09expCnJyVj09-91Gh4KHGh2cy4yTXJuQ2JjdTBRdW55a2I2VGdRTU1IdnI 47 | wrapping_accessor: GHJj6kC5MVFNRclw7uB1OoVn 48 | wrapping_token_ttl: 1h 49 | wrapping_token_creation_time: 2022-12-16 12:08:22.72283 -0700 MST 50 | wrapping_token_creation_path: kv/app 51 | ``` 52 | 53 | Use the wrapping token to unwrap the kv secret. You will see the plain-text value of the secret. 54 | 55 | ``` 56 | $ vault unwrap hvs.CAESILn8XOKS-lZ-UtiedlzqqrdxcxST09expCnJyVj09-91Gh4KHGh2cy4yTXJuQ2JjdTBRdW55a2I2VGdRTU1IdnI 57 | Key Value 58 | --- ----- 59 | refresh_interval 768h 60 | hello world 61 | ``` 62 | 63 | Trying to run the `unwrap` command will result in an error. The wrapping token can only be used once. 64 | 65 | ``` 66 | $ vault unwrap hvs.CAESILn8XOKS-lZ-UtiedlzqqrdxcxST09expCnJyVj09-91Gh4KHGh2cy4yTXJuQ2JjdTBRdW55a2I2VGdRTU1IdnI 67 | Error unwrapping: Error making API request. 68 | 69 | URL: PUT http://127.0.0.1:8200/v1/sys/wrapping/unwrap 70 | Code: 400. Errors: 71 | 72 | * wrapping token is not valid or does not exist 73 | ``` -------------------------------------------------------------------------------- /exercises/12-transit-engine-encryption/instructions.md: -------------------------------------------------------------------------------- 1 | # Exercise 12 2 | 3 | In this exercise, you will use the Transit engine for encryption/decryption purposes. 4 | 5 | 1. Log in with the root token. 6 | 2. Enable the Transit engine with the path `transit`. 7 | 3. Create an encryption key named `chacha` of type `chacha20-poly1305`. Check the details of the encryption key. 8 | 4. Encrpyt the value `abc123` using the encryption key named `chacha`. 9 | 5. Decrypt the value `abc123` using the ciphertext with the encryption key named `chacha`. 10 | 6. Rotate the encryption key. Check the details of the encryption key. 11 | 7. Change `min_decryption_version` property of the encryption key to version 2. Can you still decrypt the value `abc123` with the ciphertext from version 1? -------------------------------------------------------------------------------- /exercises/12-transit-engine-encryption/solution/solution.md: -------------------------------------------------------------------------------- 1 | # Solution 2 | 3 | Run the `login` command with the root token to sign in. 4 | 5 | ``` 6 | $ vault login -address=$VAULT_ADDR $VAULT_TOKEN 7 | WARNING! The VAULT_TOKEN environment variable is set! The value of this 8 | variable will take precedence; if this is unwanted please unset VAULT_TOKEN or 9 | update its value accordingly. 10 | 11 | Success! You are now authenticated. The token information displayed below 12 | is already stored in the token helper. You do NOT need to run "vault login" 13 | again. Future Vault requests will automatically use this token. 14 | 15 | Key Value 16 | --- ----- 17 | token hvs.1dx0yCjCNZFQQOfUljLyRukq 18 | token_accessor 6UqLKI9h3mCIWZrUkRFj2s2Z 19 | token_duration ∞ 20 | token_renewable false 21 | token_policies ["root"] 22 | identity_policies [] 23 | policies ["root"] 24 | ``` 25 | 26 | Enable the Transit engine. 27 | 28 | ``` 29 | $ vault secrets enable transit 30 | Success! Enabled the transit secrets engine at: transit/ 31 | ``` 32 | 33 | Create the encryption key `chacha` with type `chacha20-poly1305`. 34 | 35 | ``` 36 | $ vault write -f transit/keys/chacha type=chacha20-poly1305 37 | Success! Data written to: transit/keys/chacha 38 | ``` 39 | 40 | Check on the properties of the encryption key. 41 | 42 | ``` 43 | $ vault read transit/keys/chacha 44 | Key Value 45 | --- ----- 46 | allow_plaintext_backup false 47 | auto_rotate_period 0s 48 | deletion_allowed false 49 | derived false 50 | exportable false 51 | imported_key false 52 | keys map[1:1670984964] 53 | latest_version 1 54 | min_available_version 0 55 | min_decryption_version 1 56 | min_encryption_version 0 57 | name chacha 58 | supports_decryption true 59 | supports_derivation true 60 | supports_encryption true 61 | supports_signing false 62 | type chacha20-poly1305 63 | ``` 64 | 65 | Encrypt the value `abc123` with the encryption key. Ensure that you base64-encode the value before sending it to the Transit engine. 66 | 67 | ``` 68 | $ echo "abc123" | base64 69 | YWJjMTIzCg== 70 | $ vault write transit/encrypt/chacha plaintext=YWJjMTIzCg== 71 | Key Value 72 | --- ----- 73 | ciphertext vault:v1:RWSTpSNEKqGUM3EJEA5cFE7yjf6Bz01F5ih7Tlz3wPYrsVY= 74 | key_version 1 75 | ``` 76 | 77 | Decrypt the value using the ciphertext. Base64-decode the value to see the plain-text representation. 78 | 79 | ``` 80 | $ vault write transit/decrypt/chacha ciphertext=vault:v1:RWSTpSNEKqGUM3EJEA5cFE7yjf6Bz01F5ih7Tlz3wPYrsVY= 81 | Key Value 82 | --- ----- 83 | plaintext YWJjMTIzCg== 84 | $ echo "YWJjMTIzCg==" | base64 -d 85 | abc123 86 | ``` 87 | 88 | Rotate the encryption key. The `latest_version` key will now show the value 2. 89 | 90 | ``` 91 | $ vault write -f transit/keys/chacha/rotate 92 | Success! Data written to: transit/keys/chacha/rotate 93 | $ vault read transit/keys/chacha 94 | Key Value 95 | --- ----- 96 | allow_plaintext_backup false 97 | auto_rotate_period 0s 98 | deletion_allowed false 99 | derived false 100 | exportable false 101 | imported_key false 102 | keys map[1:1670984964 2:1670986091] 103 | latest_version 2 104 | min_available_version 0 105 | min_decryption_version 1 106 | min_encryption_version 0 107 | name chacha 108 | supports_decryption true 109 | supports_derivation true 110 | supports_encryption true 111 | supports_signing false 112 | type chacha20-poly1305 113 | ``` 114 | 115 | Change `min_decryption_version` property of the encryption key to version 2. 116 | 117 | ``` 118 | $ vault write transit/keys/chacha/config min_decryption_version=2 119 | Success! Data written to: transit/keys/chacha/config 120 | $ vault read transit/keys/chacha 121 | Key Value 122 | --- ----- 123 | allow_plaintext_backup false 124 | auto_rotate_period 0s 125 | deletion_allowed false 126 | derived false 127 | exportable false 128 | imported_key false 129 | keys map[2:1670986091] 130 | latest_version 2 131 | min_available_version 0 132 | min_decryption_version 2 133 | min_encryption_version 0 134 | name chacha 135 | supports_decryption true 136 | supports_derivation true 137 | supports_encryption true 138 | supports_signing false 139 | type chacha20-poly1305 140 | ``` 141 | 142 | Version 1 of the encryption key has been deleted. You cannot use the corresponding ciphertext anymore to decrypt the value. 143 | 144 | ``` 145 | $ vault write transit/decrypt/chacha ciphertext=vault:v1:RWSTpSNEKqGUM3EJEA5cFE7yjf6Bz01F5ih7Tlz3wPYrsVY= 146 | Error writing data to transit/decrypt/chacha: Error making API request. 147 | 148 | URL: PUT http://127.0.0.1:8200/v1/transit/decrypt/chacha 149 | Code: 400. Errors: 150 | 151 | * ciphertext or signature version is disallowed by policy (too old) 152 | ``` -------------------------------------------------------------------------------- /prerequisites/instructions.md: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | 3 | Exercises will require the tooling listed below. Ensure that all of those tools have been installed before attending the training if you want to follow along. The training does not reserve time for setting up or verifying the installed tools or their respective versions. 4 | 5 | ## Technical Requirements 6 | 7 | * A computer with [Vault](https://developer.hashicorp.com/vault/docs/install) installed 8 | * An editor to write and modify configuration files (instructor will use [VSCode](https://code.visualstudio.com/download), but other IDEs like IDEA may work as well) 9 | * A [Git client](https://git-scm.com/downloads) to interact with a GitHub repository 10 | * An [AWS account](https://aws.amazon.com/) and credentials for to perform tasks in some of the exercises 11 | * An optional installation of the commandline JSON processor [jq](https://stedolan.github.io/jq/) for formatting Vault API responses 12 | 13 | ## Skills 14 | 15 | * Familiarity with Unix command-line tools like wget, curl, or tar 16 | * Knowledge of Bash scripting (e.g., syntax, language constructs) 17 | * Basic understanding of cloud technologies 18 | -------------------------------------------------------------------------------- /slides.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bmuschko/cva-crash-course/560fe305686e8f32fe75a02d2468a4ca354132db/slides.pdf --------------------------------------------------------------------------------