Skip to content

Secrets Patterns

Patterns & Best Practices

Secrets vs. Config

A common question is whether to use the Config Store or the Secret Vault.

FeatureSecretsConfig Store
EncryptionAES-256-GCM (Encrypted).Plaintext JSON.
VisibilityWrite-only (except in function).Readable via API/UI.
Best ForAPI Keys, DB Passwords.Feature flags, Timeouts.

Pattern: Optional Dependencies

Functions should check if a secret is available before using it. This allows your code to gracefully degrade if an integration (like Slack or Sentry) isn’t configured in a specific environment.

async ({ event, secrets, step }) => {
if (secrets.has("SLACK_WEBHOOK")) {
const url = secrets.get("SLACK_WEBHOOK");
await step.run("notify", () => postToSlack(url, "Task started!"));
}
}

Environment Promotion

Secrets are strictly scoped to an Environment. You must set them independently for each stage of your pipeline.

Terminal window
# Development
ironflow secret set DB_PASSWORD dev_pass --env default
# Production (using the specific environment API Key)
IRONFLOW_API_KEY="ifkey_prod_..." ironflow secret set DB_PASSWORD prod_pass

Security Checklist

  1. Always Set the Master Key in Production: IRONFLOW_MASTER_KEY must be set to a hex-encoded 32 bytes (openssl rand -hex 32). If the variable is unset or empty, Ironflow falls back to a development mode that stores secret values in plaintext on disk and logs a warning at startup.
  2. Treat the Master Key as Immutable: If you rotate IRONFLOW_MASTER_KEY, all previously stored secrets become unreadable. Plan rotations as a full re-set of every secret.
  3. Environment Isolation: Use different API Keys for CI/CD and Production. An API Key leaked from a dev environment cannot access production secrets.
  4. No Logging: Decrypted secret values are not automatically redacted from your application logs. Avoid passing secret values into console.log, structured log fields, error messages, or third-party telemetry. The engine itself never logs the plaintext.
  5. Least Privilege: Only declare the secrets your function actually needs in the secrets: [...] array.