sops 加密配置文件和 CI

FreeGuideOnline 最新 2026-07-13

bash brew install sops


**Linux**
```bash
# 通过 snap 安装
sudo snap install sops

# 或下载预编译二进制文件
curl -LO https://github.com/getsops/sops/releases/latest/download/sops.linux.amd64
chmod +x sops.linux.amd64
sudo mv sops.linux.amd64 /usr/local/bin/sops

Windows

choco install sops
# 或手动下载 .exe 文件并加入PATH

安装完成后,验证版本:

sops --version

密钥后端选择

SOPS 支持多种加密后端,你至少需要配置一种。以下推荐两种常用方案:

  • age:现代、简单的加密工具,适合个人或小团队快速上手。
  • AWS KMS / GCP KMS / Azure Key Vault:适合云环境,可与 IAM 集成,通过权限控制谁可以解密。

本教程以 age 为例(无需云基础设施,体验最轻量)。

快速上手:使用 age 加密配置文件

1. 生成 age 密钥对

如果你还没有 age,先安装:

brew install age   # macOS
sudo apt install age -y   # Linux

生成密钥:

mkdir -p ~/.config/sops/age/
age-keygen -o ~/.config/sops/age/keys.txt

这会生成类似如下的密钥对,私钥保存在文件中:

# public key: age1abc...
AGE-SECRET-KEY-1xxx...

2. 创建 SOPS 配置文件

在项目根目录创建 .sops.yaml,指定使用哪些公钥加密:

creation_rules:
  - path_regex: config/.*\.yaml$
    age: age1abcxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

age1abc... 替换为你的公钥。path_regex 用于按文件路径匹配不同的加密规则。

3. 创建并加密一个配置文件

假设你有一个 config/settings.yaml 文件:

database:
  host: db.internal.example.com
  password: supersecretpassword
app:
  port: 8080
  api_key: my-api-key

使用 SOPS 加密该文件:

sops --encrypt config/settings.yaml > config/settings.enc.yaml

settings.enc.yaml 的内容会变为:

database:
  host: db.internal.example.com
  password: ENC[AES256_GCM,data:abc123...,type:str]
app:
  port: 8080
  api_key: ENC[AES256_GCM,data:def456...,type:str]
sops:
  ...  # 加密元数据

结构一目了然,只有敏感值被替换为 ENC 标识。

4. 解密并编辑

如需编辑加密文件,使用 sops 打开,它会自动解密并调用你的默认编辑器(如 vim):

sops config/settings.enc.yaml

保存退出后,文件会自动被重新加密。你也可以直接更新加密内容:

sops updatekeys config/settings.enc.yaml

5. 解密文件

sops --decrypt config/settings.enc.yaml > config/settings.dec.yaml

使用多密钥管理

对于团队协作,可将多人的 age 公钥加入 .sops.yaml

creation_rules:
  - path_regex: config/.*\.yaml$
    age: >-
      age1user1q2w3e...,
      age1user2r4t5y...      

这样任何持有对应私钥的成员都可以解密该文件。建议定期更新和轮转密钥。

Git 工作流策略

  1. 永远只提交加密文件(如 settings.enc.yaml)到仓库。
  2. 将解密后的文件加入 .gitignore,防止意外提交明文。
  3. 利用 SOPS 保留键名明文的特点,在 Code Review 中轻松识别配置结构的变化。

深度集成 CI/CD

CI 流水线需要在运行时解密配置,以便部署或测试。核心是要让 CI 环境安全地获取解密私钥。

场景 1:GitHub Actions + age

  1. 将私钥存入 GitHub Secrets
    在仓库 Setting → Secrets and variables → Actions 中,新增一个 Secret,例如 SOPS_AGE_KEY,值为你 keys.txt 中完整的私钥内容。

  2. 在 Workflow 中解密文件

    name: Deploy
    
    on: [push]
    
    jobs:
      deploy:
        runs-on: ubuntu-latest
        steps:
          - name: Checkout code
            uses: actions/checkout@v4
    
          - name: Setup SOPS and age
            run: |
              curl -LO https://github.com/getsops/sops/releases/latest/download/sops.linux.amd64
              chmod +x sops.linux.amd64
              sudo mv sops.linux.amd64 /usr/local/bin/sops
              sudo apt update && sudo apt install -y age          
    
          - name: Configure age key
            run: |
              mkdir -p ~/.config/sops/age
              echo "$SOPS_AGE_KEY" > ~/.config/sops/age/keys.txt          
            env:
              SOPS_AGE_KEY: ${{ secrets.SOPS_AGE_KEY }}
    
          - name: Decrypt config for deployment
            run: sops --decrypt config/settings.enc.yaml > config/settings.yaml
    
          - name: Deploy (example)
            run: ./deploy.sh --config=config/settings.yaml
    

场景 2:GitLab CI + AWS KMS

若使用 AWS KMS:

  1. 在 AWS IAM 中创建专用用户,赋予 kms:Decrypt 权限。
  2. 将 Access Key 和 Secret Key 存入 GitLab CI/CD 变量(或通过 OIDC 获取临时凭证)。
  3. .gitlab-ci.yml 示例
    deploy:
      image: alpine:latest
      before_script:
        - apk add --no-cache sops curl aws-cli
        - aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID
        - aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY
        - aws configure set region us-east-1
      script:
        - sops -d config.enc.yaml > config.yaml
        - ./deploy.sh
    

场景 3:Docker 构建时解密

在 Dockerfile 中使用多阶段构建,仅在构建期间挂载私钥(确保不写进镜像层):

FROM golang:1.21 AS builder
RUN apt-get update && apt-get install -y sops
COPY config/prod.enc.yaml ./
# 通过绑定挂载或构建参数传入解密
RUN --mount=type=secret,id=sops_key,target=/root/.config/sops/age/keys.txt \
    sops -d prod.enc.yaml > config.yaml
...