fnox-configuration
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseFnox - Configuration
Fnox - 配置指南
Configuring secrets management with Fnox using fnox.toml files for secure, version-controlled secret storage.
使用fnox.toml文件配置Fnox密钥管理,实现安全、受版本控制的密钥存储。
Basic Configuration
基础配置
Initialize Project
初始化项目
bash
undefinedbash
undefinedCreate fnox.toml in current directory
在当前目录创建fnox.toml
fnox init
fnox init
Initialize with specific provider
使用指定的provider初始化
fnox init --provider age
undefinedfnox init --provider age
undefinedBasic fnox.toml Structure
基础fnox.toml结构
toml
undefinedtoml
undefinedfnox.toml
fnox.toml
[providers.age]
type = "age"
public_keys = ["age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p"]
[secrets]
DATABASE_URL = { provider = "age", value = "age[...]" }
API_KEY = { provider = "age", value = "age[...]", description = "Production API key" }
undefined[providers.age]
type = "age"
public_keys = ["age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p"]
[secrets]
DATABASE_URL = { provider = "age", value = "age[...]" }
API_KEY = { provider = "age", value = "age[...]", description = "生产环境API密钥" }
undefinedSecrets Definition
密钥定义
Simple Secret
简单密钥
toml
[secrets]
DATABASE_URL = "postgresql://localhost/myapp" # Plain text (dev only)toml
[secrets]
DATABASE_URL = "postgresql://localhost/myapp" # 明文(仅开发环境使用)Encrypted Secret
加密密钥
toml
[secrets]
DATABASE_URL = {
provider = "age",
value = "age1encrypted-value-here",
description = "Production database connection string"
}toml
[secrets]
DATABASE_URL = {
provider = "age",
value = "age1encrypted-value-here",
description = "生产环境数据库连接字符串"
}Secret with Default
带默认值的密钥
toml
[secrets]
DEBUG_MODE = {
provider = "age",
value = "age[...]",
default = "false",
description = "Enable debug logging"
}toml
[secrets]
DEBUG_MODE = {
provider = "age",
value = "age[...]",
default = "false",
description = "启用调试日志"
}Secret Behavior Options
密钥行为选项
toml
[secrets]
OPTIONAL_API_KEY = {
provider = "age",
value = "age[...]",
if_missing = "warn" # Options: "error", "warn", "ignore"
}
REQUIRED_SECRET = {
provider = "age",
value = "age[...]",
if_missing = "error" # Fail if missing (default)
}toml
[secrets]
OPTIONAL_API_KEY = {
provider = "age",
value = "age[...]",
if_missing = "warn" # 选项:"error", "warn", "ignore"
}
REQUIRED_SECRET = {
provider = "age",
value = "age[...]",
if_missing = "error" # 缺失则报错(默认行为)
}Configuration Hierarchy
配置层级
File Locations (Priority Order)
文件优先级顺序
- - Local overrides (gitignored)
fnox.local.toml - - Profile-specific
fnox.$FNOX_PROFILE.toml - - Project configuration
fnox.toml - Parent directory files (recursive)
fnox.toml - - Global configuration
~/.config/fnox/config.toml
- - 本地覆盖配置(已加入git忽略)
fnox.local.toml - - 特定配置文件
fnox.$FNOX_PROFILE.toml - - 项目级配置
fnox.toml - 父目录中的文件(递归查找)
fnox.toml - - 全局配置
~/.config/fnox/config.toml
Global Configuration
全局配置
toml
undefinedtoml
undefined~/.config/fnox/config.toml
~/.config/fnox/config.toml
[providers.age]
type = "age"
identity = "~/.config/fnox/keys/identity.txt"
[settings]
if_missing = "warn" # Global default for missing secrets
undefined[providers.age]
type = "age"
identity = "~/.config/fnox/keys/identity.txt"
[settings]
if_missing = "warn" # 密钥缺失时的全局默认行为
undefinedProject Configuration
项目配置
toml
undefinedtoml
undefinedproject/fnox.toml
project/fnox.toml
[providers.age]
public_keys = ["age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p"]
[secrets]
DATABASE_URL = { provider = "age", value = "age[...]" }
APP_NAME = "myapp"
undefined[providers.age]
public_keys = ["age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p"]
[secrets]
DATABASE_URL = { provider = "age", value = "age[...]" }
APP_NAME = "myapp"
undefinedLocal Overrides
本地覆盖配置
toml
undefinedtoml
undefinedproject/fnox.local.toml (gitignored)
project/fnox.local.toml(已加入git忽略)
[secrets]
DATABASE_URL = "postgresql://localhost/myapp_dev" # Override for local dev
DEBUG = "true"
undefined[secrets]
DATABASE_URL = "postgresql://localhost/myapp_dev" # 本地开发环境覆盖配置
DEBUG = "true"
undefinedProfiles
配置文件(Profiles)
Define Profiles
定义配置文件
toml
undefinedtoml
undefinedfnox.toml
fnox.toml
[secrets]
DATABASE_URL = "postgresql://localhost/myapp" # Default
[profiles.production]
[profiles.production.secrets]
DATABASE_URL = { provider = "aws-sm", value = "prod/database-url" }
[profiles.staging]
[profiles.staging.secrets]
DATABASE_URL = { provider = "aws-sm", value = "staging/database-url" }
undefined[secrets]
DATABASE_URL = "postgresql://localhost/myapp" # 默认配置
[profiles.production]
[profiles.production.secrets]
DATABASE_URL = { provider = "aws-sm", value = "prod/database-url" }
[profiles.staging]
[profiles.staging.secrets]
DATABASE_URL = { provider = "aws-sm", value = "staging/database-url" }
undefinedUse Profiles
使用配置文件
bash
undefinedbash
undefinedSet profile via environment variable
通过环境变量设置配置文件
export FNOX_PROFILE=production
fnox get DATABASE_URL
export FNOX_PROFILE=production
fnox get DATABASE_URL
Or use flag
或使用命令行标志
fnox --profile staging get DATABASE_URL
fnox -p production exec -- node app.js
undefinedfnox --profile staging get DATABASE_URL
fnox -p production exec -- node app.js
undefinedProfile-Specific Files
特定配置文件的独立文件
toml
undefinedtoml
undefinedfnox.production.toml
fnox.production.toml
[providers.aws-sm]
type = "aws-sm"
region = "us-east-1"
[secrets]
DATABASE_URL = { provider = "aws-sm", value = "prod/database-url" }
API_KEY = { provider = "aws-sm", value = "prod/api-key" }
```bash[providers.aws-sm]
type = "aws-sm"
region = "us-east-1"
[secrets]
DATABASE_URL = { provider = "aws-sm", value = "prod/database-url" }
API_KEY = { provider = "aws-sm", value = "prod/api-key" }
```bashUse profile-specific file
使用特定配置文件的独立文件
export FNOX_PROFILE=production
fnox get DATABASE_URL # Loads from fnox.production.toml
undefinedexport FNOX_PROFILE=production
fnox get DATABASE_URL # 从fnox.production.toml加载配置
undefinedConfiguration Imports
配置导入
Import Other Configurations
导入其他配置
toml
undefinedtoml
undefinedfnox.toml
fnox.toml
import = ["shared-secrets.toml", "../common/fnox.toml"]
[secrets]
APP_SPECIFIC_SECRET = { provider = "age", value = "age[...]" }
undefinedimport = ["shared-secrets.toml", "../common/fnox.toml"]
[secrets]
APP_SPECIFIC_SECRET = { provider = "age", value = "age[...]" }
undefinedShared Configuration
共享配置
toml
undefinedtoml
undefinedshared-secrets.toml
shared-secrets.toml
[providers.age]
public_keys = ["age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p"]
[secrets]
SHARED_API_KEY = { provider = "age", value = "age[...]" }
undefined[providers.age]
public_keys = ["age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p"]
[secrets]
SHARED_API_KEY = { provider = "age", value = "age[...]" }
undefinedValidation
验证
Check Configuration
检查配置
bash
undefinedbash
undefinedShow diagnostic information
显示诊断信息
fnox doctor
fnox doctor
Verify secrets can be retrieved
验证密钥是否可获取
fnox get DATABASE_URL
fnox get DATABASE_URL
List all configured secrets
列出所有已配置的密钥
fnox list
fnox list
Test specific provider
测试指定的provider
fnox provider test age
undefinedfnox provider test age
undefinedCommon Validation Errors
常见验证错误
toml
undefinedtoml
undefinedError: Missing provider definition
错误:缺失provider定义
[secrets]
API_KEY = { provider = "nonexistent", value = "..." }
[secrets]
API_KEY = { provider = "nonexistent", value = "..." }
Error: Invalid provider configuration
错误:provider配置无效
[providers.age]
[providers.age]
Missing required fields
缺失必填字段
Error: Circular import
错误:循环导入
import = ["other.toml"] # other.toml imports this file
undefinedimport = ["other.toml"] # other.toml导入了当前文件
undefinedBest Practices
最佳实践
Separate Public and Private Config
分离公钥与私钥配置
toml
undefinedtoml
undefinedfnox.toml (committed)
fnox.toml(已提交到版本库)
[providers.age]
public_keys = ["age1ql3z..."] # Public key safe to commit
[secrets]
DATABASE_URL = { provider = "age", value = "age[...]" }
API_KEY = { provider = "age", value = "age[...]" }
[providers.age]
public_keys = ["age1ql3z..."] # 公钥可安全提交
[secrets]
DATABASE_URL = { provider = "age", value = "age[...]" }
API_KEY = { provider = "age", value = "age[...]" }
fnox.local.toml (gitignored)
fnox.local.toml(已加入git忽略)
[providers.age]
identity = "~/.ssh/age-identity.txt" # Private key, never commit
[secrets]
DATABASE_URL = "postgresql://localhost/dev" # Local override
undefined[providers.age]
identity = "~/.ssh/age-identity.txt" # 私钥,绝不能提交
[secrets]
DATABASE_URL = "postgresql://localhost/dev" # 本地开发环境覆盖配置
undefinedDocument Secrets
为密钥添加文档说明
toml
[secrets]
DATABASE_URL = {
provider = "age",
value = "age[...]",
description = "PostgreSQL connection string for production database"
}
STRIPE_API_KEY = {
provider = "age",
value = "age[...]",
description = "Stripe secret key for payment processing"
}
SENDGRID_API_KEY = {
provider = "age",
value = "age[...]",
description = "SendGrid API key for transactional emails"
}toml
[secrets]
DATABASE_URL = {
provider = "age",
value = "age[...]",
description = "生产环境PostgreSQL数据库连接字符串"
}
STRIPE_API_KEY = {
provider = "age",
value = "age[...]",
description = "用于支付处理的Stripe密钥"
}
SENDGRID_API_KEY = {
provider = "age",
value = "age[...]",
description = "用于事务性邮件的SendGrid API密钥"
}Use Meaningful Names
使用有意义的密钥名称
toml
undefinedtoml
undefinedGood: Clear, descriptive names
推荐:清晰、描述性的名称
[secrets]
POSTGRES_CONNECTION_STRING = { provider = "age", value = "age[...]" }
STRIPE_SECRET_KEY = { provider = "age", value = "age[...]" }
JWT_SIGNING_SECRET = { provider = "age", value = "age[...]" }
[secrets]
POSTGRES_CONNECTION_STRING = { provider = "age", value = "age[...]" }
STRIPE_SECRET_KEY = { provider = "age", value = "age[...]" }
JWT_SIGNING_SECRET = { provider = "age", value = "age[...]" }
Avoid: Vague names
避免:模糊的名称
[secrets]
DB = { provider = "age", value = "age[...]" }
KEY1 = { provider = "age", value = "age[...]" }
SECRET = { provider = "age", value = "age[...]" }
undefined[secrets]
DB = { provider = "age", value = "age[...]" }
KEY1 = { provider = "age", value = "age[...]" }
SECRET = { provider = "age", value = "age[...]" }
undefinedSet Appropriate Defaults
设置合理的默认值
toml
[secrets]toml
[secrets]Good: Sensible defaults for non-sensitive config
推荐:对非敏感配置设置合理默认值
LOG_LEVEL = { default = "info" }
CACHE_TTL = { default = "3600" }
LOG_LEVEL = { default = "info" }
CACHE_TTL = { default = "3600" }
Avoid: Defaults for sensitive data
避免:为敏感数据设置默认值
API_KEY = { default = "unsafe-default-key" } # Bad!
undefinedAPI_KEY = { default = "unsafe-default-key" } # 错误示例!
undefinedCommon Patterns
常见配置模式
Multi-Environment Setup
多环境配置
toml
undefinedtoml
undefinedfnox.toml - Base configuration
fnox.toml - 基础配置
[providers.age]
public_keys = ["age1ql3z..."]
[secrets]
APP_NAME = "myapp"
[providers.age]
public_keys = ["age1ql3z..."]
[secrets]
APP_NAME = "myapp"
fnox.development.toml
fnox.development.toml
[secrets]
DATABASE_URL = "postgresql://localhost/myapp_dev"
DEBUG = "true"
[secrets]
DATABASE_URL = "postgresql://localhost/myapp_dev"
DEBUG = "true"
fnox.production.toml
fnox.production.toml
[providers.aws-sm]
type = "aws-sm"
region = "us-east-1"
[secrets]
DATABASE_URL = { provider = "aws-sm", value = "prod/db-url" }
DEBUG = "false"
undefined[providers.aws-sm]
type = "aws-sm"
region = "us-east-1"
[secrets]
DATABASE_URL = { provider = "aws-sm", value = "prod/db-url" }
DEBUG = "false"
undefinedFeature Flags
功能开关
toml
[secrets]
FEATURE_NEW_DASHBOARD = { default = "false" }
FEATURE_BETA_API = { default = "false" }
FEATURE_ROLLOUT_PERCENTAGE = { default = "0" }toml
[secrets]
FEATURE_NEW_DASHBOARD = { default = "false" }
FEATURE_BETA_API = { default = "false" }
FEATURE_ROLLOUT_PERCENTAGE = { default = "0" }Service Configuration
服务配置
toml
[secrets]toml
[secrets]Database
数据库配置
DATABASE_HOST = { provider = "age", value = "age[...]" }
DATABASE_PORT = { default = "5432" }
DATABASE_NAME = { default = "myapp" }
DATABASE_USER = { provider = "age", value = "age[...]" }
DATABASE_PASSWORD = { provider = "age", value = "age[...]" }
DATABASE_HOST = { provider = "age", value = "age[...]" }
DATABASE_PORT = { default = "5432" }
DATABASE_NAME = { default = "myapp" }
DATABASE_USER = { provider = "age", value = "age[...]" }
DATABASE_PASSWORD = { provider = "age", value = "age[...]" }
Redis
Redis配置
REDIS_HOST = { provider = "age", value = "age[...]" }
REDIS_PORT = { default = "6379" }
REDIS_PASSWORD = { provider = "age", value = "age[...]" }
undefinedREDIS_HOST = { provider = "age", value = "age[...]" }
REDIS_PORT = { default = "6379" }
REDIS_PASSWORD = { provider = "age", value = "age[...]" }
undefinedAnti-Patterns
反模式
Don't Commit Private Keys
不要提交私钥
toml
undefinedtoml
undefinedBad: Private key in committed config
错误示例:私钥包含在已提交的配置中
[providers.age]
identity = "AGE-SECRET-KEY-..." # NEVER DO THIS
[providers.age]
identity = "AGE-SECRET-KEY-..." # 绝对不要这样做!
Good: Reference gitignored location
推荐:引用已加入git忽略的文件路径
[providers.age]
identity = "~/.config/fnox/keys/identity.txt"
undefined[providers.age]
identity = "~/.config/fnox/keys/identity.txt"
undefinedDon't Use Plain Text for Sensitive Data
不要用明文存储敏感数据
toml
undefinedtoml
undefinedBad: Sensitive data in plain text
错误示例:敏感数据以明文存储
[secrets]
DATABASE_PASSWORD = "super-secret-password" # Committed to git!
[secrets]
DATABASE_PASSWORD = "super-secret-password" # 已提交到git!
Good: Encrypted
推荐:使用加密存储
[secrets]
DATABASE_PASSWORD = { provider = "age", value = "age[...]" }
undefined[secrets]
DATABASE_PASSWORD = { provider = "age", value = "age[...]" }
undefinedDon't Duplicate Secrets
不要重复定义密钥
toml
undefinedtoml
undefinedBad: Same secret defined multiple times
错误示例:同一密钥多次定义
[secrets]
API_KEY = { provider = "age", value = "age[...]" }
STRIPE_KEY = { provider = "age", value = "age[...]" } # Same as API_KEY
[secrets]
API_KEY = { provider = "age", value = "age[...]" }
STRIPE_KEY = { provider = "age", value = "age[...]" } # 和API_KEY内容相同
Good: Use one secret, reference from code
推荐:定义一次密钥,在代码中引用
[secrets]
STRIPE_API_KEY = { provider = "age", value = "age[...]" }
undefined[secrets]
STRIPE_API_KEY = { provider = "age", value = "age[...]" }
undefinedDon't Mix Concerns
不要混合关注点
toml
undefinedtoml
undefinedBad: Secrets mixed with non-secret config
错误示例:密钥与非敏感配置混合
[secrets]
DATABASE_PASSWORD = { provider = "age", value = "age[...]" }
APP_NAME = "myapp" # Not a secret!
LOG_LEVEL = "info" # Not a secret!
[secrets]
DATABASE_PASSWORD = { provider = "age", value = "age[...]" }
APP_NAME = "myapp" # 这不是密钥!
LOG_LEVEL = "info" # 这不是密钥!
Good: Only secrets in fnox.toml
推荐:fnox.toml中仅存储密钥
[secrets]
DATABASE_PASSWORD = { provider = "age", value = "age[...]" }
[secrets]
DATABASE_PASSWORD = { provider = "age", value = "age[...]" }
Use separate config file for non-secrets
使用独立的配置文件存储非敏感配置
app.config.toml
app.config.toml
APP_NAME = "myapp"
LOG_LEVEL = "info"
undefinedAPP_NAME = "myapp"
LOG_LEVEL = "info"
undefinedAdvanced Patterns
高级配置模式
Template Values
模板化值
toml
[secrets]
DATABASE_HOST = { provider = "age", value = "age[...]" }
DATABASE_NAME = { default = "myapp" }
DATABASE_USER = { provider = "age", value = "age[...]" }
DATABASE_PASSWORD = { provider = "age", value = "age[...]" }toml
[secrets]
DATABASE_HOST = { provider = "age", value = "age[...]" }
DATABASE_NAME = { default = "myapp" }
DATABASE_USER = { provider = "age", value = "age[...]" }
DATABASE_PASSWORD = { provider = "age", value = "age[...]" }Constructed in application code from components above
在应用代码中通过上述组件构造完整连接字符串
DATABASE_URL = postgresql://{USER}:{PASSWORD}@{HOST}/{NAME}
DATABASE_URL = postgresql://{USER}:{PASSWORD}@{HOST}/{NAME}
undefinedundefinedConditional Secrets
条件式密钥
toml
[secrets]toml
[secrets]Base secrets always loaded
基础密钥始终加载
API_KEY = { provider = "age", value = "age[...]" }
[profiles.ci]
[profiles.ci.secrets]
API_KEY = { provider = "age", value = "age[...]" }
[profiles.ci]
[profiles.ci.secrets]
Additional secrets only for CI
仅CI环境加载的额外密钥
CI_TOKEN = { provider = "age", value = "age[...]" }
DEPLOY_KEY = { provider = "age", value = "age[...]" }
undefinedCI_TOKEN = { provider = "age", value = "age[...]" }
DEPLOY_KEY = { provider = "age", value = "age[...]" }
undefinedRelated Skills
相关技能
- providers: Configuring encryption and secret storage providers
- security-best-practices: Security guidelines for secrets management
- providers: 配置加密与密钥存储provider
- security-best-practices: 密钥管理的安全指南