Vault
HomeDocumentationTutorialsTry Cloud!
  • Vault
  • Documentation
    • What is Vault?
    • Use Cases
    • Setup
      • Install
      • Configuration
    • Get Started
      • Starting the server
      • Your first secret
      • Deploying Vault on VMs with Let's encrypt! TLS certs
    • Concepts
      • Operations
        • Seal/Unseal
        • "Dev" server mode
        • Namespace lock and unlock
        • Lease, renew, and revoke
        • Lease Explosions
        • Mount migration
        • Client count
        • Resource quotas
        • Response wrapping
      • Authentication
        • Identity
        • Tokens
        • OIDC provider
        • Username templating
        • Passwordless
      • Secrets
      • Storage
        • Integrated storage
        • High availability mode (HA)
        • Recovery mode
      • Policies
  • Tutorials
    • CLI
      • Operations
        • Deploy Vault
        • Using the HTTP API
        • Unseal/Seal
      • Authentication
        • Token
        • GitHub authentication
        • Username/Password
        • TLS Client Certificates
        • SSH Keys
        • AWS, Azure, GCP and external auth methods
          • Azure
          • AWS
          • GCP
          • Github
          • Terraform
      • Secrets
        • Secrets engines
        • Built-in help
      • Access Control
        • Policies
    • UI
      • Authentication
        • Username/Password
        • Passwordless
      • Operations
        • Unseal / Seal
        • API Explorer
      • Secrets
        • Secrets engines
      • Access Control
        • Policies
    • Use Cases
      • Namespaces
      • MongoDB admin password
      • VM Disk Encryption Keys
      • VM SSH Keys
      • Kubernetes Configuration
      • GitHub Actions
      • Dynamic credentials for cloud providers
        • AWS
        • Azure
        • GCP
  • CLI
    • agent
    • audit
    • auth
    • debug
    • delete
    • events
    • kv
    • lease
    • license
    • list
    • login
    • monitor
    • namespace
    • operator
    • patch
    • path-help
    • pki
    • plugin
    • policy
    • print
    • proxy
    • read
    • secrets
    • server
    • ssh
    • status
    • token
    • transit
    • unwrap
    • version
    • version-history
    • write
  • API
    • Secrets engines
      • AliCloud secrets engine (API)
      • AWS secrets engine (API)
      • Azure secrets engine (API)
      • Cubbyhole secrets engine (API)
      • Database
        • Cassandra database plugin HTTP API
        • Elasticsearch database plugin HTTP API
        • Influxdb database plugin HTTP API
        • MongoDB database plugin HTTP API
        • MSSQL database plugin HTTP API
        • MySQL/MariaDB database plugin HTTP API
        • Oracle database plugin HTTP API
        • PostgreSQL database plugin HTTP API
        • Redis database plugin HTTP API
        • Redis ElastiCache database plugin HTTP API
        • Redshift database plugin HTTP API
        • Snowflake database plugin HTTP API
      • Google Cloud secrets engine (API)
      • Google Cloud KMS secrets engine (API)
      • Identity
        • entity
        • entity-alias
        • group
        • group-alias
        • tokens
        • lookup
        • oidc-provider
        • MFA
          • duo
          • okta
          • pingid
          • totp
          • login-enforcement
      • KV secrets engine (API)
      • Buckypaper secrets engine
      • Kubernetes secrets engine (API)
      • Nomad secrets engine (API)
      • LDAP secrets engine (API)
      • PKI secrets engine (API)
      • RabbitMQ secrets engine (API)
      • SSH secrets engine (API)
      • TOTP secrets engine (API)
      • Transit secrets engine (API)
    • Auth engines
      • AliCloud auth method (API)
      • AppRole auth method (API)
      • AWS auth method (API)
      • Azure auth method (API)
      • Pivotal Cloud Foundry (CF) auth method (API)
      • GitHub auth method (API)
      • Google Cloud auth method (API)
      • JWT/OIDC auth method (API)
      • Kerberos auth method (API)
      • Kubernetes auth method (API)
      • LDAP auth method (API)
      • OCI auth method (API)
      • Okta auth method (API)
      • Passwordless auth method (API)
      • RADIUS auth method (API)
      • TLS certificate auth method (API)
      • Token auth method (API)
      • Userpass auth method (HTTP API)
    • Service engines
      • Licence Manager
    • System backend
      • /sys/audit
      • /sys/audit-hash
      • /sys/auth
      • /sys/capabilities
      • /sys/capabilities-accessor
      • /sys/capabilities-self
      • /sys/config/auditing/request-headers
      • /sys/config/control-group
      • /sys/config/cors
      • /sys/config/reload
      • /sys/config/state
      • /sys/config/ui
      • /sys/decode-token
      • /sys/experiments
      • /sys/generate-recovery-token
      • /sys/generate-root
      • /sys/health
      • /sys/host-info
      • /sys/in-flight-req
      • /sys/init
      • /sys/internal/counters
      • /sys/internal/inspect
        • /sys/internal/inspect/router
      • /sys/internal/specs/openapi
      • /sys/internal/ui/feature-flags
      • /sys/internal/ui/mounts
      • /sys/internal/ui/namespaces
      • /sys/internal/ui/resultant-acl
      • /sys/key-status
      • /sys/ha-status
      • /sys/leader
      • /sys/leases
      • /sys/license/status
      • /sys/locked-users
      • /sys/loggers
      • /sys/metrics
      • /sys/monitor
      • /sys/mounts
      • /sys/namespaces
      • /sys/plugins/reload/backend
      • /sys/plugins/catalog
      • /sys/plugins/runtimes/catalog
      • /sys/policy
      • /sys/policies/
      • /sys/policies/password/
      • /sys/pprof
      • /sys/quotas/config
      • /sys/quotas/rate-limit
      • /sys/quotas/lease-count
      • /sys/raw
      • /sys/rekey
      • /sys/rekey-recovery-key
      • /sys/remount
      • /sys/rotate
      • /sys/rotate/config
      • /sys/seal
      • /sys/seal-status
      • /sys/seal-backend-status
      • /sys/step-down
      • /sys/storage
        • /sys/storage/raft
        • /sys/storage/raft/autopilot
      • /sys/tools
      • /sys/unseal
      • /sys/version-history
      • /sys/wrapping/lookup
      • /sys/wrapping/rewrap
      • /sys/wrapping/unwrap
      • /sys/wrapping/wrap
  • Resources
    • Blog
    • GitHub
    • Youtube
    • CCx101
Powered by GitBook
On this page
  • Authentication
  • Configuration
  • GCP credentials
  • Group aliases
  • Implementation details
  • Generating JWTs
  • API
  • Code example
  1. Tutorials
  2. CLI
  3. Authentication
  4. AWS, Azure, GCP and external auth methods

GCP

PreviousAWSNextGithub

Last updated 1 year ago

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:

  • Google Cloud IAM service accounts

  • Google Compute Engine (GCE) instances

This backend focuses on identities specific to Google Cloud and does not support authenticating arbitrary Google or Google Workspace users or generic OAuth against Google.

This plugin is developed in a separate GitHub repository at , but is automatically bundled in Vault releases. Please file all feature requests, bugs, and pull requests specific to the GCP plugin under that repository.

Authentication

Via the CLI helper

Vault includes a CLI helper that obtains a signed JWT locally and sends the request to Vault.

# Authentication to vault outside of Google Cloud
$ vault login -method=gcp \
    role="my-role" \
    service_account="authenticating-account@my-project.iam.gserviceaccount.com" \
    jwt_exp="15m" \
    credentials=@path/to/signer/credentials.json
# Authentication to vault inside of Google Cloud
$ vault login -method=gcp role="my-role"

For more usage information, run vault auth help gcp.

-> 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.

Via the CLI

$ vault write -field=token auth/gcp/login \
    role="my-role" \
    jwt="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

See Generating JWTs for ways to obtain the JWT token.

Via the API

$ curl \
    --request POST \
    --data '{"role":"my-role", "jwt":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."}' \
    http://127.0.0.1:8200/v1/auth/gcp/login

See API docs for expected response.

Configuration

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.

  1. Enable the Google Cloud auth method:

    $ vault auth enable gcp
  2. Configure the auth method credentials if Vault is not running on Google Cloud:

    $ vault write auth/gcp/config \
        credentials=@/path/to/credentials.json

    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 Google Cloud Credentials section below.

  3. Create a named role:

    For an iam-type role:

    $ vault write auth/gcp/role/my-iam-role \
        type="iam" \
        policies="dev,prod" \
        bound_service_accounts="my-service@my-project.iam.gserviceaccount.com"

    For a gce-type role:

    $ vault write auth/gcp/role/my-gce-role \
        type="gce" \
        policies="dev,prod" \
        bound_projects="my-project1,my-project2" \
        bound_zones="us-east1-b" \
        bound_labels="foo:bar,zip:zap" \
        bound_service_accounts="my-service@my-project.iam.gserviceaccount.com"

    Note that bound_service_accounts is only required for iam-type roles.

    For the complete list of configuration options for each type, please see the API documentation.

GCP credentials

  1. The environment variable 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.

  2. Default instance credentials. When no environment variable is present, the default service account credentials are used.

To use this auth method, the service account must have the following minimum scope:

https://www.googleapis.com/auth/cloud-platform

Required GCP permissions

Enabled GCP APIs

The GCP project must have the following APIs enabled:

Vault server permissions

For iam-type Vault roles, the service account credentials given to Vault can have the following role:

roles/iam.serviceAccountKeyAdmin

For gce-type Vault roles, the service account credentials given to Vault can have the following role:

roles/compute.viewer

If you instead wish to create a custom role with only the exact GCP permissions required, use the following list of permissions:

iam.serviceAccounts.get
iam.serviceAccountKeys.get
compute.instances.get
compute.instanceGroups.list

These allow Vault to:

  • verify the service account, either directly authenticating or associated with authenticating GCE instance, exists

  • get the corresponding public keys for verifying JWTs signed by service account private keys.

  • verify authenticating GCE instances exist

  • compare bound fields for GCE roles (zone/region, labels, or membership in given instance groups)

If you are using Group Aliases as described below, you will also need to add the resourcemanager.projects.get permission.

Permissions for authenticating against Vault

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.

Note that the previously mentioned permissions are given to the Vault servers. The IAM service account or GCE instance that is authenticating against Vault must have the following role:

roles/iam.serviceAccountTokenCreator

Group aliases

As of Vault 1.0, roles can specify an add_group_aliases boolean parameter that adds 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:

[
  "project-$PROJECT_ID",
  "folder-$SUBFOLDER_ID",
  "folder-$FOLDER_ID",
  "organization-$ORG_ID"
]

If you are using a custom role for Vault server, you will need to add the resourcemanager.projects.get permission to your custom role.

Implementation details

This section describes the implementation details for how Vault communicates with Google Cloud to authenticate and authorize JWT tokens. This information is provided for those who are curious, but these details are not required knowledge for using the auth method.

IAM login

IAM login applies only to roles of type iam. The Vault authentication workflow for IAM service accounts looks like this:

  1. The client sends this signed JWT to Vault along with a role name.

  2. 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.

  3. Vault authorizes the confirmed service account against the given role. If that is successful, a Vault token with the proper policies is returned.

GCE login

GCE login only applies to roles of type gce and must be completed on an infrastructure running on Google Cloud. These steps will not work from your local laptop or another cloud provider.

  1. The client sends this JWT to Vault along with a role name.

  2. 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.

  3. 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.

Generating JWTs

This section details the various methods and examples for obtaining JWT tokens.

Service account credentials API

curl example

Vault requires the following minimum claim set:

{
  "sub": "$SERVICE_ACCOUNT_EMAIL_OR_ID",
  "aud": "vault/$ROLE",
  "exp": "$EXPIRATION"
}

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.

ROLE="my-role"
SERVICE_ACCOUNT="service-account@my-project.iam.gserviceaccount.com"
OAUTH_TOKEN="$(oauth2l header cloud-platform)"
EXPIRATION="<your_token_expiration>"
JWT_CLAIM="{\\\"aud\\\":\\\"vault/${ROLE}\\\", \\\"sub\\\": \\\"${SERVICE_ACCOUNT}\\\", \\\"exp\\\": ${EXPIRATION}}"

$ curl \
  --header "${OAUTH_TOKEN}" \
  --header "Content-Type: application/json" \
  --request POST \
  --data "{\"payload\": \"${JWT_CLAIM}\"}" \
  "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/${SERVICE_ACCOUNT}:signJwt"

gcloud example

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.

$ gcloud beta iam service-accounts sign-jwt $INPUT_JWT_CLAIMS $OUTPUT_JWT_FILE \
    --iam-account=service-account@my-project.iam.gserviceaccount.com \
    --project=my-project

Golang example

GCE

You can autogenerate this token in Vault versions 1.8.2 or higher.

GCE tokens can only be generated from a GCE instance.

  1. Vault can automatically discover the identity token on a GCE/GKE instance. This simplifies authenticating to Vault like so:

    $ vault login \
      -method=gcp \
      role="my-gce-role"
  2. The JWT token can also be obtained from the "service-accounts/default/identity" endpoint for a instance's metadata server.

    Curl example

    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"

API

The GCP Auth Plugin has a full HTTP API. Please see the API docs for more details.

Code example

The following example demonstrates the Google Cloud auth method to authenticate with Vault.

package main

import (
	"context"
	"fmt"
	"os"

	vault "github.com/hashicorp/vault/api"
	auth "github.com/hashicorp/vault/api/auth/gcp"
)

// 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).
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)
	}

	// 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.
	// 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")
	}

	svcAccountEmail := fmt.Sprintf("%s@%s.iam.gserviceaccount.com", os.Getenv("GCP_SERVICE_ACCOUNT_NAME"), os.Getenv("GOOGLE_CLOUD_PROJECT"))

	// 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)
	}

	authInfo, err := client.Auth().Login(context.TODO(), gcpAuth)
	if err != nil {
		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")
	}

	// get secret from the default mount path for KV v2 in dev mode, "secret"
	secret, err := client.KVv2("secret").Get(context.Background(), "creds")
	if err != nil {
		return "", fmt.Errorf("unable to read secret: %w", err)
	}

	// data map can contain more than one key-value pair,
	// in this case we're just grabbing one of them
	value, ok := secret.Data["password"].(string)
	if !ok {
		return "", fmt.Errorf("value type assertion failed: %T %#v", secret.Data["password"], secret.Data["password"])
	}

	return value, nil
}
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
{
    public class GCPAuthExample
    {
        /// <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");
            }

            var roleName = Environment.GetEnvironmentVariable("VAULT_ROLE");
            if(String.IsNullOrEmpty(roleName))
            {
                throw new System.ArgumentNullException("Vault Role Name");
            }

            // 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();

            IAuthMethodInfo authMethod = new GoogleCloudAuthMethodInfo(roleName, jwt);
            var vaultClientSettings = new VaultClientSettings(vaultAddr, authMethod);

            IVaultClient vaultClient = new VaultClient(vaultClientSettings);

            // We can retrieve the secret after creating our VaultClient object
            Secret<SecretData> kv2Secret = null;
            kv2Secret = vaultClient.V1.Secrets.KeyValue.V2.ReadSecretAsync(path: "/creds").Result;

            var password = kv2Secret.Data.Data["password"];

            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";
            string name = $"projects/-/serviceAccounts/{svcEmail}";

            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();

            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;
        }
    }
}

-> Note: If you're using a environment, you will additionally need to configure your environment’s custom endpoints via the custom_endpoint configuration parameter.

The Google Cloud Vault auth method uses the official Google Cloud Golang SDK. This means it supports the common ways of .

For more information on service accounts, please see the .

for iam and gce type roles.

for gce type roles.

for iam and gce type roles that set add_group_aliases to true.

!> 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 for more information.

The client generates a signed JWT using the Service Account Credentials API method. For examples of how to do this, see the Generating JWTs section.

The client obtains an on a GCE instance.

This describes how to use the GCP Service Account Credentials directly to generate the signed JWT with the claims that Vault expects. Note the CLI does this process for you and is much easier, and that there is very little reason to do this yourself.

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 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.

One you have all this information, the JWT token can be signed using curl and :

Read more on the .

hashicorp/vault-plugin-auth-gcp
Private Google Access
providing credentials to Google Cloud
Google Cloud Service Accounts documentation
iam.googleapis.com
compute.googleapis.com
cloudresourcemanager.googleapis.com
Managing service account impersonation
projects.serviceAccounts.signJwt
instance identity metadata token
API method
NumericDate
oauth2l
Google Open Source blog