a379989da4
* Consistently use "Google Cloud" where appropriate * Update GCP docs This updates the GCP docs to use the new updated fields that will be present in the next release of the plugin as well as fixes up some inconsistencies between the GCP docs and other auth method documentation.
430 lines
15 KiB
Markdown
430 lines
15 KiB
Markdown
---
|
|
layout: "docs"
|
|
page_title: "Google Cloud - Secrets Engines"
|
|
sidebar_current: "docs-secrets-gcp"
|
|
description: |-
|
|
The Google Cloud secrets engine for Vault dynamically generates Google Cloud
|
|
service account keys and OAuth tokens based on IAM policies.
|
|
---
|
|
|
|
# Google Cloud Secrets Engine
|
|
|
|
The Google Cloud Vault secrets engine dynamically generates Google Cloud service
|
|
account keys and OAuth tokens based on IAM policies. This enables users to gain
|
|
access to Google Cloud resources without needing to create or manage a dedicated
|
|
service account.
|
|
|
|
The benefits of using this secrets engine to manage Google Cloud IAM service accounts are:
|
|
|
|
- **Automatic cleanup of GCP IAM service account keys** - each Service Account
|
|
key is associated with a Vault lease. When the lease expires (either during
|
|
normal revocation or through early revocation), the service account key is
|
|
automatically revoked.
|
|
|
|
- **Quick, short-term access** - users do not need to create new GCP Service
|
|
Accounts for short-term or one-off access (such as batch jobs or quick
|
|
introspection).
|
|
|
|
- **Multi-cloud and hybrid cloud applications** - users authenticate to Vault
|
|
using a central identity service (such as LDAP) and generate GCP credentials
|
|
without the need to create or manage a new Service Account for that user.
|
|
|
|
## Setup
|
|
|
|
Most secrets engines must be configured in advance before they can perform their
|
|
functions. These steps are usually completed by an operator or configuration
|
|
management tool.
|
|
|
|
1. Enable the Google Cloud secrets engine:
|
|
|
|
```text
|
|
$ vault secrets enable gcp
|
|
Success! Enabled the gcp secrets engine at: gcp/
|
|
```
|
|
|
|
By default, the secrets engine will mount at the name of the engine. To
|
|
enable the secrets engine at a different path, use the `-path` argument.
|
|
|
|
1. Configure the secrets engine with account credentials and optionally tune the
|
|
default TTLs:
|
|
|
|
```text
|
|
$ vault write gcp/config \
|
|
credentials=@my-credentials.json \
|
|
ttl=4h \
|
|
max_ttl=30m
|
|
Success! Data written to: gcp/config
|
|
```
|
|
|
|
If you are running Vault from inside [Google Compute Engine][gce] or [Google
|
|
Kubernetes Engine][gke], the instance or pod service account can be used in
|
|
place or specifying the credentials JSON file. For more information on authentication, see the [authentication section](#authentication) below.
|
|
|
|
1. Configure a roleset. Rolesets determine the permissions that Service Account
|
|
credentials generated by Vault will have on GCP resources.
|
|
|
|
To configure a roleset that generates OAuth2 access tokens (preferred):
|
|
|
|
```text
|
|
$ vault write gcp/roleset/my-token-roleset \
|
|
project="my-project" \
|
|
secret_type="access_token" \
|
|
token_scopes="https://www.googleapis.com/auth/cloud-platform" \
|
|
bindings=-<<EOF
|
|
resource "projects/my-project" {
|
|
roles = ["roles/viewer"]
|
|
}
|
|
EOF
|
|
```
|
|
|
|
To configure a roleset that generates GCP Service Account keys:
|
|
|
|
```text
|
|
$ vault write gcp/roleset/my-key-roleset \
|
|
project="my-project" \
|
|
secret_type="service_account_key" \
|
|
bindings=-<<EOF
|
|
resource "projects/my-project" {
|
|
roles = ["roles/viewer"]
|
|
}
|
|
EOF
|
|
```
|
|
|
|
For more information on role bindings and sample role bindings, please see
|
|
the [roleset bindings](#roleset-bindings) section below.
|
|
|
|
For more information on the differences between OAuth2 access tokens and
|
|
Service Account keys, see the [things to note](#things-to-note) section
|
|
below.
|
|
|
|
## Usage
|
|
|
|
After the secrets engine is configured and a user/machine has a Vault token with
|
|
the proper permission, it can generate credentials. Depending on how the roleset
|
|
was configured, you can generate OAuth2 tokens or service account keys.
|
|
|
|
### Access Tokens
|
|
|
|
To generate OAuth2 tokens, read from `gcp/token/...`. The roleset must have been
|
|
created as type `access_token`:
|
|
|
|
```text
|
|
$ vault read gcp/token/my-token-roleset
|
|
|
|
Key Value
|
|
--- -----
|
|
lease_id gcp/token/my-token-roleset/a8e792ec-9080...
|
|
lease_duration 60m
|
|
lease_renewable false
|
|
token ya29.c.Elq3BWCRTcuzAyjYDlJZ2tA1zx_7O5AOL...
|
|
```
|
|
|
|
This endpoint generates a non-renewable OAuth2 access token with the specified TTL. The `token` is a GCP OAuth2 access token that can be used as a Bearer token as part of an API call to Google Cloud.
|
|
|
|
```sh
|
|
$ curl -H "Authorization: Bearer ya29.c.Elq3BWCRTcuzAyjYDlJZ2tA1zx_7O5AOL..."
|
|
```
|
|
|
|
### Service Account Keys
|
|
|
|
To generate service account keys, read from `gcp/key/...`. The roleset must have
|
|
been created as type `service_account_key`:
|
|
|
|
```text
|
|
$ vault read gcp/key/my-key-roleset
|
|
|
|
Key Value
|
|
--- -----
|
|
lease_id gcp/key/my-key-roleset/ce563a99-5e55-389b...
|
|
lease_duration 30m
|
|
lease_renewable true
|
|
key_algorithm KEY_ALG_RSA_2048
|
|
key_type TYPE_GOOGLE_CREDENTIALS_FILE
|
|
private_key_data ewogICJ0eXBlIjogInNlcnZpY2VfYWNjb3VudCIsC...
|
|
```
|
|
|
|
This endpoint generates a new [GCP IAM service account key][iam-keys] associated
|
|
with the roleset's Service Account. When the lease expires (or is revoked
|
|
early), the Service Account key will be deleted.
|
|
|
|
**There is a default limit of 10 keys per Service Account.** For more
|
|
information on this limit and recommended mitigation, please see the [things to
|
|
note](#things-to-note) section below.
|
|
|
|
## Roleset Bindings
|
|
|
|
Roleset bindings define a list of resources and the associated IAM roles on that
|
|
resource. Roleset bindings are used as the `binding` argument when creating or
|
|
updating a rolset and are specified in the following format using HCL:
|
|
|
|
```hcl
|
|
resource NAME {
|
|
roles = [ROLE, [ROLE...]]
|
|
}
|
|
```
|
|
|
|
For example:
|
|
|
|
```hcl
|
|
resource "buckets/my-bucket" {
|
|
roles = [
|
|
"roles/storage.objectAdmin",
|
|
"roles/storage.legacyBucketReader",
|
|
]
|
|
}
|
|
```
|
|
|
|
The top-level `resource` block defines the resource or resource path for which
|
|
IAM policy information will be bound. The resource path may be specified in a
|
|
few different formats:
|
|
|
|
- **Project-level self-link** - a URI with scheme and host, generally
|
|
corresponding to the `self_link` attribute of a resource in GCP. This must
|
|
include the resource nested in the parent project.
|
|
|
|
```text
|
|
# compute alpha zome
|
|
https://www.googleapis.com/compute/alpha/projects/my-project/zones/us-central1-c
|
|
```
|
|
|
|
- **Full resource name** - a schema-less URI consisting of a DNS-compatible API
|
|
service name and resource path. See the [full resource name API
|
|
documentation][resource-name-full] for more information.
|
|
|
|
```text
|
|
# Compute snapshot
|
|
//compute.googleapis.com/project/my-project/snapshots/my-compute-snapshot
|
|
|
|
# Pubsub snapshot
|
|
//pubsub.googleapis.com/project/my-project/snapshots/my-pubsub-snapshot
|
|
```
|
|
|
|
- **Relative resource name** - A path-noscheme URI path, usually as accepted by
|
|
the API. Use this if the version or service are apparent from the resource
|
|
type. Please see the [relative resource name API
|
|
documentation][resource-name-relative] for more information.
|
|
|
|
```text
|
|
# Storage bucket objects
|
|
buckets/my-bucket
|
|
buckets/my-bucket/objects/my-object
|
|
|
|
# PubSub topics
|
|
projects/my-project/topics/my-pubsub-topic
|
|
```
|
|
|
|
The nested `roles` attribute is an array of strings names of [GCP IAM
|
|
roles][iam-roles]. The roles may be specified in the following formats:
|
|
|
|
- **Global role name** - these are global roles built into Google Cloud. For the
|
|
full list of available roles, please see the [list of predefined GCP
|
|
roles][predefined-roles].
|
|
|
|
```text
|
|
roles/viewer
|
|
roles/bigquery.user
|
|
roles/billing.admin
|
|
```
|
|
|
|
- **Organization-level custom role** - these are roles that are created at the
|
|
organization level by organization owners.
|
|
|
|
```text
|
|
organizations/my-organization/roles/my-custom-role
|
|
```
|
|
|
|
For more information, please see the documentation on [GCP custom
|
|
roles][custom-roles].
|
|
|
|
- **Project-level custom role** - these are roles that are created at a
|
|
per-project level by project owners.
|
|
|
|
```text
|
|
projects/my-project/roles/my-custom-role
|
|
```
|
|
|
|
For more information, please see the documentation on [GCP custom
|
|
roles][custom-roles].
|
|
|
|
|
|
## Authentication
|
|
|
|
The Google Cloud Vault secrets backend uses the official Google Cloud Golang
|
|
SDK. This means it supports the common ways of [providing credentials to Google
|
|
Cloud][cloud-creds]. In addition to specifying `credentials` directly via Vault
|
|
configuration, you can also get configuration from the following values **on the
|
|
Vault server**:
|
|
|
|
1. The environment variables `GOOGLE_APPLICATION_CREDENTIALS`. This is specified
|
|
as the **path** to a Google Cloud credentials file, typically for a service
|
|
account. If this environment variable is present, the resulting credentials are
|
|
used. If the credentials are invalid, an error is returned.
|
|
|
|
1. Default instance credentials. When no environment variable is present, the
|
|
default service account credentials are used. This is useful when running Vault
|
|
on [Google Compute Engine][gce] or [Google Kubernetes Engine][gke]
|
|
|
|
For more information on service accounts, please see the [Google Cloud Service
|
|
Accounts documentation][service-accounts].
|
|
|
|
To use this storage backend, the service account must have the following
|
|
minimum scope(s):
|
|
|
|
```text
|
|
https://www.googleapis.com/auth/cloud-platform
|
|
https://www.googleapis.com/auth/iam
|
|
```
|
|
|
|
### Required Permissions
|
|
|
|
The credentials given to Vault must have the following permissions:
|
|
|
|
```text
|
|
# Service Account + Key Admin
|
|
iam.serviceAccounts.create
|
|
iam.serviceAccounts.delete
|
|
iam.serviceAccounts.get
|
|
iam.serviceAccounts.list
|
|
iam.serviceAccounts.update
|
|
iam.serviceAccountKeys.create
|
|
iam.serviceAccountKeys.delete
|
|
iam.serviceAccountKeys.get
|
|
iam.serviceAccountKeys.list
|
|
|
|
# IAM Policy Changes
|
|
<service>.<resource>.getIamPolicy
|
|
<service>.<resource>.setIamPolicy
|
|
```
|
|
|
|
where `<service>` and `<resource>` correspond to permissions which will be
|
|
granted, for example:
|
|
|
|
```text
|
|
# Projects
|
|
resourcemanager.projects.getIamPolicy
|
|
resourcemanager.projects.setIamPolicy
|
|
|
|
# All compute
|
|
compute.*.getIamPolicy
|
|
compute.*.setIamPolicy
|
|
```
|
|
|
|
You can either:
|
|
|
|
- Create a [custom role][custom-roles] using these permissions, and assign this
|
|
role at a project-level
|
|
|
|
- Assign the set of roles required to get resource-specific
|
|
`getIamPolicy/setIamPolicy` permissions. At a minimum you will need to assign
|
|
`roles/iam.serviceAccountAdmin` and `roles/iam.serviceAccountKeyAdmin` so
|
|
Vault can manage service accounts and keys.
|
|
|
|
|
|
## Things to Note
|
|
|
|
### Access Tokens vs. Service Account Keys
|
|
|
|
OAuth2 access tokens are **strongly preferred** to Service Account keys, but
|
|
some Google services do not yet support OAuth2 access tokens. Due to the quotas
|
|
imposed on Service Account Keys, these keys should be strictly monitored even if
|
|
they have been associated with a Vault lease.
|
|
|
|
Even when using Vault to generate OAuth2 access tokens, Vault will still
|
|
generate a dedicated Service Account key whose private key is stored in Vault.
|
|
This private key is never accessible to other users, and the underlying key can
|
|
be rotated. See the [GCP API documentation][api] for more information on
|
|
rotation.
|
|
|
|
### Service Accounts are Tied to Rolesets
|
|
|
|
Service Accounts are created when the roleset is created (or updated) rather
|
|
than each time a secret is generated. This may be different from how other
|
|
secrets engines behave, but it is for good reasons:
|
|
|
|
- IAM Service Account creation and permission propagation can take up to 60
|
|
seconds to complete. By creating the Service Account in advance, we speed up
|
|
the timeliness of future operations and reduce the flakiness of automated
|
|
workflows.
|
|
|
|
- Each GCP project has a limit on the number of IAM Service Accounts. You can
|
|
[request additional quota][quotas]. The quota increase is processed by humans,
|
|
so it is best to request this additional quota in advance. This limit is
|
|
currently 100, **including system-managed Service Accounts**. If Service
|
|
Accounts were created per secret, this quota limit would reduce the number of
|
|
secrets that can be generated.
|
|
|
|
### Service Account Keys Have Limits
|
|
|
|
GCP IAM has a hard limit (currently 10) on the number of Service Account keys.
|
|
Attempts to generate more keys will result in an error. If you find yourself
|
|
running into this limit, consider the follwing:
|
|
|
|
- Have shorter TTLs or revoke access earlier. If you are not using past Service
|
|
Account keys, consider rotating and freeing quota earlier.
|
|
|
|
- Create additional rolesets which share the same set of permissions. Additional
|
|
rolesets can be created with the same set of permissions. This will create a
|
|
new service account and increases the number of keys you can create.
|
|
|
|
- Where possible, use OAuth2 access tokens instead of Service Account keys.
|
|
|
|
### Resources Must Exist at Roleset Creation
|
|
|
|
Because we the bindings for the Service Account are set during roleset creation,
|
|
resources that do not exist will fail the `getIamPolicy` API call.
|
|
|
|
### Roleset Creation May Partially Fail
|
|
|
|
Every Service Account creation, key creation, and IAM policy change is a GCP API
|
|
call per resource. If an API call to one of these resources fails, the roleset
|
|
creation fails and Vault will attempt to rollback.
|
|
|
|
These rollbacks are API calls, so they may also fail. The secrets engine uses a
|
|
WAL to ensure that unused bindings are cleaned up. In the case of quota limits,
|
|
you may need to clean these up manually.
|
|
|
|
### Do Not Modify Vault-owned IAM Accounts
|
|
|
|
While Vault will initially create and assign permissions to IAM service
|
|
accounts, it is possible that an external user deletes or modifies this service
|
|
account. These changes are difficult to detect, and it is best to prevent this
|
|
type of modification through IAM permissions.
|
|
|
|
Vault roleset Service Accounts will have emails in the format:
|
|
|
|
```
|
|
vault<roleset-prefix>-<creation-unix-timestamp>@...
|
|
```
|
|
|
|
Communicate with your teams (or use IAM permissions) to not modify these
|
|
resources.
|
|
|
|
|
|
## Help & Support
|
|
|
|
The Google Cloud Vault secrets engine is written as an external Vault plugin and
|
|
thus exists outside the main Vault repository. It is automatically bundled with
|
|
Vault releases, but the code is managed separately.
|
|
|
|
Please report issues, add feature requests, and submit contributions to the
|
|
[vault-plugin-secrets-gcp repo on GitHub][repo].
|
|
|
|
|
|
## API
|
|
The GCP secrets engine has a full HTTP API. Please see the [GCP secrets engine API docs][api]
|
|
for more details.
|
|
|
|
[api]: https://vaultproject.io/api/secret/gcp/index.html
|
|
[cloud-creds]: https://cloud.google.com/docs/authentication/production#providing_credentials_to_your_application
|
|
[custom-roles]: https://cloud.google.com/iam/docs/creating-custom-roles
|
|
[gce]: https://cloud.google.com/compute/
|
|
[gke]: https://cloud.google.com/kubernetes-engine/
|
|
[iam-keys]: https://cloud.google.com/iam/docs/service-accounts#service_account_keys
|
|
[iam-roles]: https://cloud.google.com/iam/docs/understanding-roles
|
|
[predefined-roles]: https://cloud.google.com/iam/docs/understanding-roles#predefined_roles
|
|
[repo]: https://github.com/hashicorp/vault-plugin-secrets-gcp
|
|
[resource-name-full]: https://cloud.google.com/apis/design/resource_names#full_resource_name
|
|
[resource-name-relative]: https://cloud.google.com/apis/design/resource_names#relative_resource_name
|
|
[quotas]: https://cloud.google.com/compute/quotas
|
|
[service-accounts]: https://cloud.google.com/compute/docs/access/service-accounts
|