fnox-configuration

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Fnox - 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
undefined
bash
undefined

Create fnox.toml in current directory

在当前目录创建fnox.toml

fnox init
fnox init

Initialize with specific provider

使用指定的provider初始化

fnox init --provider age
undefined
fnox init --provider age
undefined

Basic fnox.toml Structure

基础fnox.toml结构

toml
undefined
toml
undefined

fnox.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密钥" }
undefined

Secrets 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)

文件优先级顺序

  1. fnox.local.toml
    - Local overrides (gitignored)
  2. fnox.$FNOX_PROFILE.toml
    - Profile-specific
  3. fnox.toml
    - Project configuration
  4. Parent directory
    fnox.toml
    files (recursive)
  5. ~/.config/fnox/config.toml
    - Global configuration
  1. fnox.local.toml
    - 本地覆盖配置(已加入git忽略)
  2. fnox.$FNOX_PROFILE.toml
    - 特定配置文件
  3. fnox.toml
    - 项目级配置
  4. 父目录中的
    fnox.toml
    文件(递归查找)
  5. ~/.config/fnox/config.toml
    - 全局配置

Global Configuration

全局配置

toml
undefined
toml
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" # 密钥缺失时的全局默认行为
undefined

Project Configuration

项目配置

toml
undefined
toml
undefined

project/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"
undefined

Local Overrides

本地覆盖配置

toml
undefined
toml
undefined

project/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"
undefined

Profiles

配置文件(Profiles)

Define Profiles

定义配置文件

toml
undefined
toml
undefined

fnox.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" }
undefined

Use Profiles

使用配置文件

bash
undefined
bash
undefined

Set 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
undefined
fnox --profile staging get DATABASE_URL fnox -p production exec -- node app.js
undefined

Profile-Specific Files

特定配置文件的独立文件

toml
undefined
toml
undefined

fnox.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" }

```bash

Use profile-specific file

使用特定配置文件的独立文件

export FNOX_PROFILE=production fnox get DATABASE_URL # Loads from fnox.production.toml
undefined
export FNOX_PROFILE=production fnox get DATABASE_URL # 从fnox.production.toml加载配置
undefined

Configuration Imports

配置导入

Import Other Configurations

导入其他配置

toml
undefined
toml
undefined

fnox.toml

fnox.toml

import = ["shared-secrets.toml", "../common/fnox.toml"]
[secrets] APP_SPECIFIC_SECRET = { provider = "age", value = "age[...]" }
undefined
import = ["shared-secrets.toml", "../common/fnox.toml"]
[secrets] APP_SPECIFIC_SECRET = { provider = "age", value = "age[...]" }
undefined

Shared Configuration

共享配置

toml
undefined
toml
undefined

shared-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[...]" }
undefined

Validation

验证

Check Configuration

检查配置

bash
undefined
bash
undefined

Show 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
undefined
fnox provider test age
undefined

Common Validation Errors

常见验证错误

toml
undefined
toml
undefined

Error: 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
undefined
import = ["other.toml"] # other.toml导入了当前文件
undefined

Best Practices

最佳实践

Separate Public and Private Config

分离公钥与私钥配置

toml
undefined
toml
undefined

fnox.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" # 本地开发环境覆盖配置
undefined

Document 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
undefined
toml
undefined

Good: 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[...]" }
undefined

Set 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!
undefined
API_KEY = { default = "unsafe-default-key" } # 错误示例!
undefined

Common Patterns

常见配置模式

Multi-Environment Setup

多环境配置

toml
undefined
toml
undefined

fnox.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"
undefined

Feature 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[...]" }
undefined
REDIS_HOST = { provider = "age", value = "age[...]" } REDIS_PORT = { default = "6379" } REDIS_PASSWORD = { provider = "age", value = "age[...]" }
undefined

Anti-Patterns

反模式

Don't Commit Private Keys

不要提交私钥

toml
undefined
toml
undefined

Bad: 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"
undefined

Don't Use Plain Text for Sensitive Data

不要用明文存储敏感数据

toml
undefined
toml
undefined

Bad: 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[...]" }
undefined

Don't Duplicate Secrets

不要重复定义密钥

toml
undefined
toml
undefined

Bad: 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[...]" }
undefined

Don't Mix Concerns

不要混合关注点

toml
undefined
toml
undefined

Bad: 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"
undefined
APP_NAME = "myapp" LOG_LEVEL = "info"
undefined

Advanced 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}

undefined
undefined

Conditional 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[...]" }
undefined
CI_TOKEN = { provider = "age", value = "age[...]" } DEPLOY_KEY = { provider = "age", value = "age[...]" }
undefined

Related Skills

相关技能

  • providers: Configuring encryption and secret storage providers
  • security-best-practices: Security guidelines for secrets management
  • providers: 配置加密与密钥存储provider
  • security-best-practices: 密钥管理的安全指南