or run

tessl search
Log in

Version

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
golangpkg:golang/cloud.google.com/go/secretmanager@v1.16.0

docs

client.mdiam.mdindex.mdsecrets.mdtypes.mdversions.md
tile.json

tessl/golang-cloud-google-com--go--secretmanager

tessl install tessl/golang-cloud-google-com--go--secretmanager@1.16.1

Go Client Library for Google Cloud Secret Manager API - stores sensitive data such as API keys, passwords, and certificates

iam.mddocs/

IAM and Access Control

Identity and Access Management (IAM) controls who can access your secrets. The Secret Manager client provides methods to manage IAM policies and test permissions.

IAM Policy Management

SetIamPolicy

func (c *Client) SetIamPolicy(ctx context.Context, req *iampb.SetIamPolicyRequest, opts ...gax.CallOption) (*iampb.Policy, error)

Sets the access control policy on the specified secret. Replaces any existing policy.

Request Type:

type SetIamPolicyRequest struct {
    Resource   string
    Policy     *Policy
    UpdateMask *fieldmaskpb.FieldMask
}

Fields:

  • Resource - Required. The resource name of the secret in format projects/*/secrets/*
  • Policy - Required. The IAM policy to set
  • UpdateMask - Optional. A FieldMask specifying which fields to update

Example - Grant access to a user:

import iampb "cloud.google.com/go/iam/apiv1/iampb"

policy := &iampb.Policy{
    Bindings: []*iampb.Binding{
        {
            Role: "roles/secretmanager.secretAccessor",
            Members: []string{
                "user:alice@example.com",
                "serviceAccount:my-service@my-project.iam.gserviceaccount.com",
            },
        },
        {
            Role: "roles/secretmanager.secretVersionManager",
            Members: []string{
                "user:bob@example.com",
            },
        },
    },
}

req := &iampb.SetIamPolicyRequest{
    Resource: "projects/my-project/secrets/my-api-key",
    Policy:   policy,
}

updatedPolicy, err := client.SetIamPolicy(ctx, req)
if err != nil {
    log.Fatalf("failed to set IAM policy: %v", err)
}

fmt.Printf("Updated policy with %d bindings\n", len(updatedPolicy.Bindings))

Example - Add a condition to a binding:

import (
    "google.golang.org/genproto/googleapis/type/expr"
)

policy := &iampb.Policy{
    Bindings: []*iampb.Binding{
        {
            Role: "roles/secretmanager.secretAccessor",
            Members: []string{
                "user:alice@example.com",
            },
            Condition: &expr.Expr{
                Title:      "Expires in 2025",
                Description: "Access expires at the end of 2025",
                Expression: "request.time < timestamp('2025-12-31T23:59:59Z')",
            },
        },
    },
}

req := &iampb.SetIamPolicyRequest{
    Resource: "projects/my-project/secrets/my-api-key",
    Policy:   policy,
}

updatedPolicy, err := client.SetIamPolicy(ctx, req)

GetIamPolicy

func (c *Client) GetIamPolicy(ctx context.Context, req *iampb.GetIamPolicyRequest, opts ...gax.CallOption) (*iampb.Policy, error)

Gets the access control policy for a secret. Returns an empty policy if the secret does not have an explicit policy set.

Request Type:

type GetIamPolicyRequest struct {
    Resource string
    Options  *GetPolicyOptions
}

Fields:

  • Resource - Required. The resource name of the secret in format projects/*/secrets/*
  • Options - Optional. Options for getting the policy

Example:

req := &iampb.GetIamPolicyRequest{
    Resource: "projects/my-project/secrets/my-api-key",
}

policy, err := client.GetIamPolicy(ctx, req)
if err != nil {
    log.Fatalf("failed to get IAM policy: %v", err)
}

fmt.Printf("Policy version: %d\n", policy.Version)
for i, binding := range policy.Bindings {
    fmt.Printf("Binding %d:\n", i)
    fmt.Printf("  Role: %s\n", binding.Role)
    fmt.Printf("  Members: %v\n", binding.Members)
    if binding.Condition != nil {
        fmt.Printf("  Condition: %s\n", binding.Condition.Expression)
    }
}

Example - Get policy and add a member:

// Get current policy
getReq := &iampb.GetIamPolicyRequest{
    Resource: "projects/my-project/secrets/my-api-key",
}

policy, err := client.GetIamPolicy(ctx, getReq)
if err != nil {
    log.Fatalf("failed to get policy: %v", err)
}

// Find or create binding for the role
var binding *iampb.Binding
for _, b := range policy.Bindings {
    if b.Role == "roles/secretmanager.secretAccessor" {
        binding = b
        break
    }
}

if binding == nil {
    binding = &iampb.Binding{
        Role:    "roles/secretmanager.secretAccessor",
        Members: []string{},
    }
    policy.Bindings = append(policy.Bindings, binding)
}

// Add new member
newMember := "user:charlie@example.com"
binding.Members = append(binding.Members, newMember)

// Update policy
setReq := &iampb.SetIamPolicyRequest{
    Resource: "projects/my-project/secrets/my-api-key",
    Policy:   policy,
}

updatedPolicy, err := client.SetIamPolicy(ctx, setReq)
if err != nil {
    log.Fatalf("failed to update policy: %v", err)
}

fmt.Printf("Added member: %s\n", newMember)

TestIamPermissions

func (c *Client) TestIamPermissions(ctx context.Context, req *iampb.TestIamPermissionsRequest, opts ...gax.CallOption) (*iampb.TestIamPermissionsResponse, error)

Returns permissions that a caller has for the specified secret. If the secret does not exist, this will return an empty set of permissions.

Request Type:

type TestIamPermissionsRequest struct {
    Resource    string
    Permissions []string
}

Fields:

  • Resource - Required. The resource name of the secret in format projects/*/secrets/*
  • Permissions - Required. The set of permissions to check

Response Type:

type TestIamPermissionsResponse struct {
    Permissions []string
}

Fields:

  • Permissions - A subset of TestIamPermissionsRequest.permissions that the caller is allowed

Example:

req := &iampb.TestIamPermissionsRequest{
    Resource: "projects/my-project/secrets/my-api-key",
    Permissions: []string{
        "secretmanager.secrets.get",
        "secretmanager.secrets.update",
        "secretmanager.versions.access",
    },
}

resp, err := client.TestIamPermissions(ctx, req)
if err != nil {
    log.Fatalf("failed to test permissions: %v", err)
}

fmt.Printf("Granted permissions: %v\n", resp.Permissions)

// Check specific permission
hasAccessPermission := false
for _, perm := range resp.Permissions {
    if perm == "secretmanager.versions.access" {
        hasAccessPermission = true
        break
    }
}

if hasAccessPermission {
    fmt.Println("User can access secret versions")
} else {
    fmt.Println("User cannot access secret versions")
}

IAM Handle

IAM

func (c *Client) IAM(name string) *iam.Handle

Returns a handle to inspect and change permissions of the resource indicated by the given secret name. The handle provides a more ergonomic interface for IAM operations.

Example:

import "cloud.google.com/go/iam"

handle := client.IAM("projects/my-project/secrets/my-api-key")

// Get current policy
policy, err := handle.Policy(ctx)
if err != nil {
    log.Fatalf("failed to get policy: %v", err)
}

// Add a member to a role
policy.Add("user:dave@example.com", "roles/secretmanager.secretAccessor")

// Update the policy
if err := handle.SetPolicy(ctx, policy); err != nil {
    log.Fatalf("failed to set policy: %v", err)
}

fmt.Println("Successfully updated IAM policy")

Example - Test permissions using handle:

handle := client.IAM("projects/my-project/secrets/my-api-key")

permissions := []string{
    "secretmanager.secrets.get",
    "secretmanager.versions.access",
}

allowed, err := handle.TestPermissions(ctx, permissions)
if err != nil {
    log.Fatalf("failed to test permissions: %v", err)
}

fmt.Printf("Allowed permissions: %v\n", allowed)

Common IAM Roles

Secret Manager provides predefined roles for common access patterns:

roles/secretmanager.admin

Full access to all Secret Manager resources.

Permissions:

  • Create, read, update, and delete secrets
  • Add, access, enable, disable, and destroy secret versions
  • Manage IAM policies
  • All other Secret Manager permissions

Example:

policy := &iampb.Policy{
    Bindings: []*iampb.Binding{
        {
            Role: "roles/secretmanager.admin",
            Members: []string{
                "user:admin@example.com",
            },
        },
    },
}

roles/secretmanager.secretAccessor

Read access to secret versions (the actual secret data).

Permissions:

  • secretmanager.versions.access - Access secret version payloads
  • secretmanager.versions.get - Get secret version metadata
  • secretmanager.versions.list - List secret versions
  • secretmanager.secrets.get - Get secret metadata
  • secretmanager.secrets.list - List secrets

Example:

policy := &iampb.Policy{
    Bindings: []*iampb.Binding{
        {
            Role: "roles/secretmanager.secretAccessor",
            Members: []string{
                "serviceAccount:my-app@my-project.iam.gserviceaccount.com",
            },
        },
    },
}

roles/secretmanager.secretVersionManager

Manage secret versions without accessing secret data.

Permissions:

  • Add new secret versions
  • Enable, disable, and destroy secret versions
  • Get and list secret version metadata
  • Does NOT include secretmanager.versions.access

Example:

policy := &iampb.Policy{
    Bindings: []*iampb.Binding{
        {
            Role: "roles/secretmanager.secretVersionManager",
            Members: []string{
                "user:rotation-bot@example.com",
            },
        },
    },
}

roles/secretmanager.viewer

Read-only access to secret metadata (not secret data).

Permissions:

  • Get and list secrets
  • Get and list secret version metadata
  • Does NOT include secretmanager.versions.access

Example:

policy := &iampb.Policy{
    Bindings: []*iampb.Binding{
        {
            Role: "roles/secretmanager.viewer",
            Members: []string{
                "group:auditors@example.com",
            },
        },
    },
}

Common Permissions

Secret Permissions

  • secretmanager.secrets.create - Create new secrets
  • secretmanager.secrets.delete - Delete secrets
  • secretmanager.secrets.get - Get secret metadata
  • secretmanager.secrets.list - List secrets
  • secretmanager.secrets.update - Update secret metadata
  • secretmanager.secrets.getIamPolicy - Get IAM policy
  • secretmanager.secrets.setIamPolicy - Set IAM policy

Version Permissions

  • secretmanager.versions.access - Access secret version data
  • secretmanager.versions.add - Add new secret versions
  • secretmanager.versions.destroy - Destroy secret versions
  • secretmanager.versions.disable - Disable secret versions
  • secretmanager.versions.enable - Enable secret versions
  • secretmanager.versions.get - Get secret version metadata
  • secretmanager.versions.list - List secret versions

Best Practices

Principle of Least Privilege

Grant only the minimum permissions needed:

// Good: Application only needs to read secrets
policy := &iampb.Policy{
    Bindings: []*iampb.Binding{
        {
            Role: "roles/secretmanager.secretAccessor",
            Members: []string{
                "serviceAccount:app@my-project.iam.gserviceaccount.com",
            },
        },
    },
}

// Bad: Application granted admin access
policy := &iampb.Policy{
    Bindings: []*iampb.Binding{
        {
            Role: "roles/secretmanager.admin",
            Members: []string{
                "serviceAccount:app@my-project.iam.gserviceaccount.com",
            },
        },
    },
}

Use Service Accounts for Applications

Applications should use service accounts instead of user credentials:

policy := &iampb.Policy{
    Bindings: []*iampb.Binding{
        {
            Role: "roles/secretmanager.secretAccessor",
            Members: []string{
                "serviceAccount:web-app@my-project.iam.gserviceaccount.com",
                "serviceAccount:worker@my-project.iam.gserviceaccount.com",
            },
        },
    },
}

Use Conditions for Time-Bound Access

Grant temporary access using IAM conditions:

import "google.golang.org/genproto/googleapis/type/expr"

policy := &iampb.Policy{
    Bindings: []*iampb.Binding{
        {
            Role: "roles/secretmanager.secretAccessor",
            Members: []string{
                "user:contractor@example.com",
            },
            Condition: &expr.Expr{
                Title:      "Temporary access",
                Description: "Access expires on January 31, 2025",
                Expression: "request.time < timestamp('2025-01-31T23:59:59Z')",
            },
        },
    },
}

Separate Policies by Environment

Use different secrets for different environments:

// Production secret - strict access
prodPolicy := &iampb.Policy{
    Bindings: []*iampb.Binding{
        {
            Role: "roles/secretmanager.secretAccessor",
            Members: []string{
                "serviceAccount:prod-app@my-project.iam.gserviceaccount.com",
            },
        },
    },
}

prodReq := &iampb.SetIamPolicyRequest{
    Resource: "projects/my-project/secrets/api-key-prod",
    Policy:   prodPolicy,
}
client.SetIamPolicy(ctx, prodReq)

// Development secret - broader access
devPolicy := &iampb.Policy{
    Bindings: []*iampb.Binding{
        {
            Role: "roles/secretmanager.secretAccessor",
            Members: []string{
                "serviceAccount:dev-app@my-project.iam.gserviceaccount.com",
                "group:developers@example.com",
            },
        },
    },
}

devReq := &iampb.SetIamPolicyRequest{
    Resource: "projects/my-project/secrets/api-key-dev",
    Policy:   devPolicy,
}
client.SetIamPolicy(ctx, devReq)

Audit Policy Changes

Log IAM policy changes for security auditing:

// Get current policy for audit log
oldPolicy, err := client.GetIamPolicy(ctx, &iampb.GetIamPolicyRequest{
    Resource: "projects/my-project/secrets/my-api-key",
})

// Update policy
newPolicy := &iampb.Policy{
    Bindings: []*iampb.Binding{
        {
            Role:    "roles/secretmanager.secretAccessor",
            Members: []string{"user:new-user@example.com"},
        },
    },
}

updatedPolicy, err := client.SetIamPolicy(ctx, &iampb.SetIamPolicyRequest{
    Resource: "projects/my-project/secrets/my-api-key",
    Policy:   newPolicy,
})

// Log the change
log.Printf("IAM policy updated for secret my-api-key")
log.Printf("Old bindings: %v", oldPolicy.Bindings)
log.Printf("New bindings: %v", updatedPolicy.Bindings)

Member Formats

IAM members can be specified in various formats:

policy := &iampb.Policy{
    Bindings: []*iampb.Binding{
        {
            Role: "roles/secretmanager.secretAccessor",
            Members: []string{
                // Individual user
                "user:alice@example.com",

                // Service account
                "serviceAccount:my-service@my-project.iam.gserviceaccount.com",

                // Google group
                "group:developers@example.com",

                // Google Workspace domain
                "domain:example.com",

                // All authenticated users
                "allAuthenticatedUsers",

                // All users (public access - use with caution!)
                "allUsers",
            },
        },
    },
}

Warning: Never use allUsers for secrets containing sensitive data. This grants public access to anyone on the internet.