Fnox安全最佳实践Skill fnox-security-best-practices

本技能提供了使用Fnox工具进行秘密管理的全面安全最佳实践指南,包括数据加密、密钥管理、访问控制、安全审计和生命周期管理。适用于DevOps团队、安全工程师和开发者,确保敏感信息的安全性,防止数据泄露。关键词:Fnox, 秘密管理, 加密技术, 安全运维, 密钥轮换, 审计监控, 访问控制, DevOps安全。

安全运维 0 次安装 0 次浏览 更新于 3/25/2026

name: fnox-security-best-practices user-invocable: false description: 在使用Fnox实施安全秘密管理时使用。涵盖加密、密钥管理、访问控制和安全硬化。 allowed-tools:

  • Read
  • Write
  • Edit
  • Bash
  • Grep
  • Glob

Fnox - 安全最佳实践

使用Fnox管理秘密的安全指南和最佳实践。

加密基础

始终加密敏感数据

# 错误:明文秘密提交到git
[secrets]
DATABASE_PASSWORD = "super-secret-password"
API_KEY = "sk-live-12345"

# 正确:加密的秘密
[providers.age]
type = "age"
public_keys = ["age1ql3z..."]

[secrets]
DATABASE_PASSWORD = { provider = "age", value = "age[...]" }
API_KEY = { provider = "age", value = "age[...]" }

使用强加密

# 正确:age加密(现代、安全)
age-keygen -o ~/.config/fnox/keys/identity.txt

# 正确:云KMS(管理加密)
[providers.kms]
type = "aws-kms"
key_id = "arn:aws:kms:us-east-1:..."

密钥管理

保护私钥

# 安全存储age私钥
chmod 600 ~/.config/fnox/keys/identity.txt

# 永不提交私钥
echo "*.txt" >> ~/.config/fnox/keys/.gitignore

分离公钥和私钥

# fnox.toml(提交)- 仅公钥
[providers.age]
type = "age"
public_keys = ["age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p"]

# fnox.local.toml(git忽略)- 私钥
[providers.age]
identity = "~/.config/fnox/keys/identity.txt"

定期轮换密钥

# 生成新的age密钥
age-keygen -o ~/.config/fnox/keys/identity-2025.txt

# 使用新密钥重新加密所有秘密
fnox get --all | fnox set --provider age-new

访问控制

使用最小权限

# 正确:按环境分离秘密
[profiles.production]
[profiles.production.providers.prod-secrets]
type = "aws-sm"
region = "us-east-1"

[profiles.production.secrets]
DATABASE_URL = { provider = "prod-secrets", value = "prod/db" }

[profiles.development]
[profiles.development.secrets]
DATABASE_URL = "postgresql://localhost/dev"  # 非敏感

团队访问控制

# 团队的多个age接收者
[providers.age]
type = "age"
public_keys = [
  "age1ql3z...",  # Alice(管理员)
  "age1qw4r...",  # Bob(开发者)
  # 不包含承包商或临时团队成员
]

基于角色的秘密

# 后端秘密
[providers.backend]
type = "aws-sm"
region = "us-east-1"

# 前端秘密(不同访问级别)
[providers.frontend]
type = "aws-sm"
region = "us-east-1"

[secrets]
BACKEND_DB_PASSWORD = { provider = "backend", value = "backend/db-pass" }
FRONTEND_API_ENDPOINT = { provider = "frontend", value = "frontend/api-url" }

Git安全

永不提交敏感数据

# .gitignore
fnox.local.toml
*.age-identity.txt
*.key
*.pem
.env

审计Git历史

# 检查意外提交的秘密
git log -p | grep -i "password\\|secret\\|key"

# 从git历史中移除秘密(如果找到)
git filter-branch --force --index-filter \
  'git rm --cached --ignore-unmatch fnox.local.toml' \
  --prune-empty --tag-name-filter cat -- --all

使用预提交钩子

# .git/hooks/pre-commit
#!/bin/bash
if git diff --cached --name-only | grep -q "fnox.local.toml"; then
  echo "错误:尝试提交fnox.local.toml"
  exit 1
fi

# 检查明文秘密
if git diff --cached | grep -q "password.*=.*\\"[^a]"; then
  echo "警告:检测到可能的明文密码"
  exit 1
fi

环境分离

分离开发和生产

# fnox.toml(开发)
[secrets]
DATABASE_URL = "postgresql://localhost/dev"
DEBUG = "true"

# fnox.production.toml(生产秘密)
[providers.prod]
type = "aws-sm"
region = "us-east-1"

[secrets]
DATABASE_URL = { provider = "prod", value = "prod/db-url" }
DEBUG = "false"

使用配置文件管理环境

# 开发
fnox exec -- node app.js

# 预生产
FNOX_PROFILE=staging fnox exec -- node app.js

# 生产
FNOX_PROFILE=production fnox exec -- node app.js

云提供商安全

AWS最佳实践

# 使用IAM角色代替访问密钥
[providers.aws-sm]
type = "aws-sm"
region = "us-east-1"
# 没有access_key_id或secret_access_key
# 使用IAM角色或AWS凭据链

# 通过资源标签限制
[providers.aws-sm]
type = "aws-sm"
region = "us-east-1"
# 确保IAM策略限制访问特定秘密

Azure最佳实践

# 使用托管身份
[providers.azure]
type = "azure-kv"
vault_url = "https://my-vault.vault.azure.net"
# 通过Azure托管身份认证

GCP最佳实践

# 使用具有最小权限的服务账户
[providers.gcp]
type = "gcp-sm"
project_id = "my-project"
# 服务账户仅具有secretmanager.versions.access权限

审计和监控

记录秘密访问

# 在云提供商中启用审计日志
# AWS CloudTrail用于Secrets Manager
# Azure Monitor用于Key Vault
# GCP Cloud Audit Logs用于Secret Manager

监控异常

# 检查哪些秘密被访问
fnox list

# 验证提供者配置
fnox doctor

# 测试提供者连接性
fnox provider test aws-sm

定期安全审计

# 列出所有秘密
fnox list

# 验证加密状态
fnox doctor

# 检查明文秘密
grep -r "password.*=.*\\"[^a]" fnox.toml

秘密生命周期

定期轮换秘密

# 生成新秘密
NEW_PASSWORD=$(openssl rand -base64 32)

# 在fnox中更新
echo "$NEW_PASSWORD" | fnox set DATABASE_PASSWORD

# 在实际服务中更新(数据库、API等)
# 然后验证应用仍正常工作

移除过时秘密

# 移除未使用的秘密
fnox unset OLD_API_KEY

# 从云提供商中清理
aws secretsmanager delete-secret --secret-id old/api-key

记录秘密用途

[secrets]
STRIPE_API_KEY = {
  provider = "age",
  value = "age[...]",
  description = "用于支付处理的Stripe秘密密钥。每季度轮换。"
}

DATABASE_PASSWORD = {
  provider = "aws-sm",
  value = "prod/db-password",
  description = "PostgreSQL主密码。最后轮换:2025-01-01"
}

CI/CD安全

使用专用CI密钥

# 用于CI/CD的单独age密钥
[providers.age]
type = "age"
public_keys = [
  "age1ql3z...",  # 开发者密钥
  "age1ci3d...",  # CI/CD密钥(有限访问)
]

限制CI秘密访问

# .github/workflows/deploy.yml
env:
  FNOX_PROFILE: production
  # 使用GitHub秘密作为age身份
  AGE_IDENTITY: ${{ secrets.AGE_IDENTITY }}

steps:
  - name: 加载秘密
    run: |
      echo "$AGE_IDENTITY" > /tmp/identity.txt
      chmod 600 /tmp/identity.txt
      fnox exec -- ./deploy.sh
      rm /tmp/identity.txt

最小CI权限

# 具有最小秘密的CI配置文件
[profiles.ci]
[profiles.ci.secrets]
DEPLOY_TOKEN = { provider = "age", value = "age[...]" }
# 不包含数据库密码或API密钥

最佳实践总结

要做

✅ 始终加密敏感秘密 ✅ 使用强加密(age、KMS) ✅ 安全存储私钥 ✅ 分离开发和生成秘密 ✅ 使用.gitignore处理本地覆盖 ✅ 定期轮换密钥和秘密 ✅ 使用云提供商托管身份 ✅ 审计秘密访问 ✅ 记录秘密用途 ✅ 使用配置文件管理环境

不要做

❌ 永不提交私钥 ❌ 永不使用明文处理敏感数据 ❌ 不要共享私钥给团队成员 ❌ 不要硬编码凭据 ❌ 不要混合开发和生成秘密 ❌ 不要在生成中跳过加密 ❌ 不要忽略安全警告 ❌ 不要使用弱密码作为秘密

常见威胁和缓解

威胁:意外提交

# 缓解:预提交钩子
cat > .git/hooks/pre-commit <<'EOF'
#!/bin/bash
if git diff --cached fnox.local.toml > /dev/null; then
  echo "错误:fnox.local.toml不应被提交"
  exit 1
fi
EOF
chmod +x .git/hooks/pre-commit

威胁:密钥泄露

# 缓解:立即轮换
# 1. 生成新密钥
age-keygen -o ~/.config/fnox/keys/identity-new.txt

# 2. 重新加密所有秘密
fnox get --all | fnox set --provider age-new

# 3. 更新公钥
# 4. 撤销旧密钥

威胁:未授权访问

# 缓解:使用云提供商IAM
[providers.aws-sm]
type = "aws-sm"
region = "us-east-1"
# 使用IAM策略限制:
# - 限制到特定秘密ARN
# - 要求MFA
# - 通过IP范围限制

相关技能

  • configuration:安全管理fnox.toml
  • providers:选择安全提供者