This guide will demonstrate Vault's GCP IAM authentication method:
- The client generates a signed JWT using the IAM projects.serviceAccounts.signJwt method. For examples of how to do this, see the Obtaining JWT Tokens section.
- The client sends this signed JWT to Vault along with a role name.
- Vault extracts the kid header value, which contains the ID of the key-pair used to generate the JWT, and the sub ID/email to find the service account key. If the service account does not exist or the key is not linked to the service account, Vault denies authentication.
- Vault authorizes the confirmed service account against the given role. If that is successful, a Vault token with the proper policies is returned. https://www.vaultproject.io/docs/auth/gcp.html#iam-login
The project will create the following resources in GCP:
- vault-gcp-iam-demo-[abc] - A project with a random generated name to assosiate all the resources to
- vaultadmin - A Service Account with the iam.serviceAccountKeyAdmin - Vault will use this to check other service account credentials
- alice-account - A Service Account bound to the backend
- bob-account - A Service Account not bound to the backend
It will also create two credential JSON files used for the login step.
We will then create the following Vault install and configuration using the vault-server:
- An initalized vault instance
- One secret in the K/V store under
secret/test/mysecret
- One secret in the K/V store under
secret/prod/mysecret
- A policy for access to that one secret called
reader
with permissions to read that secret - An auth policy tied to that reader policy that uses GCP IAM tied to the alice service account eg.
alice-account@vaultguides-gcpiam-ee.iam.gserviceaccount.com
https://www.vaultproject.io/docs/auth/gcp.html https://www.vaultproject.io/api/auth/gcp/index.html
The code in this repository is for reference only. It is meant to illustrate a few of the requirements for using the GCP IAM authentication method.
Install gcloud
With Brew:
brew install gcloud
Or with the installer:
curl https://sdk.cloud.google.com |
exec -l $SHELL
gcloud init
Configure authentication:
gcloud auth login
gcloud auth application-default login
Export your billing and organisation settings:
gcloud organizations list
gcloud beta billing accounts list
export TF_VAR_org_id=<Organisation ID>
export TF_VAR_billing_account=<Billing Account ID>
Run terraform:
terraform init
terraform plan
terraform apply
Run a local Vault instance in a new terminal in dev mode:
$ vault server -dev &
Export the root token and address
export VAULT_ADDR='http://127.0.0.1:8200'
export VAULT_TOKEN='s.F7G0fS7FqlCgkKHe0JWPfD6u'
Configure Vault with Terraform code:
cd vault/
terraform plan
terraform apply
cd ..
$ unset VAULT_TOKEN
$ vault login -method=gcp \
role="web" \
credentials=@alice-credentials.json \
project="$(terraform output project_id)" \
service_account="$(terraform output alice_account_email)"
Then try and lookup the demo secret:
$ vault kv get secret/test/mysecret
====== Metadata ======
Key Value
--- -----
created_time 2019-07-26T17:37:18.325839Z
deletion_time n/a
destroyed false
version 2
=== Data ===
Key Value
--- -----
key London
Then try and lookup the forbidden prod secret:
$ vault kv get secret/prod/mysecret
Error reading secret/data/prod/mysecret: Error making API request.
URL: GET http://127.0.0.1:8200/v1/secret/data/prod/mysecret
Code: 403. Errors:
* 1 error occurred:
* permission denied
Since we bound the auth endpoint to just Bob's account, this will fail:
$ unset VAULT_TOKEN
$ vault login -method=gcp \
role="web" \
credentials=@bob-credentials.json \
project="$(terraform output project_id)" \
service_account="$(terraform output bob_account_email)"
Error authenticating: Error making API request.
URL: PUT http://127.0.0.1:8200/v1/auth/gcp/login
Code: 400. Errors:
* service account bob-acount@vaultguides-gcpiam-ee.iam.gserviceaccount.com (id: 103413538402565467997) is not authorized for role
If we were to change the bound_service_accounts
to *
or all, or a comma seperated list including Bob, they would also be able to login.