2017-08-16 02:03:04 +00:00
---
2020-01-18 00:18:09 +00:00
layout: docs
page_title: Google Cloud - Auth Methods
2017-08-16 02:03:04 +00:00
description: |-
2018-07-11 19:52:22 +00:00
The "gcp" auth method allows users and machines to authenticate to Vault using
Google Cloud service accounts.
2017-08-16 02:03:04 +00:00
---
2018-07-11 19:52:22 +00:00
# Google Cloud Auth Method
2017-08-16 02:03:04 +00:00
2019-01-10 18:05:21 +00:00
The `gcp` auth method allows Google Cloud Platform entities to authenticate to
Vault. Vault treats Google Cloud as a trusted third party and verifies
authenticating entities against the Google Cloud APIs. This backend allows for
authentication of:
2018-12-10 20:54:18 +00:00
2019-01-10 18:05:21 +00:00
- Google Cloud IAM service accounts
- Google Compute Engine (GCE) instances
2018-12-10 20:54:18 +00:00
2019-01-10 18:05:21 +00:00
This backend focuses on identities specific to Google _Cloud_ and does not
2022-02-17 18:01:45 +00:00
support authenticating arbitrary Google or Google Workspace users or generic OAuth
2019-01-10 18:05:21 +00:00
against Google.
2017-09-13 01:48:52 +00:00
2018-07-11 19:52:22 +00:00
This plugin is developed in a separate GitHub repository at
2019-01-10 18:05:21 +00:00
[hashicorp/vault-plugin-auth-gcp][repo],
2018-07-11 19:52:22 +00:00
but is automatically bundled in Vault releases. Please file all feature
requests, bugs, and pull requests specific to the GCP plugin under that
repository.
2017-09-13 01:48:52 +00:00
2022-06-15 17:06:58 +00:00
## Authentication
2017-09-13 01:48:52 +00:00
2019-01-10 18:05:21 +00:00
### Via the CLI Helper
2018-12-10 20:54:18 +00:00
2019-01-10 18:05:21 +00:00
Vault includes a CLI helper that obtains a signed JWT locally and sends the
2022-09-06 12:11:34 +00:00
request to Vault.
2017-09-13 01:48:52 +00:00
2020-05-21 17:18:17 +00:00
```shell-session
2022-09-06 12:11:34 +00:00
# Authentication to vault outside of Google Cloud
2018-07-11 19:52:22 +00:00
$ vault login -method=gcp \
role="my-role" \
2019-03-25 18:12:09 +00:00
service_account="authenticating-account@my-project.iam.gserviceaccount.com" \
2018-12-10 20:54:18 +00:00
jwt_exp="15m" \
2019-01-10 18:05:21 +00:00
credentials=@path/to/signer/credentials.json
2018-05-30 00:36:24 +00:00
```
2017-09-13 01:48:52 +00:00
2022-09-06 12:11:34 +00:00
```shell-session
# Authentication to vault inside of Google Cloud
$ vault login -method=gcp role="my-role"
```
2019-01-10 18:05:21 +00:00
For more usage information, run `vault auth help gcp`.
2017-09-13 01:48:52 +00:00
2022-09-06 12:11:34 +00:00
-> **Note:** The `project` parameter has been removed in Vault 1.5.9+, 1.6.5+, and 1.7.2+.
It is no longer needed for configuration and will be ignored if provided.
2019-01-10 18:05:21 +00:00
### Via the CLI
2017-09-13 01:48:52 +00:00
2020-05-21 17:18:17 +00:00
```shell-session
2019-01-10 18:05:21 +00:00
$ vault write -field=token auth/gcp/login \
role="my-role" \
jwt="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
2018-12-10 20:54:18 +00:00
```
2019-01-10 18:05:21 +00:00
See [Generating JWTs](#generating-jwts) for ways to obtain the JWT token.
2019-01-08 16:51:37 +00:00
2018-07-11 19:52:22 +00:00
### Via the API
2017-08-16 02:03:04 +00:00
2020-05-21 17:18:17 +00:00
```shell-session
2018-07-11 19:52:22 +00:00
$ curl \
--request POST \
--data '{"role":"my-role", "jwt":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."}' \
http://127.0.0.1:8200/v1/auth/gcp/login
```
2017-08-16 02:03:04 +00:00
2018-12-10 20:54:18 +00:00
See [API docs][api-docs] for expected response.
2017-08-16 02:03:04 +00:00
2018-07-11 19:52:22 +00:00
## Configuration
2017-09-13 01:48:52 +00:00
2018-07-11 19:52:22 +00:00
Auth methods must be configured in advance before users or machines can
authenticate. These steps are usually completed by an operator or configuration
management tool.
2017-09-13 01:48:52 +00:00
2018-07-11 19:52:22 +00:00
1. Enable the Google Cloud auth method:
2017-08-16 02:03:04 +00:00
2022-06-07 23:22:09 +00:00
```shell-session
2020-01-18 00:18:09 +00:00
$ vault auth enable gcp
```
2017-08-16 02:03:04 +00:00
2022-09-06 12:11:34 +00:00
1. Configure the auth method credentials if Vault is not running on Google Cloud:
2017-09-19 12:44:05 +00:00
2020-01-18 00:18:09 +00:00
```text
$ vault write auth/gcp/config \
credentials=@/path/to/credentials.json
```
2017-09-19 12:44:05 +00:00
2020-01-18 00:18:09 +00:00
If you are using instance credentials or want to specify credentials via
an environment variable, you can skip this step. To learn more, see the
2022-06-15 17:06:58 +00:00
[Google Cloud Credentials](#gcp-credentials) section below.
-> **Note**: If you're using a [Private Google Access](https://cloud.google.com/vpc/docs/configure-private-google-access)
environment, you will additionally need to configure your environment’ s custom endpoints
via the [custom_endpoint](/api-docs/auth/gcp#custom_endpoint) configuration parameter.
2017-09-19 12:44:05 +00:00
2018-07-11 19:52:22 +00:00
1. Create a named role:
2017-09-19 12:44:05 +00:00
2020-01-18 00:18:09 +00:00
For an `iam`-type role:
2017-09-19 12:44:05 +00:00
2022-06-07 23:22:09 +00:00
```shell-session
2020-01-18 00:18:09 +00:00
$ vault write auth/gcp/role/my-iam-role \
type="iam" \
policies="dev,prod" \
bound_service_accounts="my-service@my-project.iam.gserviceaccount.com"
```
2017-09-19 12:44:05 +00:00
2020-01-18 00:18:09 +00:00
For a `gce`-type role:
2017-09-19 12:44:05 +00:00
2022-06-07 23:22:09 +00:00
```shell-session
2020-01-18 00:18:09 +00:00
$ vault write auth/gcp/role/my-gce-role \
type="gce" \
policies="dev,prod" \
bound_projects="my-project1,my-project2" \
bound_zones="us-east1-b" \
2020-01-27 19:48:21 +00:00
bound_labels="foo:bar,zip:zap" \
bound_service_accounts="my-service@my-project.iam.gserviceaccount.com"
2020-01-18 00:18:09 +00:00
```
2017-09-19 12:44:05 +00:00
2020-01-27 19:48:21 +00:00
Note that `bound_service_accounts` is only required for `iam`-type roles.
2020-01-18 00:18:09 +00:00
For the complete list of configuration options for each type, please see the
[API documentation][api-docs].
2017-09-19 12:44:05 +00:00
2022-06-15 17:06:58 +00:00
## GCP Credentials
2017-08-16 02:03:04 +00:00
2018-07-11 19:52:22 +00:00
The Google Cloud Vault auth method uses the official Google Cloud Golang SDK.
This means it supports the common ways of [providing credentials to Google
Cloud][cloud-creds].
2018-05-30 00:36:24 +00:00
2018-07-11 19:52:22 +00:00
1. The environment variable `GOOGLE_APPLICATION_CREDENTIALS`. This is specified
2020-01-18 00:18:09 +00:00
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.
2017-08-16 02:03:04 +00:00
2018-07-11 19:52:22 +00:00
1. Default instance credentials. When no environment variable is present, the
2020-01-18 00:18:09 +00:00
default service account credentials are used.
2017-08-16 02:03:04 +00:00
2018-07-11 19:52:22 +00:00
For more information on service accounts, please see the [Google Cloud Service
Accounts documentation][service-accounts].
2017-09-19 12:44:05 +00:00
2019-01-10 18:05:21 +00:00
To use this auth method, the service account must have the following minimum
scope:
2017-08-16 02:03:04 +00:00
2018-07-11 19:52:22 +00:00
```text
https://www.googleapis.com/auth/cloud-platform
2017-08-16 02:03:04 +00:00
```
2019-07-01 22:13:36 +00:00
### Required GCP Permissions
2019-01-10 18:05:21 +00:00
2022-05-31 17:16:24 +00:00
#### Enabled GCP APIs
The GCP project must have the following APIs enabled:
- [iam.googleapis.com](https://console.cloud.google.com/flows/enableapi?apiid=iam.googleapis.com)
for `iam` and `gce` type roles.
- [compute.googleapis.com](https://console.cloud.google.com/flows/enableapi?apiid=compute.googleapis.com)
for `gce` type roles.
- [cloudresourcemanager.googleapis.com](https://console.cloud.google.com/flows/enableapi?apiid=cloudresourcemanager.googleapis.com)
for `iam` and `gce` type roles that set [`add_group_aliases`](/api-docs/auth/gcp#add_group_aliases) to true.
2019-07-01 22:13:36 +00:00
#### Vault Server Permissions
2022-05-31 17:16:24 +00:00
**For `iam`-type Vault roles**, the service account [`credentials`](/api-docs/auth/gcp#credentials)
given to Vault can have the following role:
2019-01-10 18:05:21 +00:00
```text
roles/iam.serviceAccountKeyAdmin
```
2022-05-31 17:16:24 +00:00
**For `gce`-type Vault roles**, the service account [`credentials`](/api-docs/auth/gcp#credentials)
given to Vault can have the following role:
2019-01-10 18:05:21 +00:00
```text
2019-07-01 22:13:36 +00:00
roles/compute.viewer
2019-01-10 18:05:21 +00:00
```
2018-12-10 20:54:18 +00:00
2019-07-01 22:13:36 +00:00
If you instead wish to create a custom role with only the exact GCP permissions
required, use the following list of permissions:
```text
iam.serviceAccounts.get
iam.serviceAccountKeys.get
compute.instances.get
compute.instanceGroups.list
```
These allow Vault to:
2020-01-18 00:18:09 +00:00
- verify the service account, either directly authenticating or associated with
2019-07-01 22:13:36 +00:00
authenticating GCE instance, exists
2020-01-18 00:18:09 +00:00
- get the corresponding public keys for verifying JWTs signed by service account
2019-07-01 22:13:36 +00:00
private keys.
2020-01-18 00:18:09 +00:00
- verify authenticating GCE instances exist
- compare bound fields for GCE roles (zone/region, labels, or membership
2019-07-01 22:13:36 +00:00
in given instance groups)
2020-04-29 16:42:59 +00:00
If you are using Group Aliases as described below, you will also need to add the
`resourcemanager.projects.get` permission.
2019-07-01 22:13:36 +00:00
#### Permissions For Authenticating Against Vault
2022-09-06 12:11:34 +00:00
If you are authenticating to Vault from Google Cloud, you can skip the following step as
Vault will generate and present the identity token of the service account configured
on the instance or the pod.
2020-01-18 00:18:09 +00:00
Note that the previously mentioned permissions are given to the _Vault servers_.
2019-07-01 22:13:36 +00:00
The IAM service account or GCE instance that is **authenticating against Vault**
must have the following role:
```text
roles/iam.serviceAccountTokenCreator
```
2018-12-10 20:54:18 +00:00
2020-07-07 23:09:12 +00:00
!> **WARNING:** Make sure this role is only applied so your service account can
impersonate itself. If this role is applied GCP project-wide, this will allow the service
account to impersonate any service account in the GCP project where it resides.
See [Managing service account impersonation](https://cloud.google.com/iam/docs/impersonating-service-accounts)
for more information.
2019-01-10 18:05:21 +00:00
## Group Aliases
2018-12-10 20:54:18 +00:00
2019-01-10 18:05:21 +00:00
As of Vault 1.0, roles can specify an `add_group_aliases` boolean parameter
that adds [group aliases][identity-group-aliases] to the auth response. These
aliases can aid in building reusable policies since they are available as
interpolated values in Vault's policy engine. Once enabled, the auth response
will include the following aliases:
2018-12-10 20:54:18 +00:00
2019-01-10 18:05:21 +00:00
```json
2018-12-10 20:54:18 +00:00
[
2019-01-10 18:05:21 +00:00
"project-$PROJECT_ID",
"folder-$SUBFOLDER_ID",
"folder-$FOLDER_ID",
"organization-$ORG_ID"
2018-12-10 20:54:18 +00:00
]
```
2020-04-29 16:42:59 +00:00
If you are using a custom role for Vault server, you will need to add the
`resourcemanager.projects.get` permission to your custom role.
2019-01-10 18:05:21 +00:00
## Implementation Details
2017-08-16 02:03:04 +00:00
2018-07-11 19:52:22 +00:00
This section describes the implementation details for how Vault communicates
with Google Cloud to authenticate and authorize JWT tokens. This information is
2018-12-10 20:54:18 +00:00
provided for those who are curious, but these details are not
2018-07-11 19:52:22 +00:00
required knowledge for using the auth method.
2017-09-19 12:44:05 +00:00
2019-01-10 18:05:21 +00:00
### IAM Login
2017-09-19 12:44:05 +00:00
2018-07-11 19:52:22 +00:00
IAM login applies only to roles of type `iam`. The Vault authentication workflow
for IAM service accounts looks like this:
2017-09-19 12:44:05 +00:00
New Docs Website (#5535)
* conversion stage 1
* correct image paths
* add sidebar title to frontmatter
* docs/concepts and docs/internals
* configuration docs and multi-level nav corrections
* commands docs, index file corrections, small item nav correction
* secrets converted
* auth
* add enterprise and agent docs
* add extra dividers
* secret section, wip
* correct sidebar nav title in front matter for apu section, start working on api items
* auth and backend, a couple directory structure fixes
* remove old docs
* intro side nav converted
* reset sidebar styles, add hashi-global-styles
* basic styling for nav sidebar
* folder collapse functionality
* patch up border length on last list item
* wip restructure for content component
* taking middleman hacking to the extreme, but its working
* small css fix
* add new mega nav
* fix a small mistake from the rebase
* fix a content resolution issue with middleman
* title a couple missing docs pages
* update deps, remove temporary markup
* community page
* footer to layout, community page css adjustments
* wip downloads page
* deps updated, downloads page ready
* fix community page
* homepage progress
* add components, adjust spacing
* docs and api landing pages
* a bunch of fixes, add docs and api landing pages
* update deps, add deploy scripts
* add readme note
* update deploy command
* overview page, index title
* Update doc fields
Note this still requires the link fields to be populated -- this is solely related to copy on the description fields
* Update api_basic_categories.yml
Updated API category descriptions. Like the document descriptions you'll still need to update the link headers to the proper target pages.
* Add bottom hero, adjust CSS, responsive friendly
* Add mega nav title
* homepage adjustments, asset boosts
* small fixes
* docs page styling fixes
* meganav title
* some category link corrections
* Update API categories page
updated to reflect the second level headings for api categories
* Update docs_detailed_categories.yml
Updated to represent the existing docs structure
* Update docs_detailed_categories.yml
* docs page data fix, extra operator page remove
* api data fix
* fix makefile
* update deps, add product subnav to docs and api landing pages
* Rearrange non-hands-on guides to _docs_
Since there is no place for these on learn.hashicorp, we'll put them
under _docs_.
* WIP Redirects for guides to docs
* content and component updates
* font weight hotfix, redirects
* fix guides and intro sidenavs
* fix some redirects
* small style tweaks
* Redirects to learn and internally to docs
* Remove redirect to `/vault`
* Remove `.html` from destination on redirects
* fix incorrect index redirect
* final touchups
* address feedback from michell for makefile and product downloads
2018-10-19 15:40:11 +00:00
[![Vault Google Cloud IAM Login Workflow](/img/vault-gcp-iam-auth-workflow.svg)](/img/vault-gcp-iam-auth-workflow.svg)
2017-08-18 20:25:52 +00:00
2021-05-11 23:57:12 +00:00
1. The client generates a signed JWT using the Service Account Credentials
[`projects.serviceAccounts.signJwt`][signjwt-method] API method. For examples
of how to do this, see the [Generating JWTs](#generating-jwts) section.
2017-08-18 20:25:52 +00:00
2020-01-18 00:18:09 +00:00
2. The client sends this signed JWT to Vault along with a role name.
2017-08-18 20:25:52 +00:00
2020-01-18 00:18:09 +00:00
3. 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.
2017-08-18 20:25:52 +00:00
2020-01-18 00:18:09 +00:00
4. Vault authorizes the confirmed service account against the given role. If
that is successful, a Vault token with the proper policies is returned.
2017-08-18 20:25:52 +00:00
2019-01-10 18:05:21 +00:00
### GCE Login
2017-08-16 02:03:04 +00:00
2018-07-11 19:52:22 +00:00
GCE login only applies to roles of type `gce` and **must be completed on an
2022-09-06 12:11:34 +00:00
infrastructure running on Google Cloud**. These steps will not work from your
local laptop or another cloud provider.
2017-08-16 02:03:04 +00:00
New Docs Website (#5535)
* conversion stage 1
* correct image paths
* add sidebar title to frontmatter
* docs/concepts and docs/internals
* configuration docs and multi-level nav corrections
* commands docs, index file corrections, small item nav correction
* secrets converted
* auth
* add enterprise and agent docs
* add extra dividers
* secret section, wip
* correct sidebar nav title in front matter for apu section, start working on api items
* auth and backend, a couple directory structure fixes
* remove old docs
* intro side nav converted
* reset sidebar styles, add hashi-global-styles
* basic styling for nav sidebar
* folder collapse functionality
* patch up border length on last list item
* wip restructure for content component
* taking middleman hacking to the extreme, but its working
* small css fix
* add new mega nav
* fix a small mistake from the rebase
* fix a content resolution issue with middleman
* title a couple missing docs pages
* update deps, remove temporary markup
* community page
* footer to layout, community page css adjustments
* wip downloads page
* deps updated, downloads page ready
* fix community page
* homepage progress
* add components, adjust spacing
* docs and api landing pages
* a bunch of fixes, add docs and api landing pages
* update deps, add deploy scripts
* add readme note
* update deploy command
* overview page, index title
* Update doc fields
Note this still requires the link fields to be populated -- this is solely related to copy on the description fields
* Update api_basic_categories.yml
Updated API category descriptions. Like the document descriptions you'll still need to update the link headers to the proper target pages.
* Add bottom hero, adjust CSS, responsive friendly
* Add mega nav title
* homepage adjustments, asset boosts
* small fixes
* docs page styling fixes
* meganav title
* some category link corrections
* Update API categories page
updated to reflect the second level headings for api categories
* Update docs_detailed_categories.yml
Updated to represent the existing docs structure
* Update docs_detailed_categories.yml
* docs page data fix, extra operator page remove
* api data fix
* fix makefile
* update deps, add product subnav to docs and api landing pages
* Rearrange non-hands-on guides to _docs_
Since there is no place for these on learn.hashicorp, we'll put them
under _docs_.
* WIP Redirects for guides to docs
* content and component updates
* font weight hotfix, redirects
* fix guides and intro sidenavs
* fix some redirects
* small style tweaks
* Redirects to learn and internally to docs
* Remove redirect to `/vault`
* Remove `.html` from destination on redirects
* fix incorrect index redirect
* final touchups
* address feedback from michell for makefile and product downloads
2018-10-19 15:40:11 +00:00
[![Vault Google Cloud GCE Login Workflow](/img/vault-gcp-gce-auth-workflow.svg)](/img/vault-gcp-gce-auth-workflow.svg)
2017-08-18 20:25:52 +00:00
2020-01-18 00:18:09 +00:00
1. The client obtains an [instance identity metadata token][instance-identity]
on a GCE instance.
2017-08-18 20:25:52 +00:00
2020-01-18 00:18:09 +00:00
2. The client sends this JWT to Vault along with a role name.
2017-08-18 20:25:52 +00:00
2020-01-18 00:18:09 +00:00
3. Vault extracts the `kid` header value, which contains the ID of the
key-pair used to generate the JWT, to find the OAuth2 public cert to verify
this JWT.
2017-08-18 20:25:52 +00:00
2020-01-18 00:18:09 +00:00
4. Vault authorizes the confirmed instance against the given role, ensuring
the instance matches the bound zones, regions, or instance groups. If that is
successful, a Vault token with the proper policies is returned.
2019-01-10 18:05:21 +00:00
## Generating JWTs
This section details the various methods and examples for obtaining JWT
tokens.
2021-05-11 23:57:12 +00:00
### Service Account Credentials API
2017-08-18 20:25:52 +00:00
2021-05-11 23:57:12 +00:00
This describes how to use the GCP Service Account Credentials [API method][signjwt-method]
directly to generate the signed JWT with the claims that Vault expects. Note the CLI
2019-01-08 16:51:37 +00:00
does this process for you and is much easier, and that there is very little
reason to do this yourself.
2017-08-18 20:25:52 +00:00
2019-01-10 18:05:21 +00:00
#### curl Example
2017-08-18 20:25:52 +00:00
2018-12-10 20:54:18 +00:00
Vault requires the following minimum claim set:
2017-09-19 12:44:05 +00:00
2018-12-10 20:54:18 +00:00
```json
2018-07-11 19:52:22 +00:00
{
2018-12-10 20:54:18 +00:00
"sub": "$SERVICE_ACCOUNT_EMAIL_OR_ID",
2018-07-11 19:52:22 +00:00
"aud": "vault/$ROLE",
2018-12-10 20:54:18 +00:00
"exp": "$EXPIRATION"
2018-07-11 19:52:22 +00:00
}
2017-08-18 20:25:52 +00:00
```
2021-05-11 23:57:12 +00:00
For the API method, providing the expiration claim `exp` is required. If it is omitted,
it will not be added automatically and Vault will deny authentication. Expiration must
be specified as a [NumericDate](https://tools.ietf.org/html/rfc7519#section-2) value
(seconds from Epoch). This value must be before the max JWT expiration allowed for a
role. This defaults to 15 minutes and cannot be more than 1 hour.
2018-07-11 19:52:22 +00:00
2022-08-22 02:15:31 +00:00
If a user generates a token that expires after 15 minutes, and the gcp role has `max_jwt_exp` set to the default, Vault will return the following error: `Expiration date must be set to no more that 15 mins in JWT_CLAIM, otherwise the login request returns error "role requires that service account JWTs expire within 900 seconds`. In this case, the user must create a new signed JWT with a shorter expiration, or set `max_jwt_exp` to a higher value in the gcp role.
2018-07-11 19:52:22 +00:00
One you have all this information, the JWT token can be signed using curl and
[oauth2l](https://github.com/google/oauth2l):
2022-06-07 23:22:09 +00:00
```shell-session
2018-07-11 19:52:22 +00:00
ROLE="my-role"
SERVICE_ACCOUNT="service-account@my-project.iam.gserviceaccount.com"
OAUTH_TOKEN="$(oauth2l header cloud-platform)"
2021-05-11 23:57:12 +00:00
EXPIRATION="<your_token_expiration>"
JWT_CLAIM="{\\\"aud\\\":\\\"vault/${ROLE}\\\", \\\"sub\\\": \\\"${SERVICE_ACCOUNT}\\\", \\\"exp\\\": ${EXPIRATION}}"
2018-07-11 19:52:22 +00:00
2022-06-07 23:22:09 +00:00
$ curl \
2018-07-11 19:52:22 +00:00
--header "${OAUTH_TOKEN}" \
--header "Content-Type: application/json" \
--request POST \
2019-01-10 18:05:21 +00:00
--data "{\"payload\": \"${JWT_CLAIM}\"}" \
2021-05-11 23:57:12 +00:00
"https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/${SERVICE_ACCOUNT}:signJwt"
2017-08-18 20:25:52 +00:00
```
2018-07-11 19:52:22 +00:00
#### gcloud Example
2017-08-18 20:25:52 +00:00
2021-05-11 23:57:12 +00:00
You can also do this through the (currently beta) gcloud command. Note that you will
be required to provide the expiration claim `exp` as a part of the JWT input to the
command.
2018-12-10 20:54:18 +00:00
2020-05-21 17:18:17 +00:00
```shell-session
2018-12-10 20:54:18 +00:00
$ gcloud beta iam service-accounts sign-jwt $INPUT_JWT_CLAIMS $OUTPUT_JWT_FILE \
2018-10-21 00:35:33 +00:00
--iam-account=service-account@my-project.iam.gserviceaccount.com \
--project=my-project
2017-08-18 20:25:52 +00:00
```
2018-07-11 19:52:22 +00:00
#### Golang Example
2017-08-18 20:25:52 +00:00
2018-07-11 19:52:22 +00:00
Read more on the
[Google Open Source blog](https://opensource.googleblog.com/2017/08/hashicorp-vault-and-google-cloud-iam.html).
2017-08-18 20:25:52 +00:00
2019-01-10 18:05:21 +00:00
### GCE
2022-09-06 12:11:34 +00:00
You can autogenerate this token in Vault versions 1.8.2 or higher.
2022-06-07 23:22:09 +00:00
GCE tokens **can only be generated from a GCE instance**.
2017-08-18 20:25:52 +00:00
2022-06-07 23:22:09 +00:00
1. Vault can automatically discover the identity token on a GCE/GKE instance. This simplifies
authenticating to Vault like so:
2017-08-18 20:25:52 +00:00
2022-06-07 23:22:09 +00:00
```shell-session
$ vault login \
-method=gcp \
role="my-gce-role"
```
1. The JWT token can also be obtained from the `"service-accounts/default/identity"` endpoint for a
instance's metadata server.
#### Curl example
```shell-session
ROLE="my-gce-role"
$ curl \
--header "Metadata-Flavor: Google" \
--get \
--data-urlencode "audience=http://vault/${ROLE}" \
--data-urlencode "format=full" \
"http://metadata/computeMetadata/v1/instance/service-accounts/default/identity"
```
2017-08-18 20:25:52 +00:00
## API
2017-08-16 02:03:04 +00:00
The GCP Auth Plugin has a full HTTP API. Please see the
2018-07-11 19:52:22 +00:00
[API docs][api-docs] for more details.
[jwt]: https://tools.ietf.org/html/rfc7519
2021-05-11 23:57:12 +00:00
[signjwt-method]: https://cloud.google.com/iam/docs/reference/credentials/rest/v1/projects.serviceAccounts/signJwt
2018-07-11 19:52:22 +00:00
[cloud-creds]: https://cloud.google.com/docs/authentication/production#providing_credentials_to_your_application
[service-accounts]: https://cloud.google.com/compute/docs/access/service-accounts
2022-03-18 01:14:48 +00:00
[api-docs]: /api-docs/auth/gcp
[identity-group-aliases]: /api-docs/secret/identity/group-alias
2018-07-11 19:52:22 +00:00
[instance-identity]: https://cloud.google.com/compute/docs/instances/verifying-instance-identity
2019-01-10 18:05:21 +00:00
[repo]: https://github.com/hashicorp/vault-plugin-auth-gcp
2021-09-18 03:51:07 +00:00
## Code Example
2022-04-26 21:12:52 +00:00
The following example demonstrates the Google Cloud auth method to authenticate
2021-09-18 03:51:07 +00:00
with Vault.
2022-04-26 21:12:52 +00:00
<CodeTabs>
2021-09-18 03:51:07 +00:00
2022-04-26 21:12:52 +00:00
<CodeBlockConfig>
2021-09-18 03:51:07 +00:00
```go
package main
import (
"context"
"fmt"
"os"
vault "github.com/hashicorp/vault/api"
2021-11-17 19:52:38 +00:00
auth "github.com/hashicorp/vault/api/auth/gcp"
2021-09-18 03:51:07 +00:00
)
2021-11-17 19:52:38 +00:00
// Fetches a key-value secret (kv-v2) after authenticating to Vault
// via GCP IAM, one of two auth methods used to authenticate with
// GCP (the other is GCE auth).
2021-09-18 03:51:07 +00:00
func getSecretWithGCPAuthIAM() (string, error) {
config := vault.DefaultConfig() // modify for more granular configuration
client, err := vault.NewClient(config)
if err != nil {
return "", fmt.Errorf("unable to initialize Vault client: %w", err)
}
2021-11-17 19:52:38 +00:00
// For IAM-style auth, the environment variable GOOGLE_APPLICATION_CREDENTIALS
// must be set with the path to a valid credentials JSON file, otherwise
// Vault will fall back to Google's default instance credentials.
2021-09-18 03:51:07 +00:00
// Learn about authenticating to GCS with service account credentials at https://cloud.google.com/docs/authentication/production
if pathToCreds := os.Getenv("GOOGLE_APPLICATION_CREDENTIALS"); pathToCreds == "" {
fmt.Printf("WARNING: Environment variable GOOGLE_APPLICATION_CREDENTIALS was not set. IAM client for JWT signing and Vault server IAM client will both fall back to default instance credentials.\n")
}
2021-11-17 19:52:38 +00:00
svcAccountEmail := fmt.Sprintf("%s@%s.iam.gserviceaccount.com", os.Getenv("GCP_SERVICE_ACCOUNT_NAME"), os.Getenv("GOOGLE_CLOUD_PROJECT"))
2021-09-18 03:51:07 +00:00
2021-11-17 19:52:38 +00:00
// We pass the auth.WithIAMAuth option to use the IAM-style authentication
// of the GCP auth backend. Otherwise, we default to using GCE-style
// authentication, which gets its credentials from the metadata server.
gcpAuth, err := auth.NewGCPAuth(
"dev-role-iam",
auth.WithIAMAuth(svcAccountEmail),
)
if err != nil {
return "", fmt.Errorf("unable to initialize GCP auth method: %w", err)
2021-09-18 03:51:07 +00:00
}
2021-11-17 19:52:38 +00:00
authInfo, err := client.Auth().Login(context.TODO(), gcpAuth)
2021-09-18 03:51:07 +00:00
if err != nil {
2021-11-17 19:52:38 +00:00
return "", fmt.Errorf("unable to login to GCP auth method: %w", err)
}
if authInfo == nil {
return "", fmt.Errorf("login response did not return client token")
2021-09-18 03:51:07 +00:00
}
2022-06-09 00:37:02 +00:00
// get secret from the default mount path for KV v2 in dev mode, "secret"
secret, err := client.KVv2("secret").Get(context.Background(), "creds")
2021-09-18 03:51:07 +00:00
if err != nil {
return "", fmt.Errorf("unable to read secret: %w", err)
}
2021-11-17 19:52:38 +00:00
// data map can contain more than one key-value pair,
// in this case we're just grabbing one of them
2022-06-09 00:37:02 +00:00
value, ok := secret.Data["password"].(string)
2021-09-18 03:51:07 +00:00
if !ok {
2022-06-09 00:37:02 +00:00
return "", fmt.Errorf("value type assertion failed: %T %#v", secret.Data["password"], secret.Data["password"])
2021-09-18 03:51:07 +00:00
}
return value, nil
}
2021-12-22 17:33:12 +00:00
2021-09-18 03:51:07 +00:00
```
</CodeBlockConfig>
2022-04-26 21:12:52 +00:00
<CodeBlockConfig>
2021-10-08 15:54:26 +00:00
```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using Google.Apis.Iam.v1;
using Newtonsoft.Json;
using VaultSharp;
using VaultSharp.V1.AuthMethods;
using VaultSharp.V1.AuthMethods.GoogleCloud;
using VaultSharp.V1.Commons;
using Data = Google.Apis.Iam.v1.Data;
namespace Examples
{
2022-04-26 21:12:52 +00:00
public class GCPAuthExample
2021-10-08 15:54:26 +00:00
{
/// <summary>
/// Fetches a key-value secret (kv-v2) after authenticating to Vault via GCP IAM,
/// one of two auth methods used to authenticate with GCP (the other is GCE auth).
/// </summary>
public string GetSecretGcp()
{
var vaultAddr = Environment.GetEnvironmentVariable("VAULT_ADDR");
if(String.IsNullOrEmpty(vaultAddr))
{
throw new System.ArgumentNullException("Vault Address");
}
2021-12-22 17:33:12 +00:00
var roleName = Environment.GetEnvironmentVariable("VAULT_ROLE");
2021-10-08 15:54:26 +00:00
if(String.IsNullOrEmpty(roleName))
{
2021-12-22 17:33:12 +00:00
throw new System.ArgumentNullException("Vault Role Name");
2021-10-08 15:54:26 +00:00
}
// Learn about authenticating to GCS with service account credentials at https://cloud.google.com/docs/authentication/production
if(String.IsNullOrEmpty(Environment.GetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS")))
{
Console.WriteLine("WARNING: Environment variable GOOGLE_APPLICATION_CREDENTIALS was not set. IAM client for JWT signing will fall back to default instance credentials.");
}
var jwt = SignJWT();
2022-04-26 21:12:52 +00:00
2021-10-08 15:54:26 +00:00
IAuthMethodInfo authMethod = new GoogleCloudAuthMethodInfo(roleName, jwt);
var vaultClientSettings = new VaultClientSettings(vaultAddr, authMethod);
2022-04-26 21:12:52 +00:00
IVaultClient vaultClient = new VaultClient(vaultClientSettings);
2021-10-08 15:54:26 +00:00
// We can retrieve the secret after creating our VaultClient object
Secret<SecretData> kv2Secret = null;
kv2Secret = vaultClient.V1.Secrets.KeyValue.V2.ReadSecretAsync(path: "/creds").Result;
2022-04-26 21:12:52 +00:00
2021-10-08 15:54:26 +00:00
var password = kv2Secret.Data.Data["password"];
2022-04-26 21:12:52 +00:00
2021-10-08 15:54:26 +00:00
return password.ToString();
}
/// <summary>
/// Generate signed JWT from GCP IAM
/// </summary>
private string SignJWT()
{
var roleName = Environment.GetEnvironmentVariable("GCP_ROLE");
var svcAcctName = Environment.GetEnvironmentVariable("GCP_SERVICE_ACCOUNT_NAME");
var gcpProjName = Environment.GetEnvironmentVariable("GOOGLE_CLOUD_PROJECT");
IamService iamService = new IamService(new BaseClientService.Initializer
{
HttpClientInitializer = GetCredential(),
ApplicationName = "Google-iamSample/0.1",
});
string svcEmail = $"{svcAcctName}@{gcpProjName}.iam.gserviceaccount.com";
2022-04-26 21:12:52 +00:00
string name = $"projects/-/serviceAccounts/{svcEmail}";
2021-10-08 15:54:26 +00:00
TimeSpan currentTime = (DateTime.UtcNow - new DateTime(1970, 1, 1));
int expiration = (int)(currentTime.TotalSeconds) + 900;
Data.SignJwtRequest requestBody = new Data.SignJwtRequest();
requestBody.Payload = JsonConvert.SerializeObject(new Dictionary<string, object> ()
{
{ "aud", $"vault/{roleName}" } ,
{ "sub", svcEmail } ,
{ "exp", expiration }
});
ProjectsResource.ServiceAccountsResource.SignJwtRequest request = iamService.Projects.ServiceAccounts.SignJwt(requestBody, name);
Data.SignJwtResponse response = request.Execute();
2022-04-26 21:12:52 +00:00
2021-10-08 15:54:26 +00:00
return JsonConvert.SerializeObject(response.SignedJwt).Replace("\"", "");
}
public static GoogleCredential GetCredential()
{
GoogleCredential credential = Task.Run(() => GoogleCredential.GetApplicationDefaultAsync()).Result;
if (credential.IsCreateScopedRequired)
{
credential = credential.CreateScoped("https://www.googleapis.com/auth/cloud-platform");
}
return credential;
}
}
}
```
</CodeBlockConfig>
2021-09-18 03:51:07 +00:00
</CodeTabs>