[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6F6R9CR2WV2090ZNWMXZ2AS":3,"skill-same:01M6F6R9CR2WV2090ZNWMXZ2AS":82},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":42,"linkOnly":43,"markdownContent":44,"markdownBody":45,"frontMatter":46,"refName":30,"commitSha":56,"skillDirectory":57,"forksCount":58,"repositoryHtmlUrl":59,"repositoryHomepageUrl":6,"ownerHtmlUrl":60,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":61,"install":62,"resources":75},"01M6F6R9CR2WV2090ZNWMXZ2AS","gcp-secret-manager",null,"Secure secrets in Google Cloud Secret Manager. Configure IAM policies, integrate with GKE, and manage secret versions. Use when managing secrets in GCP environments.","boisenoise\u002Fskills-collections","boisenoise","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F193180?v=4","01M6CDBDQK6BDN55ZMA6B6PKBM","01M6CDBDVSJ3JPTBYN26FZ7TZK",12,"MIT","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-gcp-secret-manager\u002FSKILL.md",[],[18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41],"manager","gcp","secret manager","gcp secret manager","community","2026","when","relevant","scripts","scope","critical","active","main","google","only","integrate","configure","secrets","devops-security","gke","iam","assessment","secure","google cloud","2026-11-10 10:12:30",false,"---\nname: gcp-secret-manager\ndescription: Secure secrets in Google Cloud Secret Manager. Configure IAM policies,\n  integrate with GKE, and manage secret versions. Use when managing secrets in GCP\n  environments.\ncategory: security\nrisk: critical\nsource: https:\u002F\u002Fgithub.com\u002FBagelHole\u002FDevOps-Security-Agent-Skills\nsource_repo: BagelHole\u002FDevOps-Security-Agent-Skills\nsource_type: community\ndate_added: '2026-09-20'\nlicense: MIT\nlicense_source: https:\u002F\u002Fgithub.com\u002FBagelHole\u002FDevOps-Security-Agent-Skills\u002Fblob\u002Fmain\u002FLICENSE\ncompatibility: Requires the relevant security tooling (scanners, vault CLIs) and an\n  authorized scope for any active assessment. Docs-only; helper scripts and templates\n  not bundled.\nmetadata:\n  author: devops-skills\n  version: '1.0'\n---\n\n# GCP Secret Manager\n\nStore and manage secrets securely in Google Cloud Platform.\n\n## Prerequisites\n\n- GCP project with billing enabled\n- `gcloud` CLI installed and authenticated\n- Secret Manager API enabled (`secretmanager.googleapis.com`)\n- IAM permissions: `roles\u002Fsecretmanager.admin` for management, `roles\u002Fsecretmanager.secretAccessor` for reading\n- For GKE: Workload Identity configured on the cluster\n\n## Enable the API\n\n```bash\n# Enable Secret Manager API\ngcloud services enable secretmanager.googleapis.com\n\n# Verify it's enabled\ngcloud services list --enabled --filter=\"name:secretmanager\"\n```\n\n## Secret Creation and Management\n\n```bash\n# Create a secret (creates the secret resource, not the value)\ngcloud secrets create db-password \\\n  --replication-policy=\"automatic\" \\\n  --labels=\"env=production,team=platform\"\n\n# Add the secret value (first version)\ngcloud secrets versions add db-password --data-file=\"\u002Fprivate\u002Fapproved-secret-input\"\n\n# Create secret with value in one command\ngcloud secrets create db-credentials --data-file=\"\u002Fprivate\u002Fapproved-credentials-input\" \\\n  --replication-policy=\"automatic\" \\\n  --labels=\"env=production,team=platform\"\n\n# Create with specific region replication\ngcloud secrets create regional-secret \\\n  --replication-policy=\"user-managed\" \\\n  --locations=\"us-central1,us-east1\"\n\n# Create with customer-managed encryption key (CMEK)\ngcloud secrets create sensitive-secret \\\n  --replication-policy=\"user-managed\" \\\n  --locations=\"us-central1\" \\\n  --kms-key-name=\"projects\u002Fmy-project\u002Flocations\u002Fus-central1\u002FkeyRings\u002Fmy-ring\u002FcryptoKeys\u002Fmy-key\"\n\n# Access the latest version\ngcloud secrets versions access latest --secret=db-password --out-file=\"\u002Fprivate\u002Fnew-secret-output\"\n\n# Access a specific version\ngcloud secrets versions access 3 --secret=db-password --out-file=\"\u002Fprivate\u002Fnew-version-output\"\n\n# Add a new version (rotation)\ngcloud secrets versions add db-password --data-file=\"\u002Fprivate\u002Fapproved-new-secret-input\"\n\n# List all secrets\ngcloud secrets list --format=\"table(name, createTime, labels)\"\n\n# List versions of a secret\ngcloud secrets versions list db-password --format=\"table(name, state, createTime)\"\n\n# Disable a version (makes it inaccessible but recoverable)\ngcloud secrets versions disable 1 --secret=db-password\n\n# Enable a disabled version\ngcloud secrets versions enable 1 --secret=db-password\n\n# Destroy a version (permanent)\ngcloud secrets versions destroy 1 --secret=db-password\n\n# Delete the entire secret\ngcloud secrets delete db-password\n\n# Set expiration on a secret\ngcloud secrets update db-password \\\n  --expire-time=\"2026-06-01T00:00:00Z\"\n\n# Set TTL-based expiration\ngcloud secrets update temp-token \\\n  --ttl=\"2592000s\"  # 30 days\n\n# Update labels\ngcloud secrets update db-password \\\n  --update-labels=\"rotation=enabled,last-rotated=2025-01-15\"\n\n# Add version aliases\ngcloud secrets update db-password --update-version-aliases=\"production=5\"\n```\n\n## IAM Bindings\n\n```bash\n# Grant secret accessor role to a service account\ngcloud secrets add-iam-policy-binding db-password \\\n  --member=\"serviceAccount:myapp-sa@my-project.iam.gserviceaccount.com\" \\\n  --role=\"roles\u002Fsecretmanager.secretAccessor\"\n\n# IAM secretAccessor is granted at the secret level, not a fictitious secretVersionAccessor role.\n# Separate secrets if different values need different reader permissions.\n\n# Grant admin to security team\ngcloud secrets add-iam-policy-binding db-password \\\n  --member=\"group:security-team@example.com\" \\\n  --role=\"roles\u002Fsecretmanager.admin\"\n\n# View IAM policy for a secret\ngcloud secrets get-iam-policy db-password\n\n# Remove access\ngcloud secrets remove-iam-policy-binding db-password \\\n  --member=\"serviceAccount:old-sa@my-project.iam.gserviceaccount.com\" \\\n  --role=\"roles\u002Fsecretmanager.secretAccessor\"\n\n# Project-level IAM for all secrets\ngcloud projects add-iam-policy-binding my-project \\\n  --member=\"serviceAccount:myapp-sa@my-project.iam.gserviceaccount.com\" \\\n  --role=\"roles\u002Fsecretmanager.secretAccessor\" \\\n  --condition='expression=resource.name.startsWith(\"projects\u002Fmy-project\u002Fsecrets\u002Fmyapp-\"),title=myapp-secrets-only'\n```\n\n## Workload Identity for GKE\n\n```bash\n# Enable Workload Identity on cluster (if not already)\ngcloud container clusters update my-cluster \\\n  --zone us-central1-a \\\n  --workload-pool=my-project.svc.id.goog\n\n# Create GCP service account for the workload\ngcloud iam service-accounts create myapp-gke-sa \\\n  --display-name=\"MyApp GKE Service Account\"\n\n# Grant secret accessor role\ngcloud secrets add-iam-policy-binding db-password \\\n  --member=\"serviceAccount:myapp-gke-sa@my-project.iam.gserviceaccount.com\" \\\n  --role=\"roles\u002Fsecretmanager.secretAccessor\"\n\n# Bind Kubernetes SA to GCP SA\ngcloud iam service-accounts add-iam-policy-binding \\\n  myapp-gke-sa@my-project.iam.gserviceaccount.com \\\n  --role=\"roles\u002Fiam.workloadIdentityUser\" \\\n  --member=\"serviceAccount:my-project.svc.id.goog[production\u002Fmyapp-sa]\"\n```\n\n### Kubernetes Manifests\n\n```yaml\n# Kubernetes service account annotated with GCP SA\napiVersion: v1\nkind: ServiceAccount\nmetadata:\n  name: myapp-sa\n  namespace: production\n  annotations:\n    iam.gke.io\u002Fgcp-service-account: \"myapp-gke-sa@my-project.iam.gserviceaccount.com\"\n---\n# Secrets Store CSI Driver for GCP\napiVersion: secrets-store.csi.x-k8s.io\u002Fv1\nkind: SecretProviderClass\nmetadata:\n  name: gcp-secrets\n  namespace: production\nspec:\n  provider: gcp\n  parameters:\n    secrets: |\n      - resourceName: \"projects\u002Fmy-project\u002Fsecrets\u002Fdb-password\u002Fversions\u002Flatest\"\n        path: \"db-password\"\n      - resourceName: \"projects\u002Fmy-project\u002Fsecrets\u002Fdb-credentials\u002Fversions\u002Flatest\"\n        path: \"db-credentials\"\n      - resourceName: \"projects\u002Fmy-project\u002Fsecrets\u002Fapi-key\u002Fversions\u002Flatest\"\n        path: \"api-key\"\n  secretObjects:\n    - secretName: myapp-secrets\n      type: Opaque\n      data:\n        - objectName: db-password\n          key: DB_PASSWORD\n        - objectName: api-key\n          key: API_KEY\n---\n# Deployment using the secrets\napiVersion: apps\u002Fv1\nkind: Deployment\nmetadata:\n  name: myapp\n  namespace: production\nspec:\n  replicas: 3\n  selector:\n    matchLabels:\n      app: myapp\n  template:\n    metadata:\n      labels:\n        app: myapp\n    spec:\n      serviceAccountName: myapp-sa\n      containers:\n        - name: myapp\n          image: gcr.io\u002Fmy-project\u002Fmyapp:v1.0.0\n          env:\n            - name: DB_PASSWORD\n              valueFrom:\n                secretKeyRef:\n                  name: myapp-secrets\n                  key: DB_PASSWORD\n          volumeMounts:\n            - name: secrets\n              mountPath: \"\u002Fvar\u002Fsecrets\"\n              readOnly: true\n      volumes:\n        - name: secrets\n          csi:\n            driver: secrets-store.csi.k8s.io\n            readOnly: true\n            volumeAttributes:\n              secretProviderClass: \"gcp-secrets\"\n```\n\n## Application SDK Examples\n\n### Python\n\n```python\nfrom google.cloud import secretmanager\nfrom google.api_core import exceptions\nimport json\n\ndef get_secret(project_id: str, secret_id: str, version: str = \"latest\") -> str:\n    \"\"\"Access a secret version from GCP Secret Manager.\"\"\"\n    client = secretmanager.SecretManagerServiceClient()\n    name = f\"projects\u002F{project_id}\u002Fsecrets\u002F{secret_id}\u002Fversions\u002F{version}\"\n\n    try:\n        response = client.access_secret_version(request={\"name\": name}, timeout=10)\n        return response.payload.data.decode(\"UTF-8\")\n    except exceptions.NotFound:\n        raise ValueError(f\"Secret {secret_id} version {version} not found\")\n    except exceptions.PermissionDenied:\n        raise PermissionError(f\"No access to secret {secret_id}\")\n\ndef get_json_secret(project_id: str, secret_id: str) -> dict:\n    \"\"\"Access and parse a JSON secret.\"\"\"\n    raw = get_secret(project_id, secret_id)\n    return json.loads(raw)\n\ndef create_secret(project_id: str, secret_id: str, value: str, labels: dict = None) -> str:\n    \"\"\"Create a new secret with an initial version.\"\"\"\n    client = secretmanager.SecretManagerServiceClient()\n    parent = f\"projects\u002F{project_id}\"\n\n    secret_config = {\n        \"replication\": {\"automatic\": {}},\n    }\n    if labels:\n        secret_config[\"labels\"] = labels\n\n    secret = client.create_secret(\n        request={\"parent\": parent, \"secret_id\": secret_id, \"secret\": secret_config}\n    )\n\n    client.add_secret_version(\n        request={\"parent\": secret.name, \"payload\": {\"data\": value.encode(\"UTF-8\")}}\n    )\n    return secret.name\n\ndef rotate_secret(project_id: str, secret_id: str, new_value: str) -> str:\n    \"\"\"Add a new version to rotate the secret.\"\"\"\n    client = secretmanager.SecretManagerServiceClient()\n    parent = f\"projects\u002F{project_id}\u002Fsecrets\u002F{secret_id}\"\n\n    version = client.add_secret_version(\n        request={\"parent\": parent, \"payload\": {\"data\": new_value.encode(\"UTF-8\")}}\n    )\n    return version.name\n\ndef list_secrets(project_id: str, filter_str: str = \"\") -> list:\n    \"\"\"List all secrets in a project.\"\"\"\n    client = secretmanager.SecretManagerServiceClient()\n    parent = f\"projects\u002F{project_id}\"\n\n    secrets = []\n    for secret in client.list_secrets(request={\"parent\": parent, \"filter\": filter_str}):\n        secrets.append({\n            \"name\": secret.name.split(\"\u002F\")[-1],\n            \"created\": secret.create_time.isoformat(),\n            \"labels\": dict(secret.labels),\n        })\n    return secrets\n\n# Usage: pass validated fields directly to the database driver's keyword arguments,\n# with TLS hostname verification. Do not concatenate credentials into a logged URI.\ncreds = get_json_secret(\"my-project\", \"db-credentials\")\n```\n\n### Go\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"fmt\"\n    \"log\"\n    \"time\"\n\n    secretmanager \"cloud.google.com\u002Fgo\u002Fsecretmanager\u002Fapiv1\"\n    secretmanagerpb \"cloud.google.com\u002Fgo\u002Fsecretmanager\u002Fapiv1\u002Fsecretmanagerpb\"\n)\n\nfunc getSecret(projectID, secretID, version string) (string, error) {\n    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)\n    defer cancel()\n    client, err := secretmanager.NewClient(ctx)\n    if err != nil {\n        return \"\", fmt.Errorf(\"failed to create client: %w\", err)\n    }\n    defer client.Close()\n\n    name := fmt.Sprintf(\"projects\u002F%s\u002Fsecrets\u002F%s\u002Fversions\u002F%s\", projectID, secretID, version)\n    result, err := client.AccessSecretVersion(ctx, &secretmanagerpb.AccessSecretVersionRequest{\n        Name: name,\n    })\n    if err != nil {\n        return \"\", fmt.Errorf(\"failed to access secret: %w\", err)\n    }\n\n    return string(result.Payload.Data), nil\n}\n\nfunc main() {\n    secret, err := getSecret(\"my-project\", \"db-password\", \"latest\")\n    if err != nil {\n        log.Fatalf(\"Error: %v\", err)\n    }\n    _ = secret \u002F\u002F Pass directly to the authorized consumer; never print the payload.\n    fmt.Println(\"Secret retrieved\")\n}\n```\n\n### Node.js\n\n```javascript\nconst { SecretManagerServiceClient } = require('@google-cloud\u002Fsecret-manager');\n\nconst client = new SecretManagerServiceClient();\n\nasync function getSecret(projectId, secretId, version = 'latest') {\n  const name = `projects\u002F${projectId}\u002Fsecrets\u002F${secretId}\u002Fversions\u002F${version}`;\n  const [response] = await client.accessSecretVersion({ name });\n  return response.payload.data.toString('utf8');\n}\n\nasync function main() {\n  const password = await getSecret('my-project', 'db-password');\n  console.log(\"Secret retrieved\"); \u002F\u002F Do not disclose payload or length\n}\n\nmain().catch(() => { console.error(\"Secret access failed\"); process.exitCode = 1; });\n```\n\n\n## Contents\n\n- [Secret Rotation with Cloud Functions](references\u002Fdetails.md)\n- [Terraform Configuration](references\u002Fdetails.md)\n- [Troubleshooting](references\u002Fdetails.md)\n- [Best Practices](references\u002Fdetails.md)\n- [Related Skills](references\u002Fdetails.md)\n\n## When to Use This Skill\n\nUse this skill when:\n- Managing secrets in GCP environments\n- Integrating secrets with GKE workloads via Workload Identity\n- Storing API keys, database credentials, or TLS certificates\n- Implementing secret versioning and rotation\n- Meeting compliance requirements for centralized secret management\n\n## Limitations\n\n- Apply guidance only within authorized scope; test destructive steps in non-production first.\n- Docs-only import: upstream scripts and templates not bundled.\n\n### Example\n\n```bash\n# Read-only first: inventory before any active step.\nwhich \u003Ctool> && \u003Ctool> --help | head -n 20\n```\n\n> Adapted from [BagelHole\u002FDevOps-Security-Agent-Skills](https:\u002F\u002Fgithub.com\u002FBagelHole\u002FDevOps-Security-Agent-Skills) (MIT); frontmatter, When to Use\u002FLimitations, and safety boundaries added for upstream compliance. Docs-only import: helper scripts and templates not bundled.\n\n## Operational boundaries\n\nUse explicit project\u002Fregion and verify active identity before mutation. Admin is not a reader prerequisite; choose the minimum task-specific permissions. Private input\u002Foutput paths are placeholders, not bundled files: create new protected files under restrictive umask, never log content and clean up after use. Pin production numeric versions and roll out gradually; latest can change immediately. User-managed replication locations describe a globally named replicated secret, distinct from the regional-secret API. CSI manifest is the open-source driver\u002Fprovider path and needs compatible installed CRDs, provider and sync support; do not mix it with the managed GKE add-on schema. Syncing to Kubernetes Secrets creates another sensitive copy; env vars do not automatically refresh on rotation. Node pools may need Workload Identity metadata configuration as well as cluster configuration.\n\nDestroy\u002Fdelete\u002Fexpiration can break consumers or remove recovery options; confirm exact versions and retention policy. Adding a version does not update a database password or revoke an old credential. SDK samples omit CRC32C verification and complete retry\u002Ftransaction\u002Frecovery handling; implement integrity verification using the official sample and avoid logging errors that reveal values. Terraform secret_data can persist in state despite sensitive variables, so protect state and access.\n","# GCP Secret Manager\n\nStore and manage secrets securely in Google Cloud Platform.\n\n## Prerequisites\n\n- GCP project with billing enabled\n- `gcloud` CLI installed and authenticated\n- Secret Manager API enabled (`secretmanager.googleapis.com`)\n- IAM permissions: `roles\u002Fsecretmanager.admin` for management, `roles\u002Fsecretmanager.secretAccessor` for reading\n- For GKE: Workload Identity configured on the cluster\n\n## Enable the API\n\n```bash\n# Enable Secret Manager API\ngcloud services enable secretmanager.googleapis.com\n\n# Verify it's enabled\ngcloud services list --enabled --filter=\"name:secretmanager\"\n```\n\n## Secret Creation and Management\n\n```bash\n# Create a secret (creates the secret resource, not the value)\ngcloud secrets create db-password \\\n  --replication-policy=\"automatic\" \\\n  --labels=\"env=production,team=platform\"\n\n# Add the secret value (first version)\ngcloud secrets versions add db-password --data-file=\"\u002Fprivate\u002Fapproved-secret-input\"\n\n# Create secret with value in one command\ngcloud secrets create db-credentials --data-file=\"\u002Fprivate\u002Fapproved-credentials-input\" \\\n  --replication-policy=\"automatic\" \\\n  --labels=\"env=production,team=platform\"\n\n# Create with specific region replication\ngcloud secrets create regional-secret \\\n  --replication-policy=\"user-managed\" \\\n  --locations=\"us-central1,us-east1\"\n\n# Create with customer-managed encryption key (CMEK)\ngcloud secrets create sensitive-secret \\\n  --replication-policy=\"user-managed\" \\\n  --locations=\"us-central1\" \\\n  --kms-key-name=\"projects\u002Fmy-project\u002Flocations\u002Fus-central1\u002FkeyRings\u002Fmy-ring\u002FcryptoKeys\u002Fmy-key\"\n\n# Access the latest version\ngcloud secrets versions access latest --secret=db-password --out-file=\"\u002Fprivate\u002Fnew-secret-output\"\n\n# Access a specific version\ngcloud secrets versions access 3 --secret=db-password --out-file=\"\u002Fprivate\u002Fnew-version-output\"\n\n# Add a new version (rotation)\ngcloud secrets versions add db-password --data-file=\"\u002Fprivate\u002Fapproved-new-secret-input\"\n\n# List all secrets\ngcloud secrets list --format=\"table(name, createTime, labels)\"\n\n# List versions of a secret\ngcloud secrets versions list db-password --format=\"table(name, state, createTime)\"\n\n# Disable a version (makes it inaccessible but recoverable)\ngcloud secrets versions disable 1 --secret=db-password\n\n# Enable a disabled version\ngcloud secrets versions enable 1 --secret=db-password\n\n# Destroy a version (permanent)\ngcloud secrets versions destroy 1 --secret=db-password\n\n# Delete the entire secret\ngcloud secrets delete db-password\n\n# Set expiration on a secret\ngcloud secrets update db-password \\\n  --expire-time=\"2026-06-01T00:00:00Z\"\n\n# Set TTL-based expiration\ngcloud secrets update temp-token \\\n  --ttl=\"2592000s\"  # 30 days\n\n# Update labels\ngcloud secrets update db-password \\\n  --update-labels=\"rotation=enabled,last-rotated=2025-01-15\"\n\n# Add version aliases\ngcloud secrets update db-password --update-version-aliases=\"production=5\"\n```\n\n## IAM Bindings\n\n```bash\n# Grant secret accessor role to a service account\ngcloud secrets add-iam-policy-binding db-password \\\n  --member=\"serviceAccount:myapp-sa@my-project.iam.gserviceaccount.com\" \\\n  --role=\"roles\u002Fsecretmanager.secretAccessor\"\n\n# IAM secretAccessor is granted at the secret level, not a fictitious secretVersionAccessor role.\n# Separate secrets if different values need different reader permissions.\n\n# Grant admin to security team\ngcloud secrets add-iam-policy-binding db-password \\\n  --member=\"group:security-team@example.com\" \\\n  --role=\"roles\u002Fsecretmanager.admin\"\n\n# View IAM policy for a secret\ngcloud secrets get-iam-policy db-password\n\n# Remove access\ngcloud secrets remove-iam-policy-binding db-password \\\n  --member=\"serviceAccount:old-sa@my-project.iam.gserviceaccount.com\" \\\n  --role=\"roles\u002Fsecretmanager.secretAccessor\"\n\n# Project-level IAM for all secrets\ngcloud projects add-iam-policy-binding my-project \\\n  --member=\"serviceAccount:myapp-sa@my-project.iam.gserviceaccount.com\" \\\n  --role=\"roles\u002Fsecretmanager.secretAccessor\" \\\n  --condition='expression=resource.name.startsWith(\"projects\u002Fmy-project\u002Fsecrets\u002Fmyapp-\"),title=myapp-secrets-only'\n```\n\n## Workload Identity for GKE\n\n```bash\n# Enable Workload Identity on cluster (if not already)\ngcloud container clusters update my-cluster \\\n  --zone us-central1-a \\\n  --workload-pool=my-project.svc.id.goog\n\n# Create GCP service account for the workload\ngcloud iam service-accounts create myapp-gke-sa \\\n  --display-name=\"MyApp GKE Service Account\"\n\n# Grant secret accessor role\ngcloud secrets add-iam-policy-binding db-password \\\n  --member=\"serviceAccount:myapp-gke-sa@my-project.iam.gserviceaccount.com\" \\\n  --role=\"roles\u002Fsecretmanager.secretAccessor\"\n\n# Bind Kubernetes SA to GCP SA\ngcloud iam service-accounts add-iam-policy-binding \\\n  myapp-gke-sa@my-project.iam.gserviceaccount.com \\\n  --role=\"roles\u002Fiam.workloadIdentityUser\" \\\n  --member=\"serviceAccount:my-project.svc.id.goog[production\u002Fmyapp-sa]\"\n```\n\n### Kubernetes Manifests\n\n```yaml\n# Kubernetes service account annotated with GCP SA\napiVersion: v1\nkind: ServiceAccount\nmetadata:\n  name: myapp-sa\n  namespace: production\n  annotations:\n    iam.gke.io\u002Fgcp-service-account: \"myapp-gke-sa@my-project.iam.gserviceaccount.com\"\n---\n# Secrets Store CSI Driver for GCP\napiVersion: secrets-store.csi.x-k8s.io\u002Fv1\nkind: SecretProviderClass\nmetadata:\n  name: gcp-secrets\n  namespace: production\nspec:\n  provider: gcp\n  parameters:\n    secrets: |\n      - resourceName: \"projects\u002Fmy-project\u002Fsecrets\u002Fdb-password\u002Fversions\u002Flatest\"\n        path: \"db-password\"\n      - resourceName: \"projects\u002Fmy-project\u002Fsecrets\u002Fdb-credentials\u002Fversions\u002Flatest\"\n        path: \"db-credentials\"\n      - resourceName: \"projects\u002Fmy-project\u002Fsecrets\u002Fapi-key\u002Fversions\u002Flatest\"\n        path: \"api-key\"\n  secretObjects:\n    - secretName: myapp-secrets\n      type: Opaque\n      data:\n        - objectName: db-password\n          key: DB_PASSWORD\n        - objectName: api-key\n          key: API_KEY\n---\n# Deployment using the secrets\napiVersion: apps\u002Fv1\nkind: Deployment\nmetadata:\n  name: myapp\n  namespace: production\nspec:\n  replicas: 3\n  selector:\n    matchLabels:\n      app: myapp\n  template:\n    metadata:\n      labels:\n        app: myapp\n    spec:\n      serviceAccountName: myapp-sa\n      containers:\n        - name: myapp\n          image: gcr.io\u002Fmy-project\u002Fmyapp:v1.0.0\n          env:\n            - name: DB_PASSWORD\n              valueFrom:\n                secretKeyRef:\n                  name: myapp-secrets\n                  key: DB_PASSWORD\n          volumeMounts:\n            - name: secrets\n              mountPath: \"\u002Fvar\u002Fsecrets\"\n              readOnly: true\n      volumes:\n        - name: secrets\n          csi:\n            driver: secrets-store.csi.k8s.io\n            readOnly: true\n            volumeAttributes:\n              secretProviderClass: \"gcp-secrets\"\n```\n\n## Application SDK Examples\n\n### Python\n\n```python\nfrom google.cloud import secretmanager\nfrom google.api_core import exceptions\nimport json\n\ndef get_secret(project_id: str, secret_id: str, version: str = \"latest\") -> str:\n    \"\"\"Access a secret version from GCP Secret Manager.\"\"\"\n    client = secretmanager.SecretManagerServiceClient()\n    name = f\"projects\u002F{project_id}\u002Fsecrets\u002F{secret_id}\u002Fversions\u002F{version}\"\n\n    try:\n        response = client.access_secret_version(request={\"name\": name}, timeout=10)\n        return response.payload.data.decode(\"UTF-8\")\n    except exceptions.NotFound:\n        raise ValueError(f\"Secret {secret_id} version {version} not found\")\n    except exceptions.PermissionDenied:\n        raise PermissionError(f\"No access to secret {secret_id}\")\n\ndef get_json_secret(project_id: str, secret_id: str) -> dict:\n    \"\"\"Access and parse a JSON secret.\"\"\"\n    raw = get_secret(project_id, secret_id)\n    return json.loads(raw)\n\ndef create_secret(project_id: str, secret_id: str, value: str, labels: dict = None) -> str:\n    \"\"\"Create a new secret with an initial version.\"\"\"\n    client = secretmanager.SecretManagerServiceClient()\n    parent = f\"projects\u002F{project_id}\"\n\n    secret_config = {\n        \"replication\": {\"automatic\": {}},\n    }\n    if labels:\n        secret_config[\"labels\"] = labels\n\n    secret = client.create_secret(\n        request={\"parent\": parent, \"secret_id\": secret_id, \"secret\": secret_config}\n    )\n\n    client.add_secret_version(\n        request={\"parent\": secret.name, \"payload\": {\"data\": value.encode(\"UTF-8\")}}\n    )\n    return secret.name\n\ndef rotate_secret(project_id: str, secret_id: str, new_value: str) -> str:\n    \"\"\"Add a new version to rotate the secret.\"\"\"\n    client = secretmanager.SecretManagerServiceClient()\n    parent = f\"projects\u002F{project_id}\u002Fsecrets\u002F{secret_id}\"\n\n    version = client.add_secret_version(\n        request={\"parent\": parent, \"payload\": {\"data\": new_value.encode(\"UTF-8\")}}\n    )\n    return version.name\n\ndef list_secrets(project_id: str, filter_str: str = \"\") -> list:\n    \"\"\"List all secrets in a project.\"\"\"\n    client = secretmanager.SecretManagerServiceClient()\n    parent = f\"projects\u002F{project_id}\"\n\n    secrets = []\n    for secret in client.list_secrets(request={\"parent\": parent, \"filter\": filter_str}):\n        secrets.append({\n            \"name\": secret.name.split(\"\u002F\")[-1],\n            \"created\": secret.create_time.isoformat(),\n            \"labels\": dict(secret.labels),\n        })\n    return secrets\n\n# Usage: pass validated fields directly to the database driver's keyword arguments,\n# with TLS hostname verification. Do not concatenate credentials into a logged URI.\ncreds = get_json_secret(\"my-project\", \"db-credentials\")\n```\n\n### Go\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"fmt\"\n    \"log\"\n    \"time\"\n\n    secretmanager \"cloud.google.com\u002Fgo\u002Fsecretmanager\u002Fapiv1\"\n    secretmanagerpb \"cloud.google.com\u002Fgo\u002Fsecretmanager\u002Fapiv1\u002Fsecretmanagerpb\"\n)\n\nfunc getSecret(projectID, secretID, version string) (string, error) {\n    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)\n    defer cancel()\n    client, err := secretmanager.NewClient(ctx)\n    if err != nil {\n        return \"\", fmt.Errorf(\"failed to create client: %w\", err)\n    }\n    defer client.Close()\n\n    name := fmt.Sprintf(\"projects\u002F%s\u002Fsecrets\u002F%s\u002Fversions\u002F%s\", projectID, secretID, version)\n    result, err := client.AccessSecretVersion(ctx, &secretmanagerpb.AccessSecretVersionRequest{\n        Name: name,\n    })\n    if err != nil {\n        return \"\", fmt.Errorf(\"failed to access secret: %w\", err)\n    }\n\n    return string(result.Payload.Data), nil\n}\n\nfunc main() {\n    secret, err := getSecret(\"my-project\", \"db-password\", \"latest\")\n    if err != nil {\n        log.Fatalf(\"Error: %v\", err)\n    }\n    _ = secret \u002F\u002F Pass directly to the authorized consumer; never print the payload.\n    fmt.Println(\"Secret retrieved\")\n}\n```\n\n### Node.js\n\n```javascript\nconst { SecretManagerServiceClient } = require('@google-cloud\u002Fsecret-manager');\n\nconst client = new SecretManagerServiceClient();\n\nasync function getSecret(projectId, secretId, version = 'latest') {\n  const name = `projects\u002F${projectId}\u002Fsecrets\u002F${secretId}\u002Fversions\u002F${version}`;\n  const [response] = await client.accessSecretVersion({ name });\n  return response.payload.data.toString('utf8');\n}\n\nasync function main() {\n  const password = await getSecret('my-project', 'db-password');\n  console.log(\"Secret retrieved\"); \u002F\u002F Do not disclose payload or length\n}\n\nmain().catch(() => { console.error(\"Secret access failed\"); process.exitCode = 1; });\n```\n\n\n## Contents\n\n- [Secret Rotation with Cloud Functions](references\u002Fdetails.md)\n- [Terraform Configuration](references\u002Fdetails.md)\n- [Troubleshooting](references\u002Fdetails.md)\n- [Best Practices](references\u002Fdetails.md)\n- [Related Skills](references\u002Fdetails.md)\n\n## When to Use This Skill\n\nUse this skill when:\n- Managing secrets in GCP environments\n- Integrating secrets with GKE workloads via Workload Identity\n- Storing API keys, database credentials, or TLS certificates\n- Implementing secret versioning and rotation\n- Meeting compliance requirements for centralized secret management\n\n## Limitations\n\n- Apply guidance only within authorized scope; test destructive steps in non-production first.\n- Docs-only import: upstream scripts and templates not bundled.\n\n### Example\n\n```bash\n# Read-only first: inventory before any active step.\nwhich \u003Ctool> && \u003Ctool> --help | head -n 20\n```\n\n> Adapted from [BagelHole\u002FDevOps-Security-Agent-Skills](https:\u002F\u002Fgithub.com\u002FBagelHole\u002FDevOps-Security-Agent-Skills) (MIT); frontmatter, When to Use\u002FLimitations, and safety boundaries added for upstream compliance. Docs-only import: helper scripts and templates not bundled.\n\n## Operational boundaries\n\nUse explicit project\u002Fregion and verify active identity before mutation. Admin is not a reader prerequisite; choose the minimum task-specific permissions. Private input\u002Foutput paths are placeholders, not bundled files: create new protected files under restrictive umask, never log content and clean up after use. Pin production numeric versions and roll out gradually; latest can change immediately. User-managed replication locations describe a globally named replicated secret, distinct from the regional-secret API. CSI manifest is the open-source driver\u002Fprovider path and needs compatible installed CRDs, provider and sync support; do not mix it with the managed GKE add-on schema. Syncing to Kubernetes Secrets creates another sensitive copy; env vars do not automatically refresh on rotation. Node pools may need Workload Identity metadata configuration as well as cluster configuration.\n\nDestroy\u002Fdelete\u002Fexpiration can break consumers or remove recovery options; confirm exact versions and retention policy. Adding a version does not update a database password or revoke an old credential. SDK samples omit CRC32C verification and complete retry\u002Ftransaction\u002Frecovery handling; implement integrity verification using the official sample and avoid logging errors that reveal values. Terraform secret_data can persist in state despite sensitive variables, so protect state and access.\n",{"name":5,"risk":28,"source":47,"license":14,"category":48,"metadata":49,"date_added":52,"description":7,"source_repo":53,"source_type":22,"compatibility":54,"license_source":55},"https:\u002F\u002Fgithub.com\u002FBagelHole\u002FDevOps-Security-Agent-Skills","security",{"author":50,"version":51},"devops-skills","1.0","2026-09-20","BagelHole\u002FDevOps-Security-Agent-Skills","Requires the relevant security tooling (scanners, vault CLIs) and an authorized scope for any active assessment. Docs-only; helper scripts and templates not bundled.","https:\u002F\u002Fgithub.com\u002FBagelHole\u002FDevOps-Security-Agent-Skills\u002Fblob\u002Fmain\u002FLICENSE","7bf2279c8a65758319526a721d5c4b75683aec9c","skills\u002Fantigravity-gcp-secret-manager",3,"https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections","https:\u002F\u002Fgithub.com\u002Fboisenoise","2026-11-13 14:20:47",{"source":8,"skillName":5,"commands":63,"prompt":73,"zipAvailable":74},[64,67,70],{"tool":65,"command":66},"npx","npx skills add boisenoise\u002Fskills-collections --skill gcp-secret-manager",{"tool":68,"command":69},"bunx","bunx skills add boisenoise\u002Fskills-collections --skill gcp-secret-manager",{"tool":71,"command":72},"pnpm","pnpm dlx skills add boisenoise\u002Fskills-collections --skill gcp-secret-manager","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-gcp-secret-manager\u002FSKILL.md",true,[76],{"path":77,"resourceType":78,"resourceTypeDesc":79,"sizeBytes":80,"sourceHtmlUrl":81},"references\u002Fdetails.md","REFERENCE","参考文档",5103,"https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-gcp-secret-manager\u002Freferences\u002Fdetails.md",[83,109,137,163,182,205],{"skillNo":84,"name":85,"nameZh":6,"description":86,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":87,"licenseFileUrl":88,"sourceHtmlUrl":89,"categories":90,"keywords":91,"publishedAt":42},"01M6WNH92BHVFXHGPDZCPJ0AG0","web-access","Use Treg for public web or platform data only when existing search, browser and connected tools cannot cover the task, with explicit cost and data boundaries.","Apache-2.0","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-web-access\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-web-access\u002FSKILL.md",[],[92,93,94,95,96,97,98,99,100,101,102,32,103,104,105,28,106,107,108,24,23],"web","access","web access","official","development","browser","search","data","Tools","read","fetch","youtube","free tools","platform","free","cover","normal",{"skillNo":110,"name":111,"nameZh":6,"description":112,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":87,"licenseFileUrl":113,"sourceHtmlUrl":114,"categories":115,"keywords":121,"publishedAt":42},"01M6WNF9XAYAB2CZDDJBAKNM93","treg","Use the Treg CLI or MCP catalog to discover, price and call authorized external tools with team-scoped credentials and a user-approved budget.","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-treg\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-treg\u002FSKILL.md",[116],{"categoryNo":117,"categoryName":118,"taxonomyType":119,"taxonomyTypeDesc":120},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[111,122,123,124,95,96,125,100,126,127,128,129,130,131,132,28,133,134,135,136,23],"MCP","cli","github","license","Budget","credentials","team","catalog","use","call","discover","external tools","with","scoped","blob",{"skillNo":138,"name":139,"nameZh":6,"description":140,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":87,"licenseFileUrl":141,"sourceHtmlUrl":142,"categories":143,"keywords":149,"publishedAt":42},"01M6WN93MEAZ4E41DYAHJRPHQT","recruit","Turn a job description into an evidence-linked candidate shortlist through Treg, with job-related ranking and optional authorized business contact enrichment.","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-recruit\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-recruit\u002FSKILL.md",[144],{"categoryNo":145,"categoryName":146,"taxonomyType":147,"taxonomyTypeDesc":148},"01JBSEEDCAT000000000000038","人力资源","PROFESSION","适用职业",[139,124,95,125,150,151,152,153,154,155,28,156,157,158,134,159,160,161,162,136,111,23],"https","email","enrichment","business","evidence","phone","ranking","post","job description","for","person","candidate","reason",{"skillNo":164,"name":165,"nameZh":6,"description":166,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":87,"licenseFileUrl":167,"sourceHtmlUrl":168,"categories":169,"keywords":170,"publishedAt":42},"01M6WN8R5RXSMHM9B4D9FAFX42","rea-growth","Analyze a company’s public growth and content through Treg, distinguish observations from hypotheses, and produce an evidence-linked playbook within an approved budget.","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-rea-growth\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-rea-growth\u002FSKILL.md",[],[171,172,173,124,95,125,174,175,150,176,126,177,178,179,154,28,180,181,136,111,23],"growth","rea","rea growth","produce","content","playbook","marketing","analyze","public","observations","company",{"skillNo":183,"name":184,"nameZh":6,"description":185,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":87,"licenseFileUrl":186,"sourceHtmlUrl":187,"categories":188,"keywords":189,"publishedAt":42},"01M6WN2EVE3RQRGWAKBT4S7YT2","make-ugc","Create original AI UGC-style product videos through Treg: research hooks, approve a licensed presenter and voice, generate clips, add captions and report costs.","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-make-ugc\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-make-ugc\u002FSKILL.md",[],[190,191,124,192,95,193,125,194,195,196,197,198,28,199,200,201,202,203,204,136],"make","make ugc","research","create","Video","Captions","ads","short","hooks","head","style","niche","trending","talking-head","approve",{"skillNo":206,"name":207,"nameZh":6,"description":208,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":87,"licenseFileUrl":209,"sourceHtmlUrl":210,"categories":211,"keywords":212,"publishedAt":42},"01M6WN10ARAA63Y8K1YNGXJ2RM","lead-signals","Find and qualify public buying signals through Treg, rank fitting business accounts and optionally enrich authorized business contact information.","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-lead-signals\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-lead-signals\u002FSKILL.md",[],[213,214,215,124,95,125,216,217,153,218,219,28,220,221,222,223,224,225,226,136],"signals","lead","lead signals","how","find","ready","as","how to","qualify","people","information","enrich","changes","funding"]