mirror of
https://github.com/hashicorp/vault.git
synced 2025-08-22 23:21:08 +02:00
* Update README Let contributors know that docs will now be located in UDR * Add comments to each mdx doc Comment has been added to all mdx docs that are not partials * chore: added changelog changelog check failure * wip: removed changelog * Fix content errors * Doc spacing * Update website/content/docs/deploy/kubernetes/vso/helm.mdx Co-authored-by: Tu Nguyen <im2nguyen@users.noreply.github.com> --------- Co-authored-by: jonathanfrappier <92055993+jonathanfrappier@users.noreply.github.com> Co-authored-by: Tu Nguyen <im2nguyen@users.noreply.github.com>
340 lines
13 KiB
Plaintext
340 lines
13 KiB
Plaintext
---
|
|
layout: docs
|
|
page_title: Sync secrets from Vault to GCP Secret Manager
|
|
description: >-
|
|
Automatically sync and unsync the secrets from Vault to GCP Secret Manager to centralize visibility and control of secrets lifecycle management.
|
|
---
|
|
|
|
> [!IMPORTANT]
|
|
> **Documentation Update:** Product documentation, which were located in this repository under `/website`, are now located in [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs), colocated with all other product documentation. Contributions to this content should be done in the `web-unified-docs` repo, and not this one. Changes made to `/website` content in this repo will not be reflected on the developer.hashicorp.com website.
|
|
|
|
# Sync secrets from Vault to GCP Secret Manager
|
|
|
|
The Google Cloud Platform (GCP) Secret Manager sync destination allows Vault to safely synchronize secrets to your GCP projects.
|
|
This is a low footprint option that enables your applications to benefit from Vault-managed secrets without requiring them
|
|
to connect directly with Vault. This guide walks you through the configuration process.
|
|
|
|
Prerequisites:
|
|
* Ability to read or create KVv2 secrets
|
|
* Ability to create GCP Service Account credentials with access to the Secret Manager
|
|
* Ability to create sync destinations and associations on your Vault server
|
|
|
|
## Setup
|
|
|
|
1. If you do not already have a Service Account, navigate to the IAM & Admin page in the Google Cloud console to
|
|
[create a new Service Account](https://cloud.google.com/iam/docs/service-accounts-create) with the
|
|
[necessary permissions](/vault/docs/sync/gcpsm#permissions). [Instructions](/vault/docs/sync/gcpsm#provision-service-account)
|
|
to provision this Service Account via Terraform can be found below.
|
|
|
|
1. Configure a sync destination with the Service Account JSON credentials created in the previous step. See docs for
|
|
[alternative ways](/vault/docs/secrets/gcp#authentication) to pass in the `credentials` parameter.
|
|
|
|
```shell-session
|
|
$ vault write sys/sync/destinations/gcp-sm/my-dest \
|
|
credentials='@path/to/credentials.json'
|
|
replication_locations='us-east1,us-west1'
|
|
```
|
|
|
|
**Output:**
|
|
|
|
<CodeBlockConfig hideClipboard>
|
|
|
|
```plaintext
|
|
Key Value
|
|
--- -----
|
|
connection_details map[credentials:***** replication_locations:us-east1,us-west1]
|
|
name my-dest
|
|
type gcp-sm
|
|
```
|
|
|
|
</CodeBlockConfig>
|
|
|
|
## Usage
|
|
|
|
1. If you do not already have a KVv2 secret to sync, mount a new KVv2 secrets engine.
|
|
|
|
```shell-session
|
|
$ vault secrets enable -path=my-kv kv-v2
|
|
```
|
|
|
|
**Output**:
|
|
|
|
<CodeBlockConfig hideClipboard>
|
|
|
|
```plaintext
|
|
Success! Enabled the kv-v2 secrets engine at: my-kv/
|
|
```
|
|
|
|
</CodeBlockConfig>
|
|
|
|
1. Create secrets you wish to sync with a target GCP Secret Manager.
|
|
|
|
```shell-session
|
|
$ vault kv put -mount=my-kv my-secret foo='bar'
|
|
```
|
|
|
|
**Output**:
|
|
|
|
<CodeBlockConfig hideClipboard>
|
|
|
|
```plaintext
|
|
==== Secret Path ====
|
|
my-kv/data/my-secret
|
|
|
|
======= Metadata =======
|
|
Key Value
|
|
--- -----
|
|
created_time <timestamp>
|
|
custom_metadata <nil>
|
|
deletion_time n/a
|
|
destroyed false
|
|
version 1
|
|
```
|
|
|
|
</CodeBlockConfig>
|
|
|
|
1. Create an association between the destination and a secret to synchronize.
|
|
|
|
```shell-session
|
|
$ vault write sys/sync/destinations/gcp-sm/my-dest/associations/set \
|
|
mount='my-kv' \
|
|
secret_name='my-secret'
|
|
```
|
|
|
|
**Output:**
|
|
|
|
<CodeBlockConfig hideClipboard>
|
|
|
|
```plaintext
|
|
Key Value
|
|
--- -----
|
|
associated_secrets map[kv_1234/my-secret:map[accessor:kv_1234 secret_name:my-secret sync_status:SYNCED updated_at:<timestamp>]]
|
|
store_name my-dest
|
|
store_type gcp-sm
|
|
```
|
|
|
|
</CodeBlockConfig>
|
|
|
|
1. Navigate to the [Secret Manager](https://console.cloud.google.com/security/secret-manager) in the Google Cloud console
|
|
to confirm your secret was successfully created in your GCP project.
|
|
|
|
Moving forward, any modification on the Vault secret will be propagated in near real time to its GCP Secret Manager
|
|
counterpart. Creating a new secret version in Vault will create a new version in GCP Secret Manager. Deleting the secret
|
|
or the association in Vault will delete the secret in your GCP project as well.
|
|
|
|
## Replication policy
|
|
|
|
GCP can target specific geographic regions to provide strict control on where
|
|
your applications store data and sync secrets. You can target specific GCP
|
|
regions for each sync destinations during creation which will limit where Vault writes
|
|
secrets.
|
|
|
|
Regardless of the region limits on writes, synced secrets are always readable
|
|
globally when the client has the required permissions.
|
|
|
|
### Encryption keys
|
|
|
|
Vault can leverage customer-managed encryption keys (CMEK) instead of Google-managed keys to encrypt secrets in GCP Secret Manager
|
|
as part of the replication policy. To use CMEK, you must first create key ring(s) and key(s) as desired, ensuring that the key quantity
|
|
corresponds with the planned replication policy. The key rings and keys must be created before configuring the sync destination.
|
|
|
|
When using a global KMS key, it must be the only key set on the destination and the replication locations must remain unset, meaning
|
|
it can only be used with using GCP's automatic replication. When specifying regional keys, a key must be set for each region in the
|
|
replication location list. GCP key names are expected in the format of the entire resource ID, e.g. `projects/<project_id>/locations/<location_name>/keyRings/<key_ring_name>/cryptoKeys/<key_name>`. See the [API](#api) section for more details.
|
|
|
|
## Permissions
|
|
|
|
Enabling the Secret Manager API and the Cloud Resource Manager API's are prerequisites to using secrets sync with
|
|
GCP Secret Manager. Once both APIs are enabled, it may take several minutes for the changes to take effect within
|
|
the GCP project.
|
|
|
|
After the necessary APIs are active, the credentials given to Vault must have the following permissions to synchronize secrets:
|
|
|
|
```shell-session
|
|
secretmanager.secrets.create
|
|
secretmanager.secrets.delete
|
|
secretmanager.secrets.update
|
|
secretmanager.versions.add
|
|
secretmanager.versions.destroy
|
|
```
|
|
|
|
## Provision service account
|
|
|
|
Vault needs to be configured with credentials to establish a trust relationship with your GCP project so it can manage
|
|
Secret Manager secrets on your behalf. The IAM & Admin page in the Google Cloud console can be used to
|
|
[create a new Service Account](https://cloud.google.com/iam/docs/service-accounts-create) with access to the Secret Manager.
|
|
|
|
You can equally use the [Terraform Google provider](https://registry.terraform.io/providers/hashicorp/google/latest/docs#authentication-and-configuration)
|
|
to provision a GCP Service Account with the appropriate policies.
|
|
|
|
1. Copy-paste this HCL snippet into a `secrets-sync-setup.tf` file.
|
|
|
|
```hcl
|
|
provider "google" {
|
|
// See https://registry.terraform.io/providers/hashicorp/google/latest/docs#authentication-and-configuration to setup the Google Provider
|
|
// for options on how to configure this provider. The following parameters or environment
|
|
// variables are typically used.
|
|
|
|
// Parameters
|
|
// region = "" (Optional)
|
|
// project = ""
|
|
// credentials = ""
|
|
|
|
// Environment Variables
|
|
// GOOGLE_REGION (optional)
|
|
// GOOGLE_PROJECT
|
|
// GOOGLE_CREDENTIALS (The path to a service account key file with the
|
|
// "Service Account Admin", "Service Account Key Admin",
|
|
// "Secret Manager Admin", and "Project IAM Admin" roles
|
|
// attached)
|
|
}
|
|
|
|
data "google_client_config" "config" {}
|
|
|
|
resource "google_service_account" "vault_secrets_sync_account" {
|
|
account_id = "gcp-sm-vault-secrets-sync"
|
|
description = "service account for Vault Secrets Sync feature"
|
|
}
|
|
|
|
// Production environments should use a more restricted role.
|
|
// The built-in secret manager admin role is used as an example for simplicity.
|
|
data "google_iam_policy" "vault_secrets_sync_iam_policy" {
|
|
binding {
|
|
role = "roles/secretmanager.admin"
|
|
members = [
|
|
google_service_account.vault_secrets_sync_account.email,
|
|
]
|
|
}
|
|
}
|
|
|
|
resource "google_project_iam_member" "vault_secrets_sync_iam_member" {
|
|
project = data.google_client_config.config.project
|
|
role = "roles/secretmanager.admin"
|
|
member = google_service_account.vault_secrets_sync_account.member
|
|
}
|
|
|
|
resource "google_service_account_key" "vault_secrets_sync_account_key" {
|
|
service_account_id = google_service_account.vault_secrets_sync_account.name
|
|
public_key_type = "TYPE_X509_PEM_FILE"
|
|
}
|
|
|
|
resource "local_file" "vault_secrets_sync_credentials_file" {
|
|
content = base64decode(google_service_account_key.vault_secrets_sync_account_key.private_key)
|
|
filename = "gcp-sm-sync-service-account-credentials.json"
|
|
}
|
|
|
|
output "vault_secrets_sync_credentials_file_path" {
|
|
value = abspath("${path.module}/${local_file.sync_service_account_credentials_file.filename}")
|
|
}
|
|
```
|
|
|
|
1. Execute a plan to validate the Terraform Google provider is properly configured.
|
|
|
|
```shell-session
|
|
$ terraform init && terraform plan
|
|
```
|
|
|
|
**Output:**
|
|
|
|
<CodeBlockConfig hideClipboard>
|
|
|
|
```plaintext
|
|
(...)
|
|
Plan: 4 to add, 0 to change, 0 to destroy.
|
|
```
|
|
|
|
</CodeBlockConfig>
|
|
|
|
1. Execute an apply to provision the Service Account.
|
|
|
|
```shell-session
|
|
$ terraform apply
|
|
```
|
|
|
|
**Output:**
|
|
|
|
<CodeBlockConfig hideClipboard>
|
|
|
|
```plaintext
|
|
(...)
|
|
Apply complete! Resources: 4 added, 0 changed, 0 destroyed.
|
|
|
|
Outputs:
|
|
|
|
sync_service_account_credentials_file = "/path/to/credentials/file/gcp-sm-sync-service-account-credentials.json"
|
|
```
|
|
|
|
</CodeBlockConfig>
|
|
|
|
The generated Service Account credentials file can then be used to configure the Vault GCP Secret Manager destination
|
|
following the [setup](/vault/docs/sync/gcpsm#setup) steps.
|
|
|
|
## Targeting specific GCP projects
|
|
|
|
By default, the target GCP project to sync secrets with is derived from the service
|
|
account JSON [credentials](/vault/api-docs/system/secrets-sync#credentials) or application
|
|
default credentials for a particular GCP sync destination. This means secrets will be synced
|
|
within the parent project of the configured service account.
|
|
|
|
In some cases, it's desirable to use a single service account or [workload identity](https://cloud.google.com/compute/docs/access/create-enable-service-accounts-for-instances)
|
|
to sync secrets with any number of GCP projects within an organization. To achieve this,
|
|
you can set the `project_id` parameter to the target project to sync secrets with:
|
|
|
|
```shell-session
|
|
$ vault write sys/sync/destinations/gcp-sm/my-dest \
|
|
project_id='target-project-id'
|
|
```
|
|
|
|
This overrides the project ID derived from the service account JSON credentials or application
|
|
default credentials. The service account must be [authorized](https://cloud.google.com/iam/docs/service-account-overview#locations)
|
|
to perform Secret Manager actions in the target project.
|
|
|
|
## Access management
|
|
|
|
You can allow or restrict access to secrets based on
|
|
[IAM conditions](https://cloud.google.com/iam/docs/conditions-resource-attributes#resource-name)
|
|
against the fully-qualified resource name. For secrets in Secret Manager, a fully-qualified resource name must have the following
|
|
format:
|
|
|
|
`projects/<project_number>/secrets/<secret_name>`
|
|
|
|
<Tip title="Use the project number, not the project ID">
|
|
|
|
The project **number** is not the same as the project **ID**. Project numbers
|
|
are **numeric** while project IDs are **alphanumeric**. They can be found on
|
|
the Project info panel in the web dashboard or on the Welcome screen.
|
|
|
|
</Tip>
|
|
|
|
For example, the default secret name template prepends the word `vault` to the
|
|
beginning of secret names. To prevent Vault from modifying secrets that were not
|
|
created by a sync operation, you can use a role binding against the resource
|
|
name with the `startsWith` condition:
|
|
|
|
```
|
|
resource.name.startsWith("projects/<project_number>/secrets/vault")
|
|
```
|
|
|
|
To prevent out-of-band overwrites, simply add a negative condition with `!` on any
|
|
write-access role bindings not being used by Vault that contain Secret Manager permissions:
|
|
|
|
```
|
|
!(resource.name.startsWith("projects/<project_number>/secrets/vault"))
|
|
```
|
|
|
|
To add conditions to IAM principles in GCP, click "+ADD IAM CONDITION" on the **Assign Roles** screen.
|
|
|
|

|
|

|
|
|
|
<Tip title="Refer to Google's Overview of IAM Conditions documentation">
|
|
|
|
[Google's documentation](https://cloud.google.com/iam/docs/conditions-overview) on IAM Conditions provides
|
|
further information on how they work and how they should be used, as well as their limits.
|
|
|
|
</Tip>
|
|
|
|
## API
|
|
|
|
Please see the [secrets sync API](/vault/api-docs/system/secrets-sync) for more details.
|