Handling missing secrets
Use the if_missing setting to control what happens when a secret can't be resolved. This is especially useful for CI environments or when some secrets are optional.
Available modes
These policies apply when a command resolves multiple secrets. An explicit fnox get KEY may still return a provider error directly. A configured default is tried as a fallback before a value is considered missing.
error- Fail the command if a secret cannot be resolved (strictest)warn- Print a warning and continue (default)ignore- Silently skip missing secrets
Priority chain
You can set if_missing at multiple levels. fnox uses the first match:
- CLI flag (highest priority):
--if-missing error - Environment variable:
FNOX_IF_MISSING=warn - Secret-level config:
[secrets.MY_SECRET]withif_missing = "error" - Top-level config: Global default for all secrets
- Base default environment variable:
FNOX_IF_MISSING_DEFAULT=error - Default:
warn(lowest priority)
Per-secret configuration
Set different behaviors for different secrets:
[secrets]
# Critical secrets must exist
DATABASE_URL = { provider = "aws", value = "database-url", if_missing = "error" } # Fail if missing
# Optional secrets
ANALYTICS_KEY = { provider = "aws", value = "analytics-key", if_missing = "ignore" } # Continue silently if missing
# Warn about missing secrets (default)
CACHE_URL = { provider = "aws", value = "cache-url", if_missing = "warn" } # Print warning if missingTop-level default
Set a default for all secrets:
# Make all secrets strict by default
if_missing = "error"
[secrets]
DATABASE_URL = { provider = "age", value = "encrypted..." } # Inherits if_missing = "error"
API_KEY = { provider = "age", value = "encrypted..." } # Inherits if_missing = "error"
OPTIONAL_FEATURE_FLAG = { default = "false", if_missing = "ignore" } # Override - this one can be missingRuntime override with CLI
Override config settings at runtime:
# Override to be lenient (useful in CI with missing secrets)
fnox exec --if-missing ignore -- npm test
# Override to be strict (ensure all secrets are present)
fnox exec --if-missing error -- ./deploy.sh
# Use warnings (default)
fnox exec --if-missing warn -- npm startRuntime override with environment variable
# Set globally for a session
export FNOX_IF_MISSING=warn
fnox exec -- npm start
# Or inline
FNOX_IF_MISSING=error fnox exec -- ./critical-task.shBase default behavior
Set a default behavior when if_missing is not configured anywhere:
# Change the default from "warn" to "error"
export FNOX_IF_MISSING_DEFAULT=error
# Now all secrets without explicit if_missing will fail if missing
fnox exec -- ./my-appThis is useful for:
- Making your entire project strict by default
- CI/CD environments where you want failures by default
- Development environments where you want warnings by default
Priority: This has the lowest priority and only applies when if_missing is not set in:
- CLI flags
FNOX_IF_MISSINGenv var- Secret-level config
- Top-level config
CI/CD examples
These workflow excerpts assume fnox and any provider CLI have been installed. Supply provider credentials for tests that require real secrets.
Forked PRs (secrets unavailable)
# .github/workflows/test.yml
name: Test
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run tests (some secrets may be missing in forks)
env:
FNOX_IF_MISSING: ignore # Don't fail on missing secrets
run: |
fnox exec -- npm testProduction deployment (strict)
# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v4
- name: Deploy to production
env:
FNOX_IF_MISSING: error # Fail if any secret is missing
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
run: |
fnox exec --profile production -- ./deploy.shStaging (warn on missing)
# .github/workflows/staging.yml
jobs:
deploy-staging:
runs-on: ubuntu-latest
steps:
- name: Deploy to staging
env:
FNOX_IF_MISSING: warn # Print warnings but continue
run: |
fnox exec --profile staging -- ./deploy.shUse cases
Optional analytics/monitoring
[secrets]
# Won't break the app if missing
SENTRY_DSN = { provider = "aws", value = "sentry-dsn", if_missing = "ignore" }
DATADOG_API_KEY = { provider = "aws", value = "datadog-key", if_missing = "ignore" }Required database
[secrets]
DATABASE_URL = { provider = "aws", value = "database-url", if_missing = "error" } # Must exist or failDevelopment defaults
[secrets]
REDIS_URL = { provider = "aws", value = "redis-url", default = "redis://localhost:6379", if_missing = "warn" } # Fall back to the local URL if the provider lookup failsBehavior summary
| Mode | Behavior | Use Case |
|---|---|---|
error | Fail command | Required secrets (database, API keys) |
warn | Print warning, continue | Optional but recommended secrets |
ignore | Silent skip | Truly optional features (analytics, etc.) |
Next steps
- Profiles - Different secrets per environment
- Import/Export - Migrate secrets between systems
- Real-World Example - Complete setup with error handling