Skip to content

Configuration Reference

Complete reference for the fnox.toml configuration file.

File Location

fnox looks for configuration files in this order:

  1. Path specified via -c, --config flag
  2. fnox.toml in current directory
  3. fnox.toml in parent directories (hierarchical search)
  4. fnox.local.toml alongside each fnox.toml (for local overrides)

Basic Structure

toml
# Top-level settings
if_missing = "warn"  # Global default for missing secrets
imports = ["./shared/secrets.toml"]  # Import other configs

# Provider definitions
[providers.PROVIDER_NAME]
type = "PROVIDER_TYPE"
# ... provider-specific config ...

# Secret definitions
[secrets.SECRET_NAME]
provider = "PROVIDER_NAME"
value = "..."
default = "..."
if_missing = "error"
description = "..."

# Profile definitions
[profiles.PROFILE_NAME]
# ... same structure as top-level ...

Top-Level Settings

if_missing

Global default behavior when secrets cannot be resolved.

toml
if_missing = "error"  # or "warn", "ignore"

Values:

  • "error" - Fail if secret is missing
  • "warn" - Print warning and continue (default)
  • "ignore" - Silently skip missing secrets

Priority: Lowest (overridden by secret-level, env vars, CLI flags).

imports

List of config files to import.

toml
imports = ["./shared/base.toml", "./envs/dev.toml"]

Usage:

  • Paths relative to current config file
  • Imported files merged into current config
  • Later imports override earlier ones

Provider Configuration

toml
[providers.PROVIDER_NAME]
type = "PROVIDER_TYPE"
# ... provider-specific fields ...

Common Provider Types

Age Encryption

toml
[providers.age]
type = "age"
recipients = [
  "age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p",
  "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGQs..."
]

AWS Secrets Manager

toml
[providers.aws]
type = "aws-sm"
region = "us-east-1"
prefix = "myapp/"  # Optional

AWS KMS

toml
[providers.kms]
type = "aws-kms"
key_id = "arn:aws:kms:us-east-1:123456789012:key/..."
region = "us-east-1"

Azure Key Vault Secrets

toml
[providers.azure]
type = "azure-sm"
vault_url = "https://myapp-vault.vault.azure.net/"
prefix = "myapp/"  # Optional

Azure Key Vault Keys

toml
[providers.azurekms]
type = "azure-kms"
vault_url = "https://myapp-vault.vault.azure.net/"
key_name = "encryption-key"

GCP Secret Manager

toml
[providers.gcp]
type = "gcp-sm"
project = "my-project-id"
prefix = "myapp/"  # Optional

GCP Cloud KMS

toml
[providers.gcpkms]
type = "gcp-kms"
project = "my-project-id"
location = "us-central1"
keyring = "fnox-keyring"
key = "fnox-key"

1Password

toml
[providers.onepass]
type = "1password"
vault = "Development"
account = "my.1password.com"  # Optional

Bitwarden

toml
[providers.bitwarden]
type = "bitwarden"
collection = "collection-id"     # Optional
organization_id = "org-id"       # Optional

HashiCorp Vault

toml
[providers.vault]
type = "vault"
address = "https://vault.example.com:8200"
path = "secret/myapp"
token = "hvs.CAESIJ..."  # Optional, can use VAULT_TOKEN env var

OS Keychain

toml
[providers.keychain]
type = "keychain"
service = "fnox"
prefix = "myapp/"  # Optional

Secret Configuration

toml
[secrets.SECRET_NAME]
provider = "PROVIDER_NAME"    # Required (unless using default)
value = "..."                 # Provider-specific value
default = "..."               # Fallback value
if_missing = "error"          # Behavior when missing
description = "..."           # Human-readable description

Fields

provider

Provider to use for this secret.

toml
[secrets.DATABASE_URL]
provider = "age"
value = "encrypted..."

Required: Unless using only default (plain text).

value

Provider-specific value:

  • Encryption providers (age, aws-kms, etc.): Encrypted ciphertext
  • Remote providers (aws-sm, 1password, etc.): Secret name/reference
toml
# Encrypted ciphertext (age)
[secrets.DATABASE_URL]
provider = "age"
value = "YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNjcnlwdC..."

# Remote reference (AWS)
[secrets.DATABASE_URL]
provider = "aws"
value = "database-url"  # Secret name in AWS Secrets Manager

default

Fallback value if secret cannot be resolved.

toml
[secrets.DATABASE_URL]
provider = "age"
value = "encrypted..."
default = "postgresql://localhost/dev"  # Fallback for local dev

Use for:

  • Non-sensitive defaults
  • Local development fallbacks
  • Optional configuration

if_missing

Behavior when secret cannot be resolved.

toml
[secrets.DATABASE_URL]
provider = "aws"
value = "database-url"
if_missing = "error"  # Fail if missing (critical secret)

[secrets.ANALYTICS_KEY]
provider = "aws"
value = "analytics-key"
if_missing = "ignore"  # Silently skip if missing (optional)

Values: "error", "warn", "ignore"

Priority: Overrides top-level if_missing, but overridden by env vars and CLI flags.

description

Human-readable description.

toml
[secrets.DATABASE_URL]
provider = "age"
value = "encrypted..."
description = "Production database connection string"

Profile Configuration

Profiles allow environment-specific configuration:

toml
# Default profile (no prefix)
[secrets.DATABASE_URL]
provider = "age"
value = "encrypted-dev..."

# Production profile
[profiles.production]

[profiles.production.providers.aws]
type = "aws-sm"
region = "us-east-1"

[profiles.production.secrets.DATABASE_URL]
provider = "aws"
value = "database-url"

Profile Structure

toml
[profiles.PROFILE_NAME]
if_missing = "error"  # Profile-specific default

[profiles.PROFILE_NAME.providers.PROVIDER_NAME]
type = "PROVIDER_TYPE"
# ... provider config ...

[profiles.PROFILE_NAME.secrets.SECRET_NAME]
provider = "PROVIDER_NAME"
value = "..."
# ... secret config ...

Profile Inheritance

Profiles inherit top-level secrets and providers:

toml
# Top-level (inherited by all profiles)
[secrets.LOG_LEVEL]
default = "info"

[secrets.DATABASE_URL]
provider = "age"
value = "encrypted-dev..."

# Production profile
[profiles.production.secrets.DATABASE_URL]
provider = "aws"
value = "prod-db"  # Overrides top-level DATABASE_URL
# Inherits LOG_LEVEL="info" from top-level

Complete Example

toml
# Global settings
if_missing = "warn"
imports = ["./shared/common.toml"]

# Providers
[providers.age]
type = "age"
recipients = ["age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p"]

[providers.aws]
type = "aws-sm"
region = "us-east-1"
prefix = "myapp/"

# Default profile secrets
[secrets.DATABASE_URL]
provider = "age"
value = "YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNjcnlwdC..."
default = "postgresql://localhost/dev"
description = "Database connection string"

[secrets.JWT_SECRET]
provider = "age"
value = "encrypted..."
if_missing = "error"

[secrets.LOG_LEVEL]
default = "info"

# Production profile
[profiles.production]
if_missing = "error"

[profiles.production.providers.aws]
type = "aws-sm"
region = "us-east-1"
prefix = "myapp-prod/"

[profiles.production.secrets.DATABASE_URL]
provider = "aws"
value = "database-url"
description = "Production database"

[profiles.production.secrets.JWT_SECRET]
provider = "aws"
value = "jwt-secret"

# Inherits LOG_LEVEL from top-level

Local Overrides

Create fnox.local.toml alongside fnox.toml for local overrides:

toml
# fnox.local.toml (gitignored)

# Override secrets for local development
[secrets.DATABASE_URL]
default = "postgresql://localhost/mylocal"

[secrets.DEBUG_MODE]
default = "true"

Important: Add to .gitignore:

gitignore
fnox.local.toml

Hierarchical Configuration

fnox searches parent directories for fnox.toml files:

project/
├── fnox.toml              # Root config
└── services/
    └── api/
        └── fnox.toml      # API config (inherits from root)

Merge order (lowest to highest priority):

  1. Root fnox.toml
  2. Root fnox.local.toml
  3. Child fnox.toml
  4. Child fnox.local.toml

Next Steps

Released under the MIT License.