首页
/ CI/CD Secrets Management 技能实战:在 agents 插件生态中用 Vault、AWS Secrets Manager 与原生平台方案守护流水线密钥

CI/CD Secrets Management 技能实战:在 agents 插件生态中用 Vault、AWS Secrets Manager 与原生平台方案守护流水线密钥

2026-09-08 16:32:46作者:姚月梅Lane

本文深度拆解 agents 仓库中 cicd-automation 插件的 secrets-management 技能:它是一份可直接分发给 Claude Code、Codex、Cursor、OpenCode、Copilot、Antigravity 等多 harness 的专用知识包,面向在 CI/CD 流水线中安全存储、注入、轮换与扫描密钥的场景。读完本文你将掌握 HashiCorp Vault 与 AWS Secrets Manager 的完整接入步骤、GitHub/GitLab 原生变量与保护机制、External Secrets Operator 的 Kubernetes 集成、自动/手动密钥轮换流程,以及 TruffleHog 驱动的提交前与流水线双轨密钥扫描方案。

技能定位:何时激活 secrets-management

在 agents 仓库的插件体系中,每个 skill 通过 YAML frontmatter 声明 name 与激活条件。该技能 frontmatter 定义如下(SKILL.md):

---
name: secrets-management
description: Implement secure secrets management for CI/CD pipelines using Vault, AWS Secrets Manager, or native platform solutions. Use when handling sensitive credentials, rotating secrets, or securing CI/CD environments.
---

docs/agent-skills.md 的说明,Agent Skills 采用「元数据 → 指令 → 资源」三层渐进式披露(Progressive Disclosure)机制,元数据层始终加载,指令层在技能被激活时加载,示例与模板按需读取。这意味着 description 中的 Use when ... 触发短语是自动激活的关键,以下场景命中即可拉起本技能:

  • 存储 API Key 与各类凭据(Store API keys and credentials)
  • 管理数据库密码(Manage database passwords)
  • 处理 TLS 证书(Handle TLS certificates)
  • 自动轮换密钥(Rotate secrets automatically)
  • 落地最小权限访问(Implement least-privilege access)

技能的本体是一份独立、自洽的 Markdown,位于 plugins/{plugin}/skills/{skill-name}/SKILL.md,与仓库校验工具 tools/validate_generated.py 中对技能的校验约束一一对应(frontmatter 必须存在 name/description,且 name 必须与所在目录名 secrets-management 一致,description 必须非空并包含触发短语)。这套技能化设计的目标很明确:在 CI/CD 流水线中实现安全的密钥管理,杜绝把敏感信息硬编码进代码或配置文件

四大密钥管理方案能力对照

技能文档首先给出业界主流方案的能力矩阵,选择时按你所在平台与基础设施栈对号入座:

方案 核心能力 典型适用场景
HashiCorp Vault 集中式密钥管理(Centralized secrets management)、动态密钥生成(Dynamic secrets)、密钥轮换(Secret rotation)、审计日志(Audit logging)、细粒度访问控制 多云/多集群统一密钥面,需要动态凭据与审计合规
AWS Secrets Manager AWS 原生方案、自动轮换(Automatic rotation)、与 RDS 集成、CloudFormation 支持 运行于 AWS 的应用,尤其 RDS 数据库凭据
Azure Key Vault Azure 原生方案、HSM 背书密钥、证书管理、RBAC 集成 运行于 Azure,需要托管证书与硬件安全模块
Google Secret Manager GCP 原生方案、版本化(Versioning)、IAM 集成 运行于 GCP,需要按 IAM 授权的版本化密钥

这四类方案在仓库的 agent 视角中同样被反复强调:cloud-architect.md 将「HashiCorp Vault、云原生密钥库、轮换策略」列为安全与合规能力的必选项,deployment-engineer.md 则在 GitOps 配置管理中明确覆盖 External Secrets Operator、Sealed Secrets、Vault 集成。可见该技能与 CI/CD 插件族在工程语义上是严格对齐的。

HashiCorp Vault 端到端集成

本地启动与 KV v2 存储

Vault 支持以 -dev 模式快速拉起单机实例,适合本地验证与管道联调,其中 kv-v2 是支持版本化的键值引擎:

# Start Vault dev server
vault server -dev

# Set environment
export VAULT_ADDR='http://127.0.0.1:8200'
export VAULT_TOKEN='root'

# Enable secrets engine
vault secrets enable -path=secret kv-v2

# Store secret
vault kv put secret/database/config username=admin password=secret

需要理解几个底层细节,便于迁移到生产:

  • VAULT_ADDR:Vault 客户端与 SDK 默认读取的 API 地址环境变量,生产通常指向负载均衡后的 https://vault.example.com:8200
  • VAULT_TOKEN:dev 模式默认 root token,生产环境必须改用身份方法(Kubernetes auth、AppRole、OIDC 等)签发短期 token,严禁在配置文件中平铺存放;
  • kv-v2 与 kv v1 的路径差异:启用 kv-v2 后,读取逻辑路径为 secret/data/<path>(CLI 的 vault kv get 会自动处理),技能中 GitHub Actions 示例将 secret/data/database 作为读取路径正是基于这一引擎行为;
  • vault kv put secret/database/config ...:kv-v2 下写入产生新版本,天然支持密钥版本回溯,与 Google Secret Manager 的 Versioning 能力同构。

GitHub Actions 中拉取 Vault 密钥

官方 hashicorp/vault-action@v2 在作业内完成认证并注入环境变量,无需在 run 脚本里手写 Vault CLI:

name: Deploy with Vault Secrets

on: [push]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Import Secrets from Vault
        uses: hashicorp/vault-action@v2
        with:
          url: https://vault.example.com:8200
          token: ${{ secrets.VAULT_TOKEN }}
          secrets: |
            secret/data/database username | DB_USERNAME ;
            secret/data/database password | DB_PASSWORD ;
            secret/data/api key | API_KEY

      - name: Use secrets
        run: |
          echo "Connecting to database as $DB_USERNAME"
          # Use $DB_PASSWORD, $API_KEY

参数说明(可直接复制使用):

  • url:Vault 实例地址;token 引用 GitHub Actions 的 VAULT_TOKEN secret,真正落盘的还是 GitHub 原生 secret,而非 Vault token 明文;
  • secrets:行内语法为 <vault-path> <field> | <env-var> ;,分号分隔多条映射。示例中把 secret/data/databaseusername/password 字段分别注入 DB_USERNAME/DB_PASSWORD,把 secret/data/apikey 注入 API_KEY。注意此处读取路径必须是 kv-v2 的 data/ 语义路径;
  • 注入后的环境变量由 Actions 自动打码(mask),在后续 run 中直接引用即可,echo "$DB_PASSWORD" 会以 *** 输出。

GitLab CI 中读取 Vault

GitLab CI 侧没有一等公民的 Vault action,通用做法是在 before_script 中完成地址与 token 配置,再用 Vault CLI 按字段取值:

deploy:
  image: vault:1.17
  before_script:
    - export VAULT_ADDR=https://vault.example.com:8200
    - export VAULT_TOKEN=$VAULT_TOKEN
    - apk add curl jq
  script:
    - |
      DB_PASSWORD=$(vault kv get -field=password secret/database/config)
      API_KEY=$(vault kv get -field=key secret/api/credentials)
      echo "Deploying with secrets..."
      # Use $DB_PASSWORD, $API_KEY

要点:

  • 作业镜像固定为 vault:1.17(引用固定版本而非 latest,与 gitlab-ci-patterns 技能「使用具体镜像标签」的最佳实践一致);
  • vault kv get -field=password 只输出指定字段,避免将整个 JSON 密钥对象泄入日志;
  • 镜像基于 Alpine,需先 apk add curl jq 补齐工具链;
  • 建议把脚本中取回的密钥写入 GitLab 的 masked 变量机制或 set -x 关闭状态下的受保护 shell,防止密钥出现在 job 日志。

AWS Secrets Manager 集成

创建密钥

aws secretsmanager create-secret \
  --name production/database/password \
  --secret-string "super-secret-password"

在 GitHub Actions 中取回并注入

先用 aws-actions/configure-aws-credentials@v4 配置临时凭据,再通过 CLI 取回 SecretString。关键是 echo "::add-mask::$SECRET" —— 该命令把变量注册为日志脱敏值,避免 echo $DB_PASSWORD 之类的调试语句把明文刷进流水线日志:

- name: Configure AWS credentials
  uses: aws-actions/configure-aws-credentials@v4
  with:
    aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
    aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
    aws-region: us-west-2

- name: Get secret from AWS
  run: |
    SECRET=$(aws secretsmanager get-secret-value \
      --secret-id production/database/password \
      --query SecretString \
      --output text)
    echo "::add-mask::$SECRET"
    echo "DB_PASSWORD=$SECRET" >> $GITHUB_ENV

- name: Use secret
  run: |
    # Use $DB_PASSWORD
    ./deploy.sh

操作链路解析:

  • configure-aws-credentials@v4 要求仓库已配置 AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY 两个 Actions secret,长凭据只出现在此步骤,后续步骤均基于它产出的临时身份运行;
  • get-secret-value 配合 --query SecretString --output text 只提取明文串;若密钥存的是 JSON(如 {"username":"admin","password":"..."}),可在下游用 jqpython -c 拆字段(见下节 Terraform 的 jsondecode 用法);
  • echo "DB_PASSWORD=$SECRET" >> $GITHUB_ENV 将密钥写入跨步骤环境,之后所有步骤共享 $DB_PASSWORD

Terraform 中消费密钥

IaC 场景下不落盘敏感值,改用 data source 动态读取——Terraform 将该值写入 state,因此仍须配合远端加密 state:

data "aws_secretsmanager_secret_version" "db_password" {
  secret_id = "production/database/password"
}

resource "aws_db_instance" "main" {
  allocated_storage    = 100
  engine              = "postgres"
  instance_class      = "db.t3.large"
  username            = "admin"
  password            = jsondecode(data.aws_secretsmanager_secret_version.db_password.secret_string)["password"]
}

aws_secretsmanager_secret_version 取回的 secret_string 若为 JSON 对象,jsondecode(...)["password"] 即可精确取出嵌套字段,与 CLI 侧 --query 思路一致。

平台原生方案:GitHub Secrets 与 GitLab CI Variables

GitHub:组织级 / 仓库级 / 环境级 Secrets

仓库或组织级 secret 通过 ${{ secrets.XXX }} 以环境变量注入,密钥从不进入代码、不写入 step 日志

- name: Use GitHub secret
  env:
    API_KEY: ${{ secrets.API_KEY }}
    DATABASE_URL: ${{ secrets.DATABASE_URL }}
  run: |
    # Secrets are injected as env vars — never print them to logs
    ./deploy.sh

环境级 secret 更进一步,与部署环境绑定并可叠加人工审批门禁(部署前由 Environment protection rules 审查):

deploy:
  runs-on: ubuntu-latest
  environment: production
  steps:
    - name: Deploy
      env:
        PROD_API_KEY: ${{ secrets.PROD_API_KEY }}
      run: |
        # Secret injected as env var — never print to logs
        ./deploy.sh

这里 environment: productiongithub-actions-templates 技能 中「带审批的生产部署」示例是同一条安全链路的不同切面:环境既提供 production 专属 secret 作用域,也提供 required reviewers 审批门禁。

GitLab:Project / Protected / Masked / File 变量

deploy:
  script:
    - echo "Deploying with $API_KEY"
    - echo "Database: $DATABASE_URL"

GitLab CI 变量是密钥注入的主要载体,技能文档特别标出三种高阶形态:

  • Protected(受保护):仅受保护分支/标签(如 mainv* tags)上的作业可见,防止普通分支窃取生产密钥;
  • Masked(脱敏):变量值在 job 日志中被自动打码隐藏,禁止在日志中还原明文;
  • File type(文件型):变量以临时文件形式注入,适合需要密钥文件路径的工具(如 kubeconfig、服务账号 JSON、证书链)。

External Secrets Operator:Kubernetes 原生密钥同步

在 Kubernetes 中,把 Vault/AWS 的密钥同步成集群 Secret 的惯用方案是 External Secrets Operator。技能文档给出 SecretStore(声明后端提供方与认证)+ ExternalSecret(声明同步映射)的双资源模式:

apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
  name: vault-backend
  namespace: production
spec:
  provider:
    vault:
      server: "https://vault.example.com:8200"
      path: "secret"
      version: "v2"
      auth:
        kubernetes:
          mountPath: "kubernetes"
          role: "production"

---
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: database-credentials
  namespace: production
spec:
  refreshInterval: 1h
  secretStoreRef:
    name: vault-backend
    kind: SecretStore
  target:
    name: database-credentials
    creationPolicy: Owner
  data:
    - secretKey: username
      remoteRef:
        key: database/config
        property: username
    - secretKey: password
      remoteRef:
        key: database/config
        property: password

字段语义:

  • SecretStore.spec.provider.vaultserver 指 Vault 地址;path: "secret"version: "v2" 对齐 kv-v2 引擎(底层路径拼接为 secret/data/...);auth.kubernetes 使用 Vault Kubernetes auth 方法,通过 role: "production" 映射到 Vault 侧为该命名空间预置的权限策略——这是把「最小权限」落到集群身份上的关键;
  • ExternalSecret.specrefreshInterval: 1h 控制周期同步(Vault 侧轮换后最多 1 小时集群 Secret 收敛);target.creationPolicy: Owner 表示该 Secret 生命周期由 ExternalSecret 托管;data[].secretKey 决定集群 Secret 内的键名,remoteRef.key/property 指向上游 database/config 的具体字段;
  • 该模式对应 deployment-engineer.md 中 GitOps 秘密管理能力项(External Secrets Operator 位列其中),适合 ArgoCD/Flux 部署的 GitOps 工作流。

密钥轮换:自动化与手动双轨

AWS 自动轮换(Lambda 处理器骨架)

import boto3
import json

def lambda_handler(event, context):
    client = boto3.client('secretsmanager')

    # Get current secret
    response = client.get_secret_value(SecretId='my-secret')
    current_secret = json.loads(response['SecretString'])

    # Generate new password
    new_password = generate_strong_password()

    # Update database password
    update_database_password(new_password)

    # Update secret
    client.put_secret_value(
        SecretId='my-secret',
        SecretString=json.dumps({
            'username': current_secret['username'],
            'password': new_password
        })
    )

    return {'statusCode': 200}

这是 AWS Secrets Manager 自动轮换的「SecretString 读写」骨架:先 get_secret_value 读当前版本,生成强密码后先更新下游真实资源(数据库),最后 put_secret_value 回写新版本。完整的 Lambda 轮换实现还需处理 Secrets Manager 传入的 ClientRequestTokenStepcreateSecret/setSecret/testSecret/finishSecret 四阶段)以实现无窗口轮换,此处 generate_strong_password / update_database_password 为待填充的占位逻辑——真实落地时建议遵循 AWS 官方 rotation function 规范。

手动轮换流程

不引入自动化时,技能文档给出标准化五步:

  1. 生成新密钥(Generate new secret)
  2. 在密钥存储中更新(Update secret in secret store)
  3. 让应用切换到新密钥(Update applications to use new secret)
  4. 验证功能正常(Verify functionality)
  5. 吊销旧密钥(Revoke old secret)

无论自动还是手动,deployment-pipeline-design 技能 在回滚段给出的忠告同样适用:任何涉及数据库凭据的轮换都要保持向后兼容(新老密钥至少共存一个发布周期),并确保回滚不会出现「新代码 + 旧密钥」的错配窗口。

Secret Scanning:把密钥挡在提交之前与流水线之内

Pre-commit Hook(TruffleHog + Docker)

#!/bin/bash
# .git/hooks/pre-commit

# Check for secrets with TruffleHog
docker run --rm -v "$(pwd):/repo" \
  trufflesecurity/trufflehog:3.88 \
  filesystem --directory=/repo

if [ $? -ne 0 ]; then
  echo "❌ Secret detected! Commit blocked."
  exit 1
fi

脚本把当前工作区挂载进 trufflesecurity/trufflehog:3.88 容器执行文件系统扫描,检出密钥即以非零码退出并阻断提交。镜像 tag 固定为 3.88,避免漂移。仓库中 block-no-verify 插件 的存在也从侧面说明:这类 pre-commit/PreToolUse 守卫必须防止被 --no-verify 之类旁路参数绕过,才能发挥实效。

CI/CD 流水线扫描

secret-scan:
  stage: security
  image: trufflesecurity/trufflehog:3.88
  script:
    - trufflehog filesystem .
  allow_failure: false

在 CI 阶段追加独立 secret-scan 作业,allow_failure: false 保证任何一处密钥泄漏都直接判定流水线失败。技能文档在 Best Practices 中提及的 GitGuardian、TruffleHog 都属于此层的扫描工具选型。

十项最佳实践清单

技能文档收束为 10 条可执行纪律,可作为团队安全基线的验收标准:

  1. 绝不把密钥提交进 Git(Never commit secrets to Git)
  2. 不同环境使用不同密钥(Use different secrets per environment)
  3. 定期轮换密钥(Rotate secrets regularly)
  4. 实施最小权限访问(Implement least-privilege access)
  5. 开启审计日志(Enable audit logging)——Vault 的 Audit logging 能力正是为此设计
  6. 使用密钥扫描工具(GitGuardian、TruffleHog)
  7. 在日志中打码密钥(Mask secrets in logs)——对应 GitHub 的 add-mask、GitLab 的 masked 变量
  8. 静态加密密钥存储(Encrypt secrets at rest)——对应 Azure Key Vault 的 HSM-backed keys
  9. 尽可能使用短生命周期 token(Use short-lived tokens when possible)——Vault 动态凭据、云厂商临时身份
  10. 文档化密钥需求(Document secret requirements)——记录每条密钥的属主、用途、轮换周期与影响面

在 agents 技能生态中的协同定位

本技能不是孤立的文档,而是 cicd-automation 插件 的四件套之一,且在其内部相互引用、形成完整闭环:

  • github-actions-templates:负责把「测试→构建镜像→推送到 K8s」的 workflow 模板化,其 Reusable Workflows 段 通过 workflow_callsecrets: 声明对外接收 NPM_TOKEN,正是本技能「用原生 secret 承载密钥」的应用实例;
  • gitlab-ci-patterns:覆盖多阶段流水线、Docker 构建与 Terraform 流水线,其 最佳实践第 9 条 明确「Use CI/CD variables for secrets」,与本技能的 GitLab 段互为印证;
  • deployment-pipeline-design:在架构层设计多环境晋升与质量门禁,本技能则提供其安全侧的密钥处理能力。

三个同级技能均在自己的 Related Skills 中反向链接到 secrets-management,佐证了它在流水线安全语义中的枢纽地位。配合该插件的五个专属 agent(deployment-engineercloud-architect 等)使用时,可按「Agent 决策 → Skill 供能」的模式工作:Agent 判断当前需要为某条流水线落地密钥管理,随后加载本技能获取经过验证的 Vault/AWS/原生方案配置模板。

技能文档的规范性与演进建议

从仓库工具视角看,tools/validate_generated.py 会对所有技能执行结构性校验:SKILL.md 必须以 --- 开头且含 name/description、frontmatter 中的 name 必须与目录名一致、description 非空且建议含触发短语。这些规则保证了技能可被多 harness 的市场化发现与安装机制(GitHub CLI gh skill installnpx skills add 等)稳定消费,正如 docs/agent-skills.md 所记录的安装方式。文档正文中的两处内部引用(references/vault-setup.mdreferences/github-secrets.md)作为「按需加载的更深层资源」占位,当前版本技能以单文件自洽为主——若需补充扩展示例,可在技能目录内按渐进式披露规范新建对应 references 文件并保持目录结构整洁。

把本技能落地到实际项目时,推荐的最小改造路径是:先在 GitHub/GitLab 侧建好原生 secret/variable → 引入 TruffleHog pre-commit 与 CI 扫描双闸门 → 再按「Vault(统一密钥面)→ AWS Secrets Manager(AWS 原生 + 自动轮换)→ External Secrets Operator(Kubernetes 同步)」的优先级渐进引入集中式方案,最终以定期轮换与审计日志收口,形成从存储、注入、扫描到轮换的完整密钥生命周期管理。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
897
5.81 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
596
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
920
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.79 K
1.02 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
519
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
390