{"id":1006,"date":"2026-05-23T08:40:30","date_gmt":"2026-05-23T08:40:30","guid":{"rendered":"https:\/\/www.devopsschool.com\/tutorials\/?p=1006"},"modified":"2026-05-23T08:40:31","modified_gmt":"2026-05-23T08:40:31","slug":"hashicorp-vault-step-by-step-tutorial-vault-cli-on-linux-kv-secrets-userpass-auth-policy-and-crud","status":"publish","type":"post","link":"https:\/\/www.devopsschool.com\/tutorials\/hashicorp-vault-step-by-step-tutorial-vault-cli-on-linux-kv-secrets-userpass-auth-policy-and-crud\/","title":{"rendered":"HashiCorp Vault:  Step-by-Step Tutorial: Vault CLI on Linux \u2014 KV Secrets, Userpass Auth, Policy, and CRUD"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">This lab uses <strong>Vault CLI on Linux<\/strong> and demonstrates the full flow:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Start Vault<\/li>\n\n\n\n<li>Enable KV secrets engine<\/li>\n\n\n\n<li>Enable <code>userpass<\/code> auth<\/li>\n\n\n\n<li>Create a user without policy<\/li>\n\n\n\n<li>Login as the user and fail to CRUD secrets<\/li>\n\n\n\n<li>Create a policy<\/li>\n\n\n\n<li>Attach policy to user<\/li>\n\n\n\n<li>Login again and perform CRUD successfully<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Vault\u2019s <code>kv<\/code> command works with both KV v1 and KV v2, but for KV v2 the CLI path and policy path are different. HashiCorp recommends using the <code>-mount<\/code> flag to avoid confusion with KV v2 paths. (<a href=\"https:\/\/developer.hashicorp.com\/vault\/docs\/commands\/kv\">HashiCorp Developer<\/a>)<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">1. Prerequisites<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">You need a Linux machine with Vault installed. Vault is available as a precompiled binary and through Linux package managers such as <code>apt<\/code> and <code>yum<\/code>. (<a href=\"https:\/\/developer.hashicorp.com\/vault\/tutorials\/get-started\/install-binary\">HashiCorp Developer<\/a>)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For Ubuntu\/Debian:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apt update\nsudo apt install -y gpg wget\n\nwget -O- https:\/\/apt.releases.hashicorp.com\/gpg | \\\n  sudo gpg --dearmor -o \/usr\/share\/keyrings\/hashicorp-archive-keyring.gpg\n\necho \"deb &#91;arch=$(dpkg --print-architecture) signed-by=\/usr\/share\/keyrings\/hashicorp-archive-keyring.gpg] https:\/\/apt.releases.hashicorp.com $(grep -oP '(?&lt;=UBUNTU_CODENAME=).*' \/etc\/os-release || lsb_release -cs) main\" | \\\n  sudo tee \/etc\/apt\/sources.list.d\/hashicorp.list\n\nsudo apt update\nsudo apt install -y vault\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Verify:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vault version\nvault -help\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">2. Start Vault Dev Server<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">For this lab, use Vault dev mode. This is only for learning, not production.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Open <strong>Terminal 1<\/strong>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vault server -dev -dev-root-token-id=root\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Keep this terminal running.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Open <strong>Terminal 2<\/strong> and export Vault address and root token:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>export VAULT_ADDR='http:\/\/127.0.0.1:8200'\nexport VAULT_TOKEN='root'\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Verify Vault status:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vault status\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Expected:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Sealed      false\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Login with root token:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vault login root\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">3. Enable KV Secrets Engine<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">We will enable KV v2 at path <code>devops<\/code>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vault secrets enable -path=devops kv-v2\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Expected:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Success! Enabled the kv-v2 secrets engine at: devops\/\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Check enabled secrets engines:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vault secrets list\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Expected output should include:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>devops\/    kv\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">KV v2 stores versioned secrets and uses special API paths such as <code>devops\/data\/...<\/code> for secret data and <code>devops\/metadata\/...<\/code> for listing\/metadata operations. (<a href=\"https:\/\/developer.hashicorp.com\/vault\/docs\/secrets\/kv\">HashiCorp Developer<\/a>)<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">4. Enable Userpass Auth Method<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Enable the <code>userpass<\/code> authentication method:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vault auth enable userpass\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Expected:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Success! Enabled the userpass auth method at: userpass\/\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>userpass<\/code> auth method allows users to authenticate with a username and password stored directly in Vault under the <code>users\/<\/code> path. (<a href=\"https:\/\/developer.hashicorp.com\/vault\/docs\/auth\/userpass\">HashiCorp Developer<\/a>)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Verify auth methods:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vault auth list\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Expected output should include:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>userpass\/    userpass\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">5. Create a User Without Policy<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Create a user called <code>devuser<\/code>, but do <strong>not<\/strong> attach any custom policy yet.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vault write auth\/userpass\/users\/devuser \\\n  password='DevUser@123'\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Expected:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Success! Data written to: auth\/userpass\/users\/devuser\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">At this point, the user can login, but cannot access the <code>devops<\/code> secrets engine because Vault policies are deny-by-default unless access is explicitly granted. (<a href=\"https:\/\/developer.hashicorp.com\/vault\/docs\/concepts\/policies\">HashiCorp Developer<\/a>)<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">6. Login as the User<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Login as <code>devuser<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vault login -method=userpass \\\n  username=devuser \\\n  password='DevUser@123'\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Expected output:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Success! You are now authenticated.\ntoken_policies    &#91;\"default\"]\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Check current token:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vault token lookup\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You should see only the <code>default<\/code> policy.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">7. Try CRUD Secret as User \u2014 It Should Fail<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Try to Create Secret<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>vault kv put -mount=devops app1\/db \\\n  username='admin' \\\n  password='secret123'\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Expected failure:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Error writing data to devops\/data\/app1\/db: Error making API request.\n\nCode: 403. Errors:\n\n* permission denied\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Try to Read Secret<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>vault kv get -mount=devops app1\/db\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Expected:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>permission denied\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This failure is correct. The user authenticated successfully, but authorization failed because no policy allows access to <code>devops\/data\/*<\/code>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">8. Login Back as Root Admin<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Now switch back to root token so we can create a policy.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vault login root\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Or:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>export VAULT_TOKEN='root'\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Confirm:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vault token lookup\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Expected:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>policies    &#91;root]\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">9. Create a Policy to Allow CRUD on KV Secrets<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Create a policy file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cat &gt; devops-crud-policy.hcl &lt;&lt;'EOF'\n# Allow create, read, update, and delete secret data in KV v2\npath \"devops\/data\/*\" {\n  capabilities = &#91;\"create\", \"read\", \"update\", \"delete\"]\n}\n\n# Allow listing secrets and reading metadata in KV v2\npath \"devops\/metadata\" {\n  capabilities = &#91;\"list\"]\n}\n\npath \"devops\/metadata\/*\" {\n  capabilities = &#91;\"read\", \"list\", \"delete\"]\n}\nEOF\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Important: for KV v2, <code>vault kv put\/get\/delete<\/code> uses the user-friendly command path, but the policy must target <code>devops\/data\/*<\/code>. Listing uses <code>devops\/metadata\/*<\/code>. HashiCorp\u2019s KV docs show that KV v2 maps <code>kv get<\/code>, <code>kv put<\/code>, and <code>kv delete<\/code> to <code>secret\/data\/&lt;key_path&gt;<\/code>, while <code>kv list<\/code> maps to <code>secret\/metadata\/&lt;key_path&gt;<\/code>. (<a href=\"https:\/\/developer.hashicorp.com\/vault\/docs\/secrets\/kv\">HashiCorp Developer<\/a>)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Upload the policy:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vault policy write devops-crud devops-crud-policy.hcl\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Expected:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Success! Uploaded policy: devops-crud\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Verify policy:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vault policy read devops-crud\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">10. Attach Policy to Userpass User<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Update the existing <code>devuser<\/code> and attach the <code>devops-crud<\/code> policy:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vault write auth\/userpass\/users\/devuser \\\n  password='DevUser@123' \\\n  policies='devops-crud'\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Expected:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Success! Data written to: auth\/userpass\/users\/devuser\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">In <code>userpass<\/code>, users are configured under <code>auth\/userpass\/users\/&lt;username&gt;<\/code>, and policies can be associated during user creation or update. (<a href=\"https:\/\/developer.hashicorp.com\/vault\/docs\/auth\/userpass\">HashiCorp Developer<\/a>)<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">11. Login Again as User<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>vault login -method=userpass \\\n  username=devuser \\\n  password='DevUser@123'\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Expected:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Success! You are now authenticated.\ntoken_policies    &#91;\"default\" \"devops-crud\"]\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Confirm:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vault token lookup\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You should now see:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>policies    &#91;default devops-crud]\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">12. Perform CRUD Secret Using User<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Now the same user should be able to create, read, update, and delete secrets.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">C \u2014 Create Secret<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>vault kv put -mount=devops app1\/db \\\n  username='admin' \\\n  password='secret123'\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Expected:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>== Secret Path ==\ndevops\/data\/app1\/db\n\n======= Metadata =======\nversion    1\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">R \u2014 Read Secret<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>vault kv get -mount=devops app1\/db\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Expected:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>== Secret Path ==\ndevops\/data\/app1\/db\n\n====== Data ======\nKey         Value\n---         -----\npassword    secret123\nusername    admin\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">U \u2014 Update Secret<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>vault kv put -mount=devops app1\/db \\\n  username='admin' \\\n  password='newSecret456'\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Expected:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>== Secret Path ==\ndevops\/data\/app1\/db\n\n======= Metadata =======\nversion    2\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Read again:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vault kv get -mount=devops app1\/db\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Expected:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>password    newSecret456\nusername    admin\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">L \u2014 List Secrets<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>vault kv list -mount=devops app1\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Expected:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Keys\n----\ndb\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">D \u2014 Delete Secret<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>vault kv delete -mount=devops app1\/db\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Expected:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Success! Data deleted, if it existed, at: devops\/data\/app1\/db\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Try to read again:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vault kv get -mount=devops app1\/db\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Expected:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>No value found at devops\/data\/app1\/db\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">In KV v2, <code>kv delete<\/code> marks a version as deleted; it does not permanently destroy the underlying version data. Permanent removal uses <code>vault kv destroy<\/code>, and full metadata removal uses <code>vault kv metadata delete<\/code>. (<a href=\"https:\/\/developer.hashicorp.com\/vault\/docs\/secrets\/kv\">HashiCorp Developer<\/a>)<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">13. Optional: Permanently Remove Secret Metadata<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Because KV v2 keeps metadata and versions, you may still see the path in metadata unless you delete it.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vault kv metadata delete -mount=devops app1\/db\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Expected:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Success! Data deleted, if it existed, at: devops\/metadata\/app1\/db\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">14. Useful Verification Commands<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Check secrets engines:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vault secrets list\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Check auth methods:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vault auth list\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Check current login token:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vault token lookup\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Check policies:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vault policy list\nvault policy read devops-crud\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Check user by reading config as root:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vault read auth\/userpass\/users\/devuser\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">15. Cleanup Lab<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Login as root:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vault login root\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Delete user:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vault delete auth\/userpass\/users\/devuser\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Delete policy:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vault policy delete devops-crud\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Disable auth method:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vault auth disable userpass\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Disable secrets engine:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vault secrets disable devops\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Stop Vault dev server by pressing:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>CTRL + C\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Final Flow Summary<\/h1>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Step<\/th><th>Command Area<\/th><th>Purpose<\/th><\/tr><\/thead><tbody><tr><td>1<\/td><td><code>vault server -dev<\/code><\/td><td>Start lab Vault server<\/td><\/tr><tr><td>2<\/td><td><code>vault secrets enable -path=devops kv-v2<\/code><\/td><td>Enable KV secrets engine<\/td><\/tr><tr><td>3<\/td><td><code>vault auth enable userpass<\/code><\/td><td>Enable username\/password login<\/td><\/tr><tr><td>4<\/td><td><code>vault write auth\/userpass\/users\/devuser<\/code><\/td><td>Create user without policy<\/td><\/tr><tr><td>5<\/td><td><code>vault login -method=userpass<\/code><\/td><td>Login as user<\/td><\/tr><tr><td>6<\/td><td><code>vault kv put\/get<\/code><\/td><td>Fails because user has no policy<\/td><\/tr><tr><td>7<\/td><td><code>vault policy write<\/code><\/td><td>Create CRUD policy<\/td><\/tr><tr><td>8<\/td><td><code>vault write auth\/userpass\/users\/devuser policies=...<\/code><\/td><td>Attach policy<\/td><\/tr><tr><td>9<\/td><td><code>vault login -method=userpass<\/code><\/td><td>Login again with policy<\/td><\/tr><tr><td>10<\/td><td><code>vault kv put\/get\/list\/delete<\/code><\/td><td>CRUD succeeds<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">This lab proves the key Vault concept: <strong>authentication only proves who the user is; policy decides what the user can do.<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This lab uses Vault CLI on Linux and demonstrates the full flow: Vault\u2019s kv command works with both KV v1 and KV v2, but for KV v2&#8230; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1006","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts\/1006","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/comments?post=1006"}],"version-history":[{"count":1,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts\/1006\/revisions"}],"predecessor-version":[{"id":1007,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts\/1006\/revisions\/1007"}],"wp:attachment":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/media?parent=1006"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/categories?post=1006"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/tags?post=1006"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}