fnox-security-best-practices
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseFnox - Security Best Practices
Fnox - 安全最佳实践
Security guidelines and best practices for managing secrets with Fnox.
使用Fnox管理密钥的安全指南与最佳实践。
Encryption Fundamentals
加密基础
Always Encrypt Sensitive Data
始终加密敏感数据
toml
undefinedtoml
undefinedBad: Plain text secrets committed to git
错误:将明文密钥提交至Git
[secrets]
DATABASE_PASSWORD = "super-secret-password"
API_KEY = "sk-live-12345"
[secrets]
DATABASE_PASSWORD = "super-secret-password"
API_KEY = "sk-live-12345"
Good: Encrypted secrets
正确:加密后的密钥
[providers.age]
type = "age"
public_keys = ["age1ql3z..."]
[secrets]
DATABASE_PASSWORD = { provider = "age", value = "age[...]" }
API_KEY = { provider = "age", value = "age[...]" }
undefined[providers.age]
type = "age"
public_keys = ["age1ql3z..."]
[secrets]
DATABASE_PASSWORD = { provider = "age", value = "age[...]" }
API_KEY = { provider = "age", value = "age[...]" }
undefinedUse Strong Encryption
使用强加密算法
bash
undefinedbash
undefinedGood: age encryption (modern, secure)
推荐:age加密(现代、安全)
age-keygen -o ~/.config/fnox/keys/identity.txt
age-keygen -o ~/.config/fnox/keys/identity.txt
Good: Cloud KMS (managed encryption)
推荐:云KMS(托管式加密)
[providers.kms]
type = "aws-kms"
key_id = "arn:aws:kms:us-east-1:..."
undefined[providers.kms]
type = "aws-kms"
key_id = "arn:aws:kms:us-east-1:..."
undefinedKey Management
密钥管理
Protect Private Keys
保护私钥安全
bash
undefinedbash
undefinedStore age private key securely
安全存储age私钥
chmod 600 ~/.config/fnox/keys/identity.txt
chmod 600 ~/.config/fnox/keys/identity.txt
Never commit private keys
切勿提交私钥
echo "*.txt" >> ~/.config/fnox/keys/.gitignore
undefinedecho "*.txt" >> ~/.config/fnox/keys/.gitignore
undefinedSeparate Public and Private Keys
分离公钥与私钥
toml
undefinedtoml
undefinedfnox.toml (committed) - public keys only
fnox.toml(可提交)- 仅包含公钥
[providers.age]
type = "age"
public_keys = ["age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p"]
[providers.age]
type = "age"
public_keys = ["age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p"]
fnox.local.toml (gitignored) - private keys
fnox.local.toml(需忽略Git提交)- 包含私钥
[providers.age]
identity = "~/.config/fnox/keys/identity.txt"
undefined[providers.age]
identity = "~/.config/fnox/keys/identity.txt"
undefinedRotate Keys Regularly
定期轮换密钥
bash
undefinedbash
undefinedGenerate new age key
生成新的age密钥
age-keygen -o ~/.config/fnox/keys/identity-2025.txt
age-keygen -o ~/.config/fnox/keys/identity-2025.txt
Re-encrypt all secrets with new key
使用新密钥重新加密所有密钥
fnox get --all | fnox set --provider age-new
undefinedfnox get --all | fnox set --provider age-new
undefinedAccess Control
访问控制
Use Least Privilege
遵循最小权限原则
toml
undefinedtoml
undefinedGood: Separate secrets by environment
推荐:按环境分离密钥
[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" # Non-sensitive
undefined[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" # 非敏感内容
undefinedTeam Access Control
团队访问控制
toml
undefinedtoml
undefinedMultiple age recipients for team
为团队设置多个age接收方
[providers.age]
type = "age"
public_keys = [
"age1ql3z...", # Alice (admin)
"age1qw4r...", # Bob (developer)
Don't include contractors or temporary team members
]
undefined[providers.age]
type = "age"
public_keys = [
"age1ql3z...", # Alice(管理员)
"age1qw4r...", # Bob(开发人员)
请勿包含外包人员或临时团队成员
]
undefinedRole-Based Secrets
基于角色的密钥管理
toml
undefinedtoml
undefinedBackend secrets
后端密钥
[providers.backend]
type = "aws-sm"
region = "us-east-1"
[providers.backend]
type = "aws-sm"
region = "us-east-1"
Frontend secrets (different access level)
前端密钥(不同访问级别)
[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" }
undefined[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" }
undefinedGit Security
Git安全
Never Commit Sensitive Data
切勿提交敏感数据
gitignore
undefinedgitignore
undefined.gitignore
.gitignore
fnox.local.toml
*.age-identity.txt
*.key
*.pem
.env
undefinedfnox.local.toml
*.age-identity.txt
*.key
*.pem
.env
undefinedAudit Git History
审计Git历史
bash
undefinedbash
undefinedCheck for accidentally committed secrets
检查是否意外提交了密钥
git log -p | grep -i "password|secret|key"
git log -p | grep -i "password|secret|key"
Remove secrets from git history (if found)
从Git历史中移除密钥(若发现)
git filter-branch --force --index-filter
'git rm --cached --ignore-unmatch fnox.local.toml'
--prune-empty --tag-name-filter cat -- --all
'git rm --cached --ignore-unmatch fnox.local.toml'
--prune-empty --tag-name-filter cat -- --all
undefinedgit filter-branch --force --index-filter
'git rm --cached --ignore-unmatch fnox.local.toml'
--prune-empty --tag-name-filter cat -- --all
'git rm --cached --ignore-unmatch fnox.local.toml'
--prune-empty --tag-name-filter cat -- --all
undefinedUse Pre-Commit Hooks
使用提交前钩子
bash
undefinedbash
undefined.git/hooks/pre-commit
.git/hooks/pre-commit
#!/bin/bash
if git diff --cached --name-only | grep -q "fnox.local.toml"; then
echo "Error: Attempting to commit fnox.local.toml"
exit 1
fi
#!/bin/bash
if git diff --cached --name-only | grep -q "fnox.local.toml"; then
echo "错误:尝试提交fnox.local.toml"
exit 1
fi
Check for plain text secrets
检查明文密钥
if git diff --cached | grep -q "password.=."[^a]"; then
echo "Warning: Possible plain text password detected"
exit 1
fi
undefinedif git diff --cached | grep -q "password.=."[^a]"; then
echo "警告:检测到可能的明文密码"
exit 1
fi
undefinedEnvironment Separation
环境分离
Separate Development and Production
分离开发与生产环境
toml
undefinedtoml
undefinedfnox.toml (development)
fnox.toml(开发环境)
[secrets]
DATABASE_URL = "postgresql://localhost/dev"
DEBUG = "true"
[secrets]
DATABASE_URL = "postgresql://localhost/dev"
DEBUG = "true"
fnox.production.toml (production secrets)
fnox.production.toml(生产环境密钥)
[providers.prod]
type = "aws-sm"
region = "us-east-1"
[secrets]
DATABASE_URL = { provider = "prod", value = "prod/db-url" }
DEBUG = "false"
undefined[providers.prod]
type = "aws-sm"
region = "us-east-1"
[secrets]
DATABASE_URL = { provider = "prod", value = "prod/db-url" }
DEBUG = "false"
undefinedUse Profiles for Environments
使用配置文件区分环境
bash
undefinedbash
undefinedDevelopment
开发环境
fnox exec -- node app.js
fnox exec -- node app.js
Staging
预发布环境
FNOX_PROFILE=staging fnox exec -- node app.js
FNOX_PROFILE=staging fnox exec -- node app.js
Production
生产环境
FNOX_PROFILE=production fnox exec -- node app.js
undefinedFNOX_PROFILE=production fnox exec -- node app.js
undefinedCloud Provider Security
云服务商安全
AWS Best Practices
AWS最佳实践
toml
undefinedtoml
undefinedUse IAM roles instead of access keys
使用IAM角色而非访问密钥
[providers.aws-sm]
type = "aws-sm"
region = "us-east-1"
[providers.aws-sm]
type = "aws-sm"
region = "us-east-1"
No access_key_id or secret_access_key
无需配置access_key_id或secret_access_key
Uses IAM role or AWS credentials chain
使用IAM角色或AWS凭证链
Restrict by resource tags
按资源标签限制访问
[providers.aws-sm]
type = "aws-sm"
region = "us-east-1"
[providers.aws-sm]
type = "aws-sm"
region = "us-east-1"
Ensure IAM policy limits access to specific secrets
确保IAM策略仅允许访问特定密钥
undefinedundefinedAzure Best Practices
Azure最佳实践
toml
undefinedtoml
undefinedUse managed identity
使用托管标识
[providers.azure]
type = "azure-kv"
vault_url = "https://my-vault.vault.azure.net"
[providers.azure]
type = "azure-kv"
vault_url = "https://my-vault.vault.azure.net"
Authentication via Azure managed identity
通过Azure托管标识进行身份验证
undefinedundefinedGCP Best Practices
GCP最佳实践
toml
undefinedtoml
undefinedUse service account with minimal permissions
使用权限最小化的服务账号
[providers.gcp]
type = "gcp-sm"
project_id = "my-project"
[providers.gcp]
type = "gcp-sm"
project_id = "my-project"
Service account with only secretmanager.versions.access
仅授予secretmanager.versions.access权限的服务账号
undefinedundefinedAudit and Monitoring
审计与监控
Log Secret Access
记录密钥访问日志
bash
undefinedbash
undefinedEnable audit logging in cloud providers
在云服务商中启用审计日志
AWS CloudTrail for Secrets Manager
AWS CloudTrail(用于Secrets Manager)
Azure Monitor for Key Vault
Azure Monitor(用于Key Vault)
GCP Cloud Audit Logs for Secret Manager
GCP Cloud Audit Logs(用于Secret Manager)
undefinedundefinedMonitor for Anomalies
监控异常行为
bash
undefinedbash
undefinedCheck which secrets are accessed
查看哪些密钥被访问
fnox list
fnox list
Verify provider configuration
验证服务商配置
fnox doctor
fnox doctor
Test provider connectivity
测试服务商连接性
fnox provider test aws-sm
undefinedfnox provider test aws-sm
undefinedRegular Security Audits
定期安全审计
bash
undefinedbash
undefinedList all secrets
列出所有密钥
fnox list
fnox list
Verify encryption status
验证加密状态
fnox doctor
fnox doctor
Check for plain text secrets
检查明文密钥
grep -r "password.=."[^a]" fnox.toml
undefinedgrep -r "password.=."[^a]" fnox.toml
undefinedSecrets Lifecycle
密钥生命周期
Rotate Secrets Regularly
定期轮换密钥
bash
undefinedbash
undefinedGenerate new secret
生成新密钥
NEW_PASSWORD=$(openssl rand -base64 32)
NEW_PASSWORD=$(openssl rand -base64 32)
Update in fnox
在Fnox中更新密钥
echo "$NEW_PASSWORD" | fnox set DATABASE_PASSWORD
echo "$NEW_PASSWORD" | fnox set DATABASE_PASSWORD
Update in actual service (database, API, etc.)
在实际服务中更新(数据库、API等)
Then verify application still works
然后验证应用是否仍能正常运行
undefinedundefinedRemove Obsolete Secrets
移除废弃密钥
bash
undefinedbash
undefinedRemove unused secret
移除未使用的密钥
fnox unset OLD_API_KEY
fnox unset OLD_API_KEY
Clean up from cloud provider
从云服务商中清理
aws secretsmanager delete-secret --secret-id old/api-key
undefinedaws secretsmanager delete-secret --secret-id old/api-key
undefinedDocument Secret Purpose
记录密钥用途
toml
[secrets]
STRIPE_API_KEY = {
provider = "age",
value = "age[...]",
description = "Stripe secret key for payment processing. Rotate quarterly."
}
DATABASE_PASSWORD = {
provider = "aws-sm",
value = "prod/db-password",
description = "PostgreSQL master password. Last rotated: 2025-01-01"
}toml
[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 Security
CI/CD安全
Use Dedicated CI Keys
使用专用CI密钥
toml
undefinedtoml
undefinedSeparate age key for CI/CD
为CI/CD设置独立的age密钥
[providers.age]
type = "age"
public_keys = [
"age1ql3z...", # Developer key
"age1ci3d...", # CI/CD key (limited access)
]
undefined[providers.age]
type = "age"
public_keys = [
"age1ql3z...", # 开发人员密钥
"age1ci3d...", # CI/CD密钥(权限受限)
]
undefinedRestrict CI Secret Access
限制CI密钥访问权限
yaml
undefinedyaml
undefined.github/workflows/deploy.yml
.github/workflows/deploy.yml
env:
FNOX_PROFILE: production
Use GitHub secrets for age identity
AGE_IDENTITY: ${{ secrets.AGE_IDENTITY }}
steps:
- name: Load secrets run: | echo "$AGE_IDENTITY" > /tmp/identity.txt chmod 600 /tmp/identity.txt fnox exec -- ./deploy.sh rm /tmp/identity.txt
undefinedenv:
FNOX_PROFILE: production
使用GitHub Secrets存储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
undefinedMinimal CI Permissions
最小化CI权限
toml
undefinedtoml
undefinedCI profile with minimal secrets
仅包含必要密钥的CI配置文件
[profiles.ci]
[profiles.ci.secrets]
DEPLOY_TOKEN = { provider = "age", value = "age[...]" }
[profiles.ci]
[profiles.ci.secrets]
DEPLOY_TOKEN = { provider = "age", value = "age[...]" }
Don't include database passwords or API keys
请勿包含数据库密码或API密钥
undefinedundefinedBest Practices Summary
最佳实践总结
DO
建议做法
✅ Always encrypt sensitive secrets
✅ Use strong encryption (age, KMS)
✅ Store private keys securely
✅ Separate dev and prod secrets
✅ Use .gitignore for local overrides
✅ Rotate keys and secrets regularly
✅ Use cloud provider managed identities
✅ Audit secret access
✅ Document secret purpose
✅ Use profiles for environments
✅ 始终加密敏感密钥
✅ 使用强加密算法(age、KMS)
✅ 安全存储私钥
✅ 分离开发与生产环境密钥
✅ 使用.gitignore忽略本地配置文件
✅ 定期轮换密钥与密钥对
✅ 使用云服务商托管标识
✅ 审计密钥访问记录
✅ 记录密钥用途
✅ 使用配置文件区分环境
DON'T
禁止做法
❌ Never commit private keys
❌ Never use plain text for sensitive data
❌ Don't share private keys between team members
❌ Don't hardcode credentials
❌ Don't mix dev and prod secrets
❌ Don't skip encryption in production
❌ Don't ignore security warnings
❌ Don't use weak passwords as secrets
❌ 切勿提交私钥
❌ 切勿将敏感数据以明文形式存储
❌ 切勿在团队成员间共享私钥
❌ 切勿硬编码凭证
❌ 切勿混合开发与生产环境密钥
❌ 生产环境中切勿跳过加密步骤
❌ 切勿忽略安全警告
❌ 切勿使用弱密码作为密钥
Common Threats and Mitigations
常见威胁与缓解措施
Threat: Accidental Commit
威胁:意外提交
bash
undefinedbash
undefinedMitigation: Pre-commit hooks
缓解措施:使用提交前钩子
cat > .git/hooks/pre-commit <<'EOF'
#!/bin/bash
if git diff --cached fnox.local.toml > /dev/null; then
echo "Error: fnox.local.toml should not be committed"
exit 1
fi
EOF
chmod +x .git/hooks/pre-commit
undefinedcat > .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
undefinedThreat: Key Compromise
威胁:密钥泄露
bash
undefinedbash
undefinedMitigation: Immediate rotation
缓解措施:立即轮换密钥
1. Generate new key
1. 生成新密钥
age-keygen -o ~/.config/fnox/keys/identity-new.txt
age-keygen -o ~/.config/fnox/keys/identity-new.txt
2. Re-encrypt all secrets
2. 重新加密所有密钥
fnox get --all | fnox set --provider age-new
fnox get --all | fnox set --provider age-new
3. Update public keys
3. 更新公钥
4. Revoke old key
4. 吊销旧密钥
undefinedundefinedThreat: Unauthorized Access
威胁:未授权访问
toml
undefinedtoml
undefinedMitigation: Use cloud provider IAM
缓解措施:使用云服务商IAM
[providers.aws-sm]
type = "aws-sm"
region = "us-east-1"
[providers.aws-sm]
type = "aws-sm"
region = "us-east-1"
Restrict with IAM policies:
通过IAM策略限制:
- Limit to specific secret ARNs
- 仅允许访问特定密钥ARN
- Require MFA
- 要求MFA验证
- Restrict by IP range
- 按IP范围限制访问
undefinedundefinedRelated Skills
相关技能
- configuration: Managing fnox.toml securely
- providers: Choosing secure providers
- configuration: 安全管理fnox.toml配置
- providers: 选择安全的服务商