AgentSkillsCN

sops-age-secrets

SOPS 与 age 加密工具,用于在 Git 仓库中管理敏感信息。当您遇到以下场景时,可优先选用此技能: (1) 在项目中设置加密后的敏感信息(初始 .sops.yaml 配置); (2) 使用 age 密钥对 YAML、JSON、ENV 或 INI 文件进行加解密; (3) 管理 age 密钥(生成、分发、轮转); (4) 针对不同环境配置基于路径的加密规则; (5) 在 CI/CD 管道中集成 SOPS 解密功能(GitHub Actions、GitLab CI); (6) 排查 SOPS 解密失败或密钥相关的问题; (7) 利用 encrypted_regex 模式实现选择性加密。

SKILL.md
--- frontmatter
name: sops-age-secrets
description: |
  SOPS and age encryption for secrets management in git repositories. Use when:
  (1) Setting up encrypted secrets in a project (initial .sops.yaml configuration)
  (2) Encrypting/decrypting YAML, JSON, ENV, or INI files with age keys
  (3) Managing age keys (generation, distribution, rotation)
  (4) Configuring path-based encryption rules for different environments
  (5) Integrating SOPS decryption in CI/CD pipelines (GitHub Actions, GitLab CI)
  (6) Troubleshooting SOPS decryption failures or key issues
  (7) Selective encryption with encrypted_regex patterns

SOPS + age Secrets Management

Encrypt secrets in git with SOPS using age keys. Values are encrypted with AES256-GCM; keys are simple X25519 keypairs.

Quick Reference

TaskCommand
Generate age keyage-keygen -o keys.txt
Extract public keyage-keygen -y keys.txt
Encrypt filesops encrypt file.yaml > file.enc.yaml
Decrypt filesops decrypt file.enc.yaml
Edit encrypted filesops edit file.enc.yaml
Update recipientssops updatekeys -y file.enc.yaml
Rotate data keysops rotate -i file.enc.yaml

Initial Setup

1. Generate Keys

bash
# Create key directory
mkdir -p ~/.config/sops/age

# Generate keypair
age-keygen -o ~/.config/sops/age/keys.txt
# Output: public key: age1abc123...

2. Create .sops.yaml

At repository root:

yaml
creation_rules:
  - age: age1yourpublickeyhere...

3. Encrypt First File

bash
sops encrypt config/secrets.yaml > config/secrets.enc.yaml
rm config/secrets.yaml
git add config/secrets.enc.yaml .sops.yaml

Core Workflows

Encrypt New File

bash
# Create plaintext file
cat > secrets.yaml << 'EOF'
database:
  password: secret123
api_key: abc-xyz
EOF

# Encrypt (uses .sops.yaml rules)
sops encrypt secrets.yaml > secrets.enc.yaml
rm secrets.yaml

Edit Encrypted File

bash
# Opens decrypted in $EDITOR, re-encrypts on save
sops edit secrets.enc.yaml

Decrypt for Use

bash
# To stdout
sops decrypt secrets.enc.yaml

# To file
sops decrypt secrets.enc.yaml > secrets.yaml

# Extract single value
sops decrypt --extract '["database"]["password"]' secrets.enc.yaml

Pass to Process (No File)

bash
# As environment variables
sops exec-env secrets.enc.yaml './deploy.sh'

# As temporary file
sops exec-file secrets.enc.yaml 'source {}'

Multi-Environment Configuration

yaml
# .sops.yaml
creation_rules:
  # Production - admin + CI only
  - path_regex: ^config/secrets/prod\..*
    age: >-
      age1admin...,
      age1cicd...

  # Staging/Dev - broader access
  - path_regex: ^config/secrets/.*
    age: >-
      age1admin...,
      age1cicd...,
      age1dev...

Selective Encryption

Only encrypt sensitive keys (keeps file readable):

yaml
creation_rules:
  - age: age1...
    encrypted_regex: ^(password|secret|token|key|api_key|private)$

Result:

yaml
database:
  host: localhost           # plaintext
  password: ENC[AES256_GCM,data:...,type:str]  # encrypted

CI/CD Integration

GitHub Actions

yaml
- name: Decrypt secrets
  env:
    SOPS_AGE_KEY: ${{ secrets.SOPS_AGE_KEY }}
  run: sops decrypt config/secrets.enc.yaml > secrets.yaml

Store AGE-SECRET-KEY-1... in repository secrets as SOPS_AGE_KEY.

Environment Variables

bash
# Key file location
export SOPS_AGE_KEY_FILE=/path/to/keys.txt

# Key value directly (CI/CD)
export SOPS_AGE_KEY="AGE-SECRET-KEY-1..."

Key Management

Add New Recipient

  1. Update .sops.yaml with new public key
  2. Re-encrypt existing files:
    bash
    sops updatekeys -y file.enc.yaml
    

Remove Recipient

  1. Remove from .sops.yaml
  2. Re-encrypt and rotate:
    bash
    sops updatekeys -y file.enc.yaml
    sops rotate -i file.enc.yaml
    

Key Locations

PlatformDefault Path
Linux~/.config/sops/age/keys.txt
macOS~/Library/Application Support/sops/age/keys.txt

Reference Files

FileWhen to Read
age-keys.mdKey generation, storage, distribution patterns
sops-config.md.sops.yaml syntax, path rules, key groups
cli-reference.mdFull command reference, all flags
ci-cd-patterns.mdGitHub Actions, GitLab CI, Docker integration
troubleshooting.mdCommon errors and solutions

Common Issues

ProblemSolution
"could not decrypt data key"Wrong key - check SOPS_AGE_KEY_FILE or key location
"no matching keys found"File uses Shamir key groups - need multiple keys
.sops.yaml not foundRun from repo root or ensure file is in parent directory
path_regex not matchingUse regex syntax (.*\.yaml$), not glob (*.yaml)

Security Notes

  • Never commit private keys - Add keys.txt, *.agekey to .gitignore
  • Use dedicated CI keys - Easier to rotate, limit scope
  • Rotate data keys - Run sops rotate periodically
  • Limit recipients - Production files should have minimal access

Official Documentation