Configuration

Melange supports configuration via YAML files, environment variables, and command-line flags with the following precedence (highest to lowest):

  1. Command-line flags
  2. Environment variables (MELANGE_* prefix)
  3. Configuration file (melange.yaml or melange.yml)
  4. Built-in defaults

Configuration File

Melange automatically discovers a configuration file by:

  1. Looking for melange.yaml or melange.yml in the current directory
  2. Walking up parent directories until a .git directory is found (repository boundary)
  3. Stopping after 25 parent levels if no repository boundary is found

You can override auto-discovery with --config:

melange --config /path/to/custom-config.yaml migrate

File Format

Create a melange.yaml in your project root:

# Path to OpenFGA schema file (used by all commands)
schema: schemas/schema.fga

# Database connection (used by migrate, status, doctor)
database:
  # Option 1: Full connection URL
  url: postgres://user:password@localhost:5432/mydb?sslmode=prefer

  # Option 2: Discrete fields (used when url is empty)
  # host: localhost
  # port: 5432
  # name: mydb
  # user: melange
  # password: secret
  # sslmode: prefer

# Code generation settings
generate:
  client:
    runtime: go
    schema: schemas/schema.fga  # Overrides top-level schema
    output: internal/authz
    package: authz
    filter: can_
    id_type: string

# Migration settings
migrate:
  dry_run: false
  force: false

# Doctor command settings
doctor:
  verbose: false

Minimal Configuration

A minimal configuration for most projects:

schema: schemas/schema.fga

database:
  url: postgres://localhost/mydb

generate:
  client:
    runtime: go
    output: internal/authz

Configuration Reference

Top-Level Settings

KeyTypeDefaultDescription
schemastringschemas/schema.fgaPath to the OpenFGA schema file

Database Settings

Configure under database::

KeyTypeDefaultDescription
urlstring-Full PostgreSQL connection URL
hoststring-Database host (used when url is empty)
portint5432Database port
namestring-Database name
userstring-Database user
passwordstring-Database password
sslmodestringpreferSSL mode for connection

Connection URL format:

postgres://user:password@host:5432/dbname?sslmode=require

Required fields when using discrete configuration:

  • host
  • name
  • user

SSL Mode Values:

ValueDescription
disableNo SSL
allowTry non-SSL first, then SSL
preferTry SSL first, then non-SSL (default)
requireRequire SSL
verify-caRequire SSL and verify CA
verify-fullRequire SSL and verify CA and hostname

Generate Client Settings

Configure under generate.client::

KeyTypeDefaultDescription
runtimestring-Target runtime: go, typescript
schemastring(top-level schema)Path to schema file
outputstring-Output directory for generated code
packagestringauthzPackage/module name
filterstring-Relation prefix filter (e.g., can_)
id_typestringstringID type for constructors

Migrate Settings

Configure under migrate::

KeyTypeDefaultDescription
dry_runboolfalseOutput SQL without applying
forceboolfalseForce migration even if unchanged

Doctor Settings

Configure under doctor::

KeyTypeDefaultDescription
verboseboolfalseShow detailed output

Environment Variables

All configuration options can be set via environment variables with the MELANGE_ prefix. Use underscores to separate nested keys:

Environment VariableConfiguration Path
MELANGE_SCHEMAschema
MELANGE_DATABASE_URLdatabase.url
MELANGE_DATABASE_HOSTdatabase.host
MELANGE_DATABASE_PORTdatabase.port
MELANGE_DATABASE_NAMEdatabase.name
MELANGE_DATABASE_USERdatabase.user
MELANGE_DATABASE_PASSWORDdatabase.password
MELANGE_DATABASE_SSLMODEdatabase.sslmode
MELANGE_GENERATE_CLIENT_RUNTIMEgenerate.client.runtime
MELANGE_GENERATE_CLIENT_SCHEMAgenerate.client.schema
MELANGE_GENERATE_CLIENT_OUTPUTgenerate.client.output
MELANGE_GENERATE_CLIENT_PACKAGEgenerate.client.package
MELANGE_GENERATE_CLIENT_FILTERgenerate.client.filter
MELANGE_GENERATE_CLIENT_ID_TYPEgenerate.client.id_type
MELANGE_MIGRATE_DRY_RUNmigrate.dry_run
MELANGE_MIGRATE_FORCEmigrate.force
MELANGE_DOCTOR_VERBOSEdoctor.verbose

Example:

export MELANGE_DATABASE_URL="postgres://prod-user:secret@prod-db:5432/myapp"
export MELANGE_GENERATE_CLIENT_RUNTIME="go"
melange migrate

Boolean values: Use true/false or 1/0 for boolean environment variables.

Configuration Inheritance

Per-command settings can override top-level settings:

# Top-level default
schema: schemas/schema.fga

generate:
  client:
    # Overrides top-level schema for generate command only
    schema: schemas/api-schema.fga

Viewing Effective Configuration

Use melange config show to see the effective configuration after merging all sources:

# Show effective configuration
melange config show

# Show with config file path
melange config show --source

Output:

Config file: /path/to/project/melange.yaml

schema: schemas/schema.fga
database:
  url: postgres://localhost/mydb
  host: ""
  port: 5432
  ...

Security Considerations

  • Prefer environment variables for secrets in production environments
  • Avoid committing melange.yaml files containing database.password to version control
  • Consider using connection URLs with credentials stored in secure secret management systems
  • For local development, discrete fields in a .gitignored config file are acceptable

Example Configurations

Local Development

schema: schemas/schema.fga

database:
  url: postgres://localhost/myapp_dev

generate:
  client:
    runtime: go
    output: internal/authz
    package: authz

CI/CD Pipeline

Use environment variables for credentials:

# .github/workflows/deploy.yml
env:
  MELANGE_DATABASE_URL: ${{ secrets.DATABASE_URL }}

With a minimal config file:

schema: schemas/schema.fga

generate:
  client:
    runtime: go
    output: internal/authz

Multi-Environment

Use different config files per environment:

# Development
melange --config melange.dev.yaml migrate

# Production
melange --config melange.prod.yaml migrate

Or use environment variable overrides with a shared base config:

# melange.yaml (shared)
schema: schemas/schema.fga

generate:
  client:
    runtime: go
    output: internal/authz
# Override database per environment
MELANGE_DATABASE_URL="postgres://prod-host/myapp" melange migrate