Skip to content

Secret Manager

Secure storage for API keys, passwords, and certificates.


Overview

Secret Manager provides a secure and convenient method for storing API keys, passwords, certificates, and other sensitive data.


Key Features

  • Encrypted storage
  • Version management
  • Access control (IAM)
  • Audit logging
  • Automatic replication
  • Integration with GCP services

Creating Secrets

Via gcloud:

# Create secret
echo -n "my-secret-value" | gcloud secrets create my-secret \
  --data-file=- \
  --replication-policy="automatic"

# Create secret from file
gcloud secrets create db-password \
  --data-file=password.txt

# Create with specific locations
gcloud secrets create my-secret \
  --data-file=- \
  --replication-policy="user-managed" \
  --locations="us-central1,us-east1"

Via API:

from google.cloud import secretmanager

client = secretmanager.SecretManagerServiceClient()
parent = f"projects/{project_id}"

# Create secret
secret = client.create_secret(
    request={
        "parent": parent,
        "secret_id": "my-secret",
        "secret": {
            "replication": {"automatic": {}}
        }
    }
)

# Add secret version
client.add_secret_version(
    request={
        "parent": secret.name,
        "payload": {"data": b"my-secret-value"}
    }
)


Accessing Secrets

Python:

from google.cloud import secretmanager

def access_secret(project_id, secret_id, version_id="latest"):
    client = secretmanager.SecretManagerServiceClient()
    name = f"projects/{project_id}/secrets/{secret_id}/versions/{version_id}"

    response = client.access_secret_version(request={"name": name})
    return response.payload.data.decode("UTF-8")

Node.js:

const {SecretManagerServiceClient} = require('@google-cloud/secret-manager');
const client = new SecretManagerServiceClient();

async function accessSecret(projectId, secretId) {
  const name = `projects/${projectId}/secrets/${secretId}/versions/latest`;
  const [version] = await client.accessSecretVersion({name});
  return version.payload.data.toString();
}

Go:

import secretmanager "cloud.google.com/go/secretmanager/apiv1"

func accessSecret(projectID, secretID string) (string, error) {
    ctx := context.Background()
    client, _ := secretmanager.NewClient(ctx)
    defer client.Close()

    name := fmt.Sprintf("projects/%s/secrets/%s/versions/latest", projectID, secretID)
    result, _ := client.AccessSecretVersion(ctx, &secretmanagerpb.AccessSecretVersionRequest{
        Name: name,
    })

    return string(result.Payload.Data), nil
}


IAM Permissions

# Grant access to secret
gcloud secrets add-iam-policy-binding my-secret \
  --member=serviceAccount:my-sa@project.iam.gserviceaccount.com \
  --role=roles/secretmanager.secretAccessor

# Grant admin access
gcloud secrets add-iam-policy-binding my-secret \
  --member=user:admin@example.com \
  --role=roles/secretmanager.admin

Roles: - roles/secretmanager.admin - Full access - roles/secretmanager.secretAccessor - Read secrets - roles/secretmanager.secretVersionManager - Manage versions - roles/secretmanager.viewer - View metadata only


Version Management

# Add new version
echo -n "new-value" | gcloud secrets versions add my-secret \
  --data-file=-

# List versions
gcloud secrets versions list my-secret

# Disable version
gcloud secrets versions disable 1 --secret=my-secret

# Destroy version
gcloud secrets versions destroy 1 --secret=my-secret

# Access specific version
gcloud secrets versions access 2 --secret=my-secret

Integration Examples

Cloud Run

# Mount secret as environment variable
gcloud run deploy my-service \
  --image=IMAGE_URL \
  --update-secrets=DB_PASSWORD=my-secret:latest

# Mount secret as volume
gcloud run deploy my-service \
  --image=IMAGE_URL \
  --update-secrets=/secrets/db-password=my-secret:latest

GKE

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  serviceAccountName: my-ksa
  containers:
  - name: app
    image: my-image
    env:
    - name: DB_PASSWORD
      valueFrom:
        secretKeyRef:
          name: db-password
          key: latest

Cloud Functions

import os
from google.cloud import secretmanager

def my_function(request):
    client = secretmanager.SecretManagerServiceClient()
    name = f"projects/{os.environ['GCP_PROJECT']}/secrets/my-secret/versions/latest"
    response = client.access_secret_version(request={"name": name})
    secret_value = response.payload.data.decode("UTF-8")
    # Use secret_value

Best Practices

✓ Use automatic replication for HA
✓ Implement least privilege access
✓ Enable audit logging
✓ Rotate secrets regularly
✓ Use version management
✓ Never commit secrets to code
✓ Use service accounts for applications
✓ Monitor secret access


Pricing

Storage: $0.06 per secret per month
Access: $0.03 per 10,000 operations
Replication: Additional cost for user-managed

Last Updated: March 2026
Status: ✅ Complete