{"id":14069697,"url":"https://github.com/sethvargo/vault-demo","last_synced_at":"2025-07-30T06:32:29.588Z","repository":{"id":66255472,"uuid":"68317471","full_name":"sethvargo/vault-demo","owner":"sethvargo","description":"Walkthroughs and scripts for my @HashiCorp Vault talks","archived":true,"fork":false,"pushed_at":"2019-04-23T07:44:04.000Z","size":12,"stargazers_count":65,"open_issues_count":0,"forks_count":17,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-08-13T07:16:05.700Z","etag":null,"topics":["google-cloud","hashicorp-vault","modern-security","security","vault"],"latest_commit_sha":null,"homepage":"https://www.vaultproject.io/","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sethvargo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2016-09-15T17:51:18.000Z","updated_at":"2024-05-07T13:38:42.000Z","dependencies_parsed_at":"2023-02-20T20:01:03.492Z","dependency_job_id":null,"html_url":"https://github.com/sethvargo/vault-demo","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sethvargo%2Fvault-demo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sethvargo%2Fvault-demo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sethvargo%2Fvault-demo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sethvargo%2Fvault-demo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sethvargo","download_url":"https://codeload.github.com/sethvargo/vault-demo/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228102115,"owners_count":17869781,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["google-cloud","hashicorp-vault","modern-security","security","vault"],"created_at":"2024-08-13T07:07:09.119Z","updated_at":"2024-12-04T11:30:37.283Z","avatar_url":"https://github.com/sethvargo.png","language":"Shell","funding_links":[],"categories":["Shell"],"sub_categories":[],"readme":"# Vault Demo\n\nThis repository contains the materials and demo for my **Modern Secrets\nManagement** with Vault talk. It has been given at a number of conferences and\nmeetups.\n\nThis README contains the steps I take when demoing Vault. I usually change\nthings up a bit here and there, but the content is generally like this. The\nsteps here are for demo purposes and **may not represent best practices!**\n\nIf you want to run HashiCorp Vault in production, check out\n[sethvargo/vault-on-gke](https://github.com/sethvargo/vault-on-gke).\n\n\n## Getting Started\n\nFirst, we need to configure our local client to talk to the remote Vault server:\n\n```\nexport VAULT_DEV_ROOT_TOKEN_ID=root\nexport VAULT_ADDR=http://127.0.0.1\n```\n\nThis server is not designed to be a \"best-practices\" Vault server and is mostly\ndesigned for demonstrations such as this. It is not production ready. Please do\nnot use this Vault setup in production.\n\nStart the Vault server\n\n```\nvault server -dev -dev-plugin-dir=./plugins\n```\n\nOpen a new terminal tab/session or background the process.\n\n\n## Authentication\n\nThe first thing we need to do is authenticate to the Vault. Because this Vault\nis completely unconfigured, we need to use the root token to get started.\nNormally this is a random UUID, but we cheated and made it \"root\" to make the\ndemo easier.\n\n```\nvault login root\n```\n\nThere are many ways to authenticate to Vault including GitHub,\nusername-password, LDAP, and more. There are also ways for machines to\nauthenticate such as AppID or TLS.\n\nThe root user is special and has all permissions in the system. Other users must\nbe granted access via policies, which we will explore in a bit.\n\n\n## Create Users\n\nCreate some users who will authenticate to Vault. These users will\nauthentication with standard username and password.\n\n```\n./scripts/create-users.sh\n```\n\n\n## Static Secrets\n\nThere are two kinds of secrets in Vault - static and dynamic. Dynamic secrets\nhave enforced leases and usually expire after a short period of time. Static\nsecrets are refresh intervals, but they do not expire unless explicitly removed.\n\nThe easiest way to think about static secrets is \"encrypted redis\" or \"encrypted\nmemcached\". Vault exposes an encrypted key-value store such that all data\nwritten is encrypted and stored.\n\nLet's go ahead and write, read, update, and delete some static secrets:\n\n```\nvault kv put secret/foo a=b\n```\n\nRead a secret\n\n```\nvault kv get secret/foo\n```\n\nShow versioning\n\n```\nvault kv put secret/foo c=d\nvault kv get secret/foo\nvault kv get -version=1 secret/foo\n```\n\nRollback\n\n```\nvault kv rollback -version=1 secret/foo\nvault kv get secret/foo\n```\n\nDelete\n\n```\nvault kv delete secret/foo\n```\n\n\n## Transit\n\nThe transit backend provides \"encryption as a service\" and allows round-tripping\nof data through Vault. This data is never actually stored in Vault, so the\nmemory footprint is relatively low (as compared with the generic secret backend,\nfor example). The transit backend behaves very similar a cloud KMS service\n\nThe advantage here is that applications do not need to know how to do asymmetric\nencryption nor do they applications even know the encryption key. An attacker\nwould need to compromise multiple systems to decrypt the data.\n\n```\nvault secrets enable transit\n```\n\nCreate an encryption key. You can think of the name \"myapp\" as a symlink or\npointer to the actual encryption key.\n\n```\nvault write -f transit/keys/myapp\n```\n\nEncrypt some data (base64). Now we can feed data into this named key, and Vault\nwill return the encrypted data. Because there is no requirement the data be\n\"text\", we need to pass base64-encoded data.\n\n```\nvault write transit/encrypt/myapp plaintext=$(base64 \u003c\u003c\u003c \"hi\")\n```\n\nVault returns the base64-encoded ciphertext. This ciphertext can be stored in\nour database or filesystem. When our application needs the plaintext value, it\ncan post the encrypted value and get the plaintext back.\n\nDecrypt that data.\n\n```\nvault write transit/decrypt/myapp ciphertext=\"...\"\n```\n\nThe transit endpoint supports key rotation as well. Trigger a key rotation:\n\n```\nvault write -f transit/keys/myapp/rotate\n```\n\nThis will add a new encryption key to a ring, and data will be upgraded to the\nnew version on the fly automatically. We could optionally have an application\nthat iterates through the data and \"rewraps\" to the new encryption key. The\nadvantage to the rewrap endpoint is that we never disclose the plaintext to the\nprocess - both the input and output are ciphertext. Here is what that looks\nlike:\n\n```\nvault write transit/rewrap/myapp ciphertext=\"...\"\n```\n\nWe could have a relatively un-trusted process perform the rewrap operation,\nbecause it never discloses the plaintext.\n\nLastly, it may be tempting to have **per-row encryption keys** (like in a\ndatabase). However, you should not do this. That means Vault needs to maintain\none encryption key per row, and that will bloat over time. Instead you can use\n[derived keys](https://www.vaultproject.io/docs/secrets/transit/), which allow a\nper-context encryption value.\n\n\n## Database\n\nVault also has the ability to _generate_ secrets. These are called \"dynamic\"\nsecrets. Unlike static secrets, dynamic secrets have an expiration, called a\nlease. At the end of this lease, the credential is revoked. This prevents secret\nsprawl and significantly reduces the attack surface. Instead of a database\npassword living in a text file for 6 months, it can be dynamically generated\nevery 30 minutes!\n\nStart postgres (requires Docker). This example uses a local Postgres instance,\nbut this could easily be a Google Cloud SQL instance or other hosted database\nservice.\n\n```\n./scripts/start-postgres.sh\n```\n\nEnable the database secrets engine.\n\n```\nvault secrets enable database\n```\n\nConfigure the database connection and role.\n\n```\ncat scripts/configure-database.sh\n```\n\n- Explain role mapping to credentials (like a symlink)\n- Explain ttl\n\n```\n./scripts/configure-database.sh\n```\n\nGenerate a new database credential\n\n```\nvault read database/creds/readonly\n```\n\nLogin as one of our users and generate:\n\n```\nvault login -method=userpass username=chris password=password\nvault read database/creds/readonly\n```\n\nLog back in as the root user:\n\n```\nvault login root\n```\n\nDo this a few times to showcase real production\n\n```\n./scripts/generate-credentials.sh\n```\n\nShow\n\n```\npsql\n\\du\n\\q\n```\n\nOh no - chris and devin are evil - let's revoke everything\n\n```\nvault token revoke -mode=path auth/userpass/login/chris\nvault token revoke -mode=path auth/userpass/login/devin\n```\n\n```\npsql\n\\du\n\\q\n```\n\nSerious data breach\n\n```\nvault lease revoke -prefix database/\n```\n\n\n## TOTP\n\n```\nvault secrets enable totp\n```\n\nCreate a key (your app would make an API call to vault for this)\n\n```\nvault write totp/keys/seth \\\n  generate=true \\\n  issuer=MyApp \\\n  account_name=seth@sethvargo.com\n```\n\nQR code\n\n```\necho \"...\" | base64 --decode \u003e qr.png\n```\n\nSign into 1password\n\n...\n\nAuthenticate\n\n```\nvault write totp/code/seth code=...\n```\n\n\n## Plugin\n\nVault can be extended with plugins. A popular third-party plugin is a plugin\nthat generates passwords and passphrases for use on websites similar to\n1Password or LastPass called \"vault-secrets-gen\".\n\nNote that the plugin is \"enabled\" or \"mounted\" at `gen/`. That means all\nrequests to `gen/` go to the plugin. The plugin defines the supported paths.\n\nRun the script:\n\n```\n./scripts/setup-plugin.sh\n```\n\nTo generate a new password:\n\n```\nvault write gen/password length=64\n```\n\nTo generate a random passphrase using the diceware algorithm:\n\n```\nvault write -f gen/passphrase words=6\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsethvargo%2Fvault-demo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsethvargo%2Fvault-demo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsethvargo%2Fvault-demo/lists"}