HashiCorp Vault — Azure & GCP Secrets

1 minute read

Vault can generate dynamic credentials for Azure (service principals) and GCP (service account keys, OAuth tokens).


Azure Secrets Engine

Enable and Configure

vault secrets enable azure

vault write azure/config \
    subscription_id="your-subscription-id" \
    tenant_id="your-tenant-id" \
    client_id="vault-app-client-id" \
    client_secret="vault-app-client-secret"

Vault’s Azure app registration needs Application.ReadWrite.All and GroupMember.ReadWrite.All permissions (or equivalent).

Create a Role

# Role that assigns an Azure RBAC role
vault write azure/roles/contributor \
    ttl=1h \
    max_ttl=24h \
    azure_roles=-<<EOF
[
  {
    "role_name": "Contributor",
    "scope": "/subscriptions/your-subscription-id/resourceGroups/my-rg"
  }
]
EOF

Generate Credentials

vault read azure/creds/contributor

Expected output:

Key                Value
---                -----
lease_id           azure/creds/contributor/abc123
lease_duration     1h
lease_renewable    true
client_id          generated-app-client-id
client_secret      generated-client-secret
# Use with Azure CLI
az login --service-principal \
    -u "generated-app-client-id" \
    -p "generated-client-secret" \
    --tenant "your-tenant-id"

GCP Secrets Engine

Enable and Configure

vault secrets enable gcp

# Configure with service account key
vault write gcp/config \
    credentials=@vault-sa-key.json

Credential Types

Type What It Creates Lifetime
access_token OAuth2 access token Up to 1h (GCP limit)
service_account_key SA JSON key Until lease expires

Create Roles

# OAuth token role (preferred — no key material)
vault write gcp/roleset/project-viewer \
    project="my-gcp-project" \
    secret_type="access_token" \
    token_scopes="https://www.googleapis.com/auth/cloud-platform" \
    bindings=-<<EOF
resource "//cloudresourcemanager.googleapis.com/projects/my-gcp-project" {
  roles = ["roles/viewer"]
}
EOF

# Service account key role
vault write gcp/roleset/storage-admin \
    project="my-gcp-project" \
    secret_type="service_account_key" \
    bindings=-<<EOF
resource "//cloudresourcemanager.googleapis.com/projects/my-gcp-project" {
  roles = ["roles/storage.admin"]
}
EOF

Generate Credentials

# Get an OAuth token
vault read gcp/roleset/project-viewer/token

Expected output:

Key                Value
---                -----
expires_at_seconds 1705312800
token              ya29.a0ARrdaM...
token_ttl          59m59s
# Get a service account key
vault read gcp/roleset/storage-admin/key
# Use the OAuth token
curl -H "Authorization: Bearer ya29.a0ARrdaM..." \
     "https://storage.googleapis.com/storage/v1/b?project=my-gcp-project"

Cloud Secrets Comparison

Feature AWS Azure GCP
Credential types IAM user, STS assumed role, federation token Service principal OAuth token, SA key
Preferred type Assumed Role (STS) Service principal OAuth token (access_token)
Max TTL Varies (15min–36h for STS) Configurable 1h (access_token)
Root rotation ✅ ❌ (app registration) ❌ (SA key)
Cleanup Deletes IAM user/keys Deletes service principal Deletes SA key/token

Quick Reference

Command Description
vault secrets enable azure Enable Azure engine
vault write azure/config ... Configure Azure
vault write azure/roles/NAME ... Create Azure role
vault read azure/creds/NAME Generate Azure creds
vault secrets enable gcp Enable GCP engine
vault write gcp/config ... Configure GCP
vault write gcp/roleset/NAME ... Create GCP roleset
vault read gcp/roleset/NAME/token Get OAuth token
vault read gcp/roleset/NAME/key Get SA key

Next: Lease Management