All Projects → kelseyhightower → Serverless Vault With Cloud Run

kelseyhightower / Serverless Vault With Cloud Run

Licence: apache-2.0
Guide to running Vault on Cloud Run

Programming Languages

shell
77523 projects

Projects that are alternatives of or similar to Serverless Vault With Cloud Run

Retinal
🏙 Retinal is a Serverless AWS Lambda service for resizing images on-demand or event-triggered
Stars: ✭ 208 (-7.56%)
Mutual labels:  serverless
Openapi Backend
Build, Validate, Route, Authenticate and Mock using OpenAPI
Stars: ✭ 216 (-4%)
Mutual labels:  serverless
Nstack
Type-safe, composable microservices for data analytics
Stars: ✭ 219 (-2.67%)
Mutual labels:  serverless
Vsh
vsh - HashiCorp Vault interactive shell and cli tool
Stars: ✭ 209 (-7.11%)
Mutual labels:  vault
Hydro Serving
MLOps Platform
Stars: ✭ 213 (-5.33%)
Mutual labels:  serverless
Commerceql
UNMAINTAINED
Stars: ✭ 217 (-3.56%)
Mutual labels:  serverless
Quirrel
The Task Queueing Solution for Serverless.
Stars: ✭ 203 (-9.78%)
Mutual labels:  serverless
Terracotta
A light-weight, versatile XYZ tile server, built with Flask and Rasterio 🌍
Stars: ✭ 220 (-2.22%)
Mutual labels:  serverless
Serverless Azure Functions
Serverless Azure Functions Plugin – Add Azure Functions support to the Serverless Framework
Stars: ✭ 213 (-5.33%)
Mutual labels:  serverless
Spec
CloudEvents Specification
Stars: ✭ 3,025 (+1244.44%)
Mutual labels:  serverless
Yoyo
A dead simple comment engine built on top of AWS lambda and React, alternative comment service to Disqus.
Stars: ✭ 210 (-6.67%)
Mutual labels:  serverless
Hydrogen Demo
微信小程序 demo for 知晓云 Serverless SDK
Stars: ✭ 211 (-6.22%)
Mutual labels:  serverless
Eventsource
Serverless Go event sourcing library built on top of dynamodb
Stars: ✭ 217 (-3.56%)
Mutual labels:  serverless
Stacks Blockchain
The Stacks 2.0 blockchain implementation
Stars: ✭ 2,549 (+1032.89%)
Mutual labels:  serverless
Serverless Analytics
Track website visitors with Serverless Analytics using Kinesis, Lambda, and TypeScript.
Stars: ✭ 219 (-2.67%)
Mutual labels:  serverless
Source Code Reading Notes
源码阅读笔记
Stars: ✭ 207 (-8%)
Mutual labels:  serverless
Bitwarden Serverless
Implementation of the Bitwarden API using an AWS serverless stack
Stars: ✭ 217 (-3.56%)
Mutual labels:  serverless
Aws Lambda Haskell Runtime
⚡Haskell runtime for AWS Lambda
Stars: ✭ 223 (-0.89%)
Mutual labels:  serverless
Ffmpeg Aws Lambda Layer
FFmpeg/FFprobe AWS Lambda layer
Stars: ✭ 222 (-1.33%)
Mutual labels:  serverless
Serverless Slack App
A Serverless.js Slack App Boilerplate with OAuth and Bot actions
Stars: ✭ 217 (-3.56%)
Mutual labels:  serverless

Serverless Vault with Cloud Run

This tutorial walks you through deploying Hashicorp's Vault on Cloud Run, Google Cloud's container based Serverless compute platform.

Serverless Vault Architecture

Rational

Vault 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 and Google Cloud Storage to protect and store its data, and Cloud Run to serve it and capture audit logs.

While 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 to serve concurrent request at the lowest latency possible. Cloud Run automatically captures Vault's audit logs and sends them to Cloud Logging for centralized storage and analysis.

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.

Tutorial

Create a new Google Cloud project:

gcloud projects create \
  --name vault-on-cloud-run \
  --set-as-default

Type y at the prompt and press enter:

No project id provided.

Use [vault-on-cloud-run-XXXXXX] as project id (Y/n)?  y

Before you can continue you must enable billing on the project to enable the use of Cloud KMS as an auto-unseal mechanism.

To streamline the rest of the tutorial define the key configuration settings and assign them to environment variables:

PROJECT_ID=$(gcloud config get-value project)

PROJECT_ID holds the project id generated at the start of the tutorial.

GCS_BUCKET_NAME="gs://${PROJECT_ID}-data"

GCS_BUCKET_NAME holds the Google Cloud Storage bucket name used to persist Vault's data.

SERVICE_ACCOUNT_EMAIL="[email protected]${PROJECT_ID}.iam.gserviceaccount.com"

SERVICE_ACCOUNT_EMAIL holds the Google Cloud IAM email address representing the vault-server service account.

CURRENT_USER_EMAIL=$(gcloud config list account --format "value(core.account)")

CURRENT_USER_EMAIL holds the email address representing the current logged in Google Cloud user.

Enable the Cloud KMS, Cloud Run, and Cloud Storage APIs:

gcloud services enable --async \
  cloudkms.googleapis.com \
  run.googleapis.com \
  storage.googleapis.com

Create a GCS storage bucket to hold Vault's encrypted data:

gsutil mb ${GCS_BUCKET_NAME}
Creating gs://vault-on-cloud-run-XXXXXX-data/...

Create a service account for the Vault server:

gcloud iam service-accounts create vault-server

Grant the necessary permissions on GCS storage bucket for the vault-server service account:

gsutil iam ch \
  serviceAccount:${SERVICE_ACCOUNT_EMAIL}:objectAdmin \
  ${GCS_BUCKET_NAME}

Create a Cloud KMS key ring that will be used to hold Vault seal encryption key:

gcloud kms keyrings create "vault-server" \
  --location "global"

Create the Cloud KMS encryption key that will be used to encrypt and decrypt the Vault master key:

gcloud kms keys create "seal" \
  --location "global" \
  --keyring "vault-server" \
  --purpose "encryption"

Grant the necessary permissions on the seal Cloud KMS encryption key for the vault-server service account:

gcloud kms keys add-iam-policy-binding seal \
  --keyring "vault-server" \
  --location "global" \
  --member serviceAccount:${SERVICE_ACCOUNT_EMAIL} \
  --role roles/cloudkms.cryptoKeyEncrypterDecrypter

Deploy the vault-server Cloud Run service:

The initial deployment will be made private to prevent someone else from initializing the Vault server. Clients will need to provide authentication credentials 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.

gcloud beta run deploy vault-server \
  --no-allow-unauthenticated \
  --concurrency 50 \
  --cpu 2 \
  --image gcr.io/hightowerlabs/vault:run \
  --memory '2G' \
  --min-instances 1 \
  --max-instances 1 \
  --platform managed \
  --port 8200 \
  --service-account ${SERVICE_ACCOUNT_EMAIL} \
  --set-env-vars="GOOGLE_PROJECT=${PROJECT_ID},GOOGLE_STORAGE_BUCKET=${GCS_BUCKET_NAME}" \
  --timeout 300 \
  --region us-west1

Grant permission to the current logged in GCP user to invoke the vault-server Cloud Run service:

gcloud run services add-iam-policy-binding vault-server \
  --member="user:${CURRENT_USER_EMAIL}" \
  --role='roles/run.invoker' \
  --platform managed \
  --region us-west1

Retrieve the vault-server service URL:

VAULT_SERVICE_URL=$(gcloud run services describe vault-server \
  --platform managed \
  --region us-west1 \
  --format 'value(status.url)')

Use curl to retrieve the status of the Vault server:

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.

curl -s -X GET \
  ${VAULT_SERVICE_URL}/v1/sys/seal-status \
  -H "Authorization: Bearer $(gcloud auth print-identity-token)"
{
  "type": "gcpckms",
  "initialized": false,
  "sealed": true,
  "t": 0,
  "n": 0,
  "progress": 0,
  "nonce": "",
  "version": "1.6.0",
  "migration": false,
  "recovery_seal": true,
  "storage_type": "gcs"
}

From the output above you can see that the Vault server has not been initialized and is currently sealed. Use the curl command to initialize the Vault server:

cat <<EOF > init.json
{
  "recovery_shares": 1,
  "recovery_threshold": 1,
  "secret_shares": 1,
  "secret_threshold": 1,
  "stored_share": 1
}
EOF
curl -s -X PUT \
  ${VAULT_SERVICE_URL}/v1/sys/init \
  -H "Authorization: Bearer $(gcloud auth print-identity-token)" \
  --data @init.json
{
  "keys": [],
  "keys_base64": [],
  "recovery_keys": [
    "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
  ],
  "recovery_keys_base64": [
    "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
  ],
  "root_token": "X.XXXXXXXXXXXXXXXXXXXXXXXX"
}

At 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:

gsutil ls ${GCS_BUCKET_NAME}
gs://vault-on-cloud-run-XXXXXX-data/core/
gs://vault-on-cloud-run-XXXXXX-data/logical/
gs://vault-on-cloud-run-XXXXXX-data/sys/

Now that Vault has been initialized make the vault-server service public:

Requests to Vault will no longer be authenticated by the Cloud Run control plane. Requests will be authenticated directly by Vault.

gcloud beta run deploy vault-server \
  --allow-unauthenticated \
  --concurrency 50 \
  --cpu 2 \
  --image gcr.io/hightowerlabs/vault:run \
  --memory '2G' \
  --min-instances 1 \
  --max-instances 1 \
  --platform managed \
  --port 8200 \
  --service-account ${SERVICE_ACCOUNT_EMAIL} \
  --set-env-vars="GOOGLE_PROJECT=${PROJECT_ID},GOOGLE_STORAGE_BUCKET=${GCS_BUCKET_NAME}" \
  --timeout 300 \
  --region us-west1

At this point Vault is up and running and can be configured using the Vault UI by visiting the vault-server service URL in browser:

gcloud run services describe vault-server \
  --platform managed \
  --region us-west1 \
  --format 'value(status.url)'

You can also use the vault command line tool as described in the next section.

Retrieve the Vault Server Status Using the Vault Client

Download the Vault binary and add it to your path:

vault version
Vault v1.6.0 (7ce0bd9691998e0443bc77e98b1e2a4ab1e965d4)

Configure the vault CLI to use the vault-server Cloud Run service URL by setting the VAULT_ADDR environment variable:

VAULT_ADDR=$(gcloud run services describe vault-server \
  --platform managed \
  --region us-west1 \
  --format 'value(status.url)')

Retrieve the status of the remote Vault server:

vault status
Key                      Value
---                      -----
Recovery Seal Type       shamir
Initialized              true
Sealed                   false
Total Recovery Shares    1
Threshold                1
Version                  1.6.0
Storage Type             gcs
Cluster Name             vault-cluster-XXXXXXXX
Cluster ID               XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
HA Enabled               false

Clean Up

gcloud projects delete ${PROJECT_ID}
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].