{"id":13637954,"url":"https://github.com/kelseyhightower/serverless-vault-with-cloud-run","last_synced_at":"2025-04-06T09:10:58.067Z","repository":{"id":38541106,"uuid":"320981352","full_name":"kelseyhightower/serverless-vault-with-cloud-run","owner":"kelseyhightower","description":"Guide to running Vault on Cloud Run","archived":false,"fork":false,"pushed_at":"2022-04-28T16:47:21.000Z","size":210,"stargazers_count":405,"open_issues_count":5,"forks_count":47,"subscribers_count":15,"default_branch":"main","last_synced_at":"2025-03-30T08:11:18.065Z","etag":null,"topics":["cloudrun","serverless","vault"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kelseyhightower.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-12-13T04:14:54.000Z","updated_at":"2025-03-27T12:31:29.000Z","dependencies_parsed_at":"2022-08-03T06:30:29.454Z","dependency_job_id":null,"html_url":"https://github.com/kelseyhightower/serverless-vault-with-cloud-run","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/kelseyhightower%2Fserverless-vault-with-cloud-run","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kelseyhightower%2Fserverless-vault-with-cloud-run/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kelseyhightower%2Fserverless-vault-with-cloud-run/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kelseyhightower%2Fserverless-vault-with-cloud-run/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kelseyhightower","download_url":"https://codeload.github.com/kelseyhightower/serverless-vault-with-cloud-run/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247457803,"owners_count":20941906,"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":["cloudrun","serverless","vault"],"created_at":"2024-08-02T01:00:37.468Z","updated_at":"2025-04-06T09:10:58.048Z","avatar_url":"https://github.com/kelseyhightower.png","language":"Shell","funding_links":[],"categories":["Tutorials","Shell"],"sub_categories":["Security"],"readme":"# Serverless Vault with Cloud Run\n\nThis tutorial walks you through deploying Hashicorp's [Vault](https://www.vaultproject.io) on [Cloud Run](https://cloud.google.com/run), Google Cloud's container based Serverless compute platform.\n\n![Serverless Vault Architecture](serverless-vault.png)\n\n## Rational\n\nVault is a tool for encrypting data, managing secrets, and auditing access to them. Vault should be deployed to a secure and highly available environment to ensure applications have reliable access to secrets and credentials. Vault can leverage managed services such as [Cloud KMS](https://cloud.google.com/security-key-management) and [Google Cloud Storage](https://cloud.google.com/storage) to protect and store its data, and [Cloud Run](https://cloud.google.com/run) to serve it and capture audit logs.\n\nWhile Vault can be deployed to Kubernetes, or a virtual machine, Cloud Run reduces operational complexity by delegating infrastructure management to the cloud provider. Cloud Run can scale Vault to zero when not in use, or be configured to [keep a single instance available](https://cloud.google.com/run/docs/configuring/min-instances) to serve [concurrent request](https://cloud.google.com/run/docs/configuring/concurrency) at the lowest latency possible. Cloud Run automatically captures Vault's audit logs and sends them to [Cloud Logging](https://cloud.google.com/logging/docs) for centralized storage and analysis.\n\n\u003e Cloud Run can also be configured to ensure only one instance of Vault is running at a given time. See the Cloud Run [maximum instances docs](https://cloud.google.com/run/docs/configuring/max-instances).\n\n## Tutorial\n\nCreate a new Google Cloud project:\n\n```\ngcloud projects create \\\n  --name vault-on-cloud-run \\\n  --set-as-default\n```\n\nType `y` at the prompt and press `enter`:\n\n```\nNo project id provided.\n\nUse [vault-on-cloud-run-XXXXXX] as project id (Y/n)?  y\n```\n\nBefore you can continue you must [enable billing](https://cloud.google.com/billing/docs/how-to/modify-project) on the project to enable the use of Cloud KMS as an [auto-unseal](https://learn.hashicorp.com/tutorials/vault/autounseal-gcp-kms) mechanism.\n\nTo streamline the rest of the tutorial define the key configuration settings and assign them to environment variables:\n\n```\nPROJECT_ID=$(gcloud config get-value project)\n```\n\u003e `PROJECT_ID` holds the project id generated at the start of the tutorial.\n\n```\nGCS_BUCKET_NAME=\"${PROJECT_ID}-data\"\n```\n\n\u003e `GCS_BUCKET_NAME` holds the Google Cloud Storage bucket name used to persist Vault's data.\n\n```\nSERVICE_ACCOUNT_EMAIL=\"vault-server@${PROJECT_ID}.iam.gserviceaccount.com\"\n```\n\n\u003e `SERVICE_ACCOUNT_EMAIL` holds the Google Cloud IAM email address representing the `vault-server` service account.\n\n```\nCURRENT_USER_EMAIL=$(gcloud config list account --format \"value(core.account)\")\n```\n\n\u003e `CURRENT_USER_EMAIL` holds the email address representing the current logged in Google Cloud user.\n\n```\nREGION=us-west1\n```\n\n\u003e `REGION` holds the region in which to deploy the vault-server.\n\n\nEnable the Cloud KMS, Cloud Run, Cloud Storage, and Secret Manager APIs:\n\n```\ngcloud services enable --async \\\n  cloudkms.googleapis.com \\\n  run.googleapis.com \\\n  secretmanager.googleapis.com \\\n  storage.googleapis.com\n```\n\nCreate a service account for the Vault server:\n\n```\ngcloud iam service-accounts create vault-server\n```\n\nCreate a GCS storage bucket to hold Vault's encrypted data:\n\n```\ngsutil mb gs://${GCS_BUCKET_NAME}\n```\n```\nCreating gs://vault-on-cloud-run-XXXXXX-data/...\n```\n\nGrant the necessary permissions on GCS storage bucket for the `vault-server` service account:\n\n```\ngsutil iam ch \\\n  serviceAccount:${SERVICE_ACCOUNT_EMAIL}:objectAdmin \\\n  gs://${GCS_BUCKET_NAME}\n```\n\nStore the vault server config file in [Secret Manager](https://cloud.google.com/secret-manager):\n\n```\ngcloud secrets create vault-server-config \\\n  --replication-policy automatic \\\n  --data-file vault-server.hcl\n```\n\nGrant access to the `vault-server-config` secret to the `vault-server` service account:\n\n```\ngcloud secrets add-iam-policy-binding vault-server-config \\\n  --member \"serviceAccount:${SERVICE_ACCOUNT_EMAIL}\" \\\n  --role \"roles/secretmanager.secretAccessor\"\n```\n\nCreate a Cloud KMS key ring that will be used to hold Vault `seal` encryption key:\n\n```\ngcloud kms keyrings create \"vault-server\" \\\n  --location \"global\"\n```\n\nCreate the Cloud KMS encryption key that will be used to [encrypt and decrypt the Vault master key](https://www.vaultproject.io/docs/configuration/seal/gcpckms):\n\n```\ngcloud kms keys create \"seal\" \\\n  --location \"global\" \\\n  --keyring \"vault-server\" \\\n  --purpose \"encryption\"\n```\n\nGrant the necessary permissions on the `seal` Cloud KMS encryption key for the `vault-server` service account:\n\n```\ngcloud kms keys add-iam-policy-binding seal \\\n  --keyring \"vault-server\" \\\n  --location \"global\" \\\n  --member serviceAccount:${SERVICE_ACCOUNT_EMAIL} \\\n  --role roles/cloudkms.cryptoKeyEncrypterDecrypter\n```\n\nDeploy the `vault-server` Cloud Run service:\n\n\u003e The initial deployment will be made private to prevent someone else from initializing the Vault server. Clients will need to [provide authentication credentials](https://cloud.google.com/run/docs/authenticating/developers) that will be validated by the Cloud Run control plane. After Vault has been initialized the Cloud Run deployment will be updated to bypass Cloud Run authentication and delegate the authentication to Vault. \n\n```\ngcloud beta run deploy vault-server \\\n  --no-allow-unauthenticated \\\n  --concurrency 50 \\\n  --cpu 2 \\\n  --image gcr.io/hightowerlabs/vault:1.7.1 \\\n  --no-cpu-throttling \\\n  --memory '2G' \\\n  --min-instances 1 \\\n  --max-instances 1 \\\n  --platform managed \\\n  --port 8200 \\\n  --service-account ${SERVICE_ACCOUNT_EMAIL} \\\n  --set-env-vars=\"GOOGLE_PROJECT=${PROJECT_ID},GOOGLE_STORAGE_BUCKET=${GCS_BUCKET_NAME}\" \\\n  --set-secrets=\"/etc/vault/config.hcl=vault-server-config:1\" \\\n  --timeout 300 \\\n  --region ${REGION}\n```\n\nGrant permission to the current logged in GCP user to invoke the `vault-server` Cloud Run service:\n\n```\ngcloud run services add-iam-policy-binding vault-server \\\n  --member=\"user:${CURRENT_USER_EMAIL}\" \\\n  --role='roles/run.invoker' \\\n  --platform managed \\\n  --region ${REGION}\n```\n\nRetrieve the `vault-server` service URL:\n\n```\nVAULT_SERVICE_URL=$(gcloud run services describe vault-server \\\n  --platform managed \\\n  --region ${REGION} \\\n  --format 'value(status.url)')\n```\n\nUse `curl` to retrieve the status of the Vault server:\n\n\u003e The `gcloud` command can be used to generate an identity token which can be used to authenticate to the private `vault-server` Cloud Run service.\n\n```\ncurl -s -X GET \\\n  ${VAULT_SERVICE_URL}/v1/sys/seal-status \\\n  -H \"Authorization: Bearer $(gcloud auth print-identity-token)\"\n```\n\n```\n{\n  \"type\": \"gcpckms\",\n  \"initialized\": false,\n  \"sealed\": true,\n  \"t\": 0,\n  \"n\": 0,\n  \"progress\": 0,\n  \"nonce\": \"\",\n  \"version\": \"1.7.1\",\n  \"migration\": false,\n  \"recovery_seal\": true,\n  \"storage_type\": \"gcs\"\n}\n```\n\nFrom the output above you can see that the Vault server has not been [initialized](https://www.vaultproject.io/docs/commands/operator/init) and is currently [sealed](https://www.vaultproject.io/docs/concepts/seal). Use the `curl` command to initialize the Vault server:\n\n```\ncat \u003c\u003cEOF \u003e init.json\n{\n  \"recovery_shares\": 1,\n  \"recovery_threshold\": 1,\n  \"secret_shares\": 1,\n  \"secret_threshold\": 1,\n  \"stored_share\": 1\n}\nEOF\n```\n\n```\ncurl -s -X PUT \\\n  ${VAULT_SERVICE_URL}/v1/sys/init \\\n  -H \"Authorization: Bearer $(gcloud auth print-identity-token)\" \\\n  --data @init.json\n```\n\n```\n{\n  \"keys\": [],\n  \"keys_base64\": [],\n  \"recovery_keys\": [\n    \"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\"\n  ],\n  \"recovery_keys_base64\": [\n    \"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\"\n  ],\n  \"root_token\": \"X.XXXXXXXXXXXXXXXXXXXXXXXX\"\n}\n```\n\nAt this point the Vault server has been initialized. If you list the GCS storage bucket you will see a new set of directories created by Vault:\n\n```\ngsutil ls gs://${GCS_BUCKET_NAME}\n```\n```\ngs://vault-on-cloud-run-XXXXXX-data/core/\ngs://vault-on-cloud-run-XXXXXX-data/logical/\ngs://vault-on-cloud-run-XXXXXX-data/sys/\n```\n\nNow that Vault has been initialized make the `vault-server` service [public](https://cloud.google.com/run/docs/authenticating/public):\n\n\u003e Requests to Vault will no longer be authenticated by the Cloud Run control plane. Requests will be authenticated directly by Vault. \n\n```\ngcloud beta run deploy vault-server \\\n  --allow-unauthenticated \\\n  --concurrency 50 \\\n  --cpu 2 \\\n  --image gcr.io/hightowerlabs/vault:1.7.1 \\\n  --no-cpu-throttling \\\n  --memory '2G' \\\n  --min-instances 1 \\\n  --max-instances 1 \\\n  --platform managed \\\n  --port 8200 \\\n  --service-account ${SERVICE_ACCOUNT_EMAIL} \\\n  --set-env-vars=\"GOOGLE_PROJECT=${PROJECT_ID},GOOGLE_STORAGE_BUCKET=${GCS_BUCKET_NAME}\" \\\n  --set-secrets=\"/etc/vault/config.hcl=vault-server-config:1\" \\\n  --timeout 300 \\\n  --region ${REGION}\n```\n\nAt this point Vault is up and running and can be configured using the [Vault UI](https://www.vaultproject.io/docs/configuration/ui) by visiting the `vault-server` service URL in browser:\n\n```\ngcloud run services describe vault-server \\\n  --platform managed \\\n  --region ${REGION} \\\n  --format 'value(status.url)'\n```\n\nYou can also use the `vault` command line tool as described in the next section.\n\n### Retrieve the Vault Server Status Using the Vault Client\n\n[Download](https://www.vaultproject.io/downloads) the Vault binary and add it to your path:\n\n```\nvault version\n```\n\n```\nVault v1.7.1 (917142287996a005cb1ed9d96d00d06a0590e44e)\n```\n\nConfigure the vault CLI to use the `vault-server` Cloud Run service URL by setting the `VAULT_ADDR` environment variable:\n\n```\nexport VAULT_ADDR=$(gcloud run services describe vault-server \\\n  --platform managed \\\n  --region ${REGION} \\\n  --format 'value(status.url)')\n```\n\nRetrieve the status of the remote Vault server:\n\n```\nvault status\n```\n\n```\nKey                      Value\n---                      -----\nRecovery Seal Type       shamir\nInitialized              true\nSealed                   false\nTotal Recovery Shares    1\nThreshold                1\nVersion                  1.7.1\nStorage Type             gcs\nCluster Name             vault-cluster-XXXXXXXX\nCluster ID               XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\nHA Enabled               false\n```\n\n## Clean Up\n\n```\ngcloud projects delete ${PROJECT_ID}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkelseyhightower%2Fserverless-vault-with-cloud-run","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkelseyhightower%2Fserverless-vault-with-cloud-run","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkelseyhightower%2Fserverless-vault-with-cloud-run/lists"}