Skip to main content

Configuration

flAPI uses YAML files for configuration. The main configuration file (flapi.yaml) defines global settings, connections, and server behaviour. This page is an introduction to each top-level section — see the upstream Configuration Reference for the full option list.

Naming Conventions​

flAPI configuration keys use hyphenated names (project-name, template-source, url-path, enforce-https). The only exception is the duckdb: block, whose keys (db_path, access_mode, max_memory, default_order, threads, …) keep snake_case because they are forwarded verbatim to DuckDB.

Project Metadata​

project-name: example-flapi-project
project-description: An example flAPI project

template:
path: './sqls' # Path to SQL templates and endpoint configs
environment-whitelist: # Optional: which env vars may be substituted in templates
- '^FLAPI_.*'

Other top-level metadata keys: server-name (default "localhost") and http-port (default 8080).

See: CONFIG_REFERENCE.md §2.1 Project Metadata.

DuckDB Settings​

Configure the embedded DuckDB instance. Note the snake_case keys — they are passed through directly to DuckDB:

duckdb:
db_path: ./flapi_cache.db # Optional: omit for in-memory (default :memory:)
access_mode: READ_WRITE # READ_WRITE or READ_ONLY
threads: 8 # Default: auto
max_memory: 8GB # Default: auto
default_order: DESC # ASC or DESC

Any additional key under duckdb: is forwarded as a DuckDB SET option.

See: CONFIG_REFERENCE.md §2.4 DuckDB Configuration.

Connections​

Define your data source connections. Each connection is keyed by a unique name and may have an init: block (SQL run once when the connection is opened) and a properties: block (key-value pairs accessible in templates as {{ conn.<key> }}).

connections:
# Local Parquet file
customers-parquet:
properties:
path: './data/customers.parquet'

# BigQuery connection
bigquery-lakehouse:
init: |
INSTALL 'bigquery' FROM community;
LOAD 'bigquery';
properties:
project_id: 'my-project-id'

Default: no connections defined. See: CONFIG_REFERENCE.md §2.3 Connections.

DuckLake (Snapshot Cache)​

DuckLake adds snapshot-based caching with retention, compaction, and a scheduler for periodic refreshes. It is disabled by default.

ducklake:
enabled: true
alias: cache # Catalog alias (default: "cache")
metadata-path: ./data/cache.ducklake # Metadata directory
data-path: ./data/cache # Data files directory
retention:
keep-last-snapshots: 10
max-snapshot-age: 30d
compaction:
enabled: true
schedule: '@daily'
scheduler:
enabled: true
scan-interval: 5m # How often to check for scheduled refreshes

Default: ducklake.enabled: false. See: CONFIG_REFERENCE.md §2.5 DuckLake Configuration.

MCP (Model Context Protocol)​

flAPI exposes both REST endpoints and MCP tools/resources/prompts. The MCP server is enabled by default on port 8081; you only need an mcp: block to override defaults or to provide LLM-facing instructions.

mcp:
enabled: true # Default: true
port: 8081 # Default: 8081
host: localhost
allow-list-changed-notifications: true
instructions-file: ./mcp_instructions.md # Or inline via `instructions: |`

Per-endpoint MCP behaviour is configured inside endpoint YAML files (mcp-tool:, mcp-resource:, mcp-prompt:).

See: CONFIG_REFERENCE.md §2.6 MCP Configuration.

Global Authentication​

Set a default authentication policy that applies to all endpoints unless overridden at the endpoint level. Supported types: basic, jwt, bearer, oidc.

auth:
enabled: true
type: basic
users:
- username: admin
password: '{{env.ADMIN_PASSWORD}}'
roles: [admin, read, write]
auth:
enabled: true
type: bearer
jwt-secret: '{{env.JWT_SECRET}}'
jwt-issuer: '{{env.JWT_ISSUER}}'

Default: auth.enabled: false. See: CONFIG_REFERENCE.md §2.7 Authentication (Global) and §7 for the per-type options.

Global Rate Limiting​

Apply a global request budget across all endpoints. Per-endpoint rate-limit: blocks override this.

rate_limit:
enabled: true
max: 100 # Default: 100
interval: 60 # Time window in seconds (default: 60)
key: user-or-ip # Bucket strategy (default: ip)

rate-limit.key picks the bucket strategy:

  • ip (default, legacy) — per-IP. Behaves identically to older flAPI releases.
  • user — per-authenticated-principal. Unauthenticated requests are not rate-limited via this strategy (they fall back to the IP bucket if also configured).
  • user-or-ip — authenticated principal when present, IP fallback otherwise. Recommended for share-NAT scenarios where many users share a single egress IP.

Default: rate_limit.enabled: false. See: CONFIG_REFERENCE.md §2.8 Rate Limiting (Global).

CORS Allow-List​

flAPI no longer emits the wildcard Access-Control-Allow-Origin: * by default. Opt into specific origins via:

cors:
allow-origins:
- https://app.example.com
- https://staging.example.com

flapii project init still ships ["*"] so first-run demos work; the startup auditor warns at boot when * is combined with auth.enabled: true (credential-bearing requests across origins).

Request Audit Log​

Per-request JSONL audit log for both REST and MCP traffic. Off by default — opt in:

audit:
enabled: true
sink: file # `stdout` for container log collectors, `file`, or `null`
path: ./logs/audit.jsonl
redact: # Values for these parameter names become <redacted>
- tax_id
- customer_ref

Each event is a single JSON line:

{"timestamp":"2026-05-17T05:32:11Z","request_id":"req-9f2c1a7b8e4d5063","principal":"alice","method":"POST","target":"/customers/:id","status":"success","row_count":1,"latency_ms":12,"params":{"id":"42"}}

status is one of success (2xx), denied (401/403), rate_limited (429), or error:<code>. target is the route template, never the filled path — a filled path on a data API is a filter over customer data.

Coverage is every request on every route, REST and MCP alike, including ones rejected before the handler runs: a 401, a 403 and a 429 each produce a line. Health probes (/health, /health/live, /mcp/health) produce none.

Credential-shaped names are redacted whether or not you list them

redact is for your field names. Names that look like credentials — password, api_key, x-api-key, auth_token, authorization, cookie, client_secret, private_key, connection_string and similar — are masked regardless of configuration, so the guarantee does not depend on your list being complete. Matching ignores case, - and _.

With tracing enabled, each line also carries trace_id and span_id, so an audit entry joins to the trace and to the application log. Without it the schema is byte-identical.

HTTPS Enforcement​

flAPI can terminate TLS directly via OpenSSL. Reverse-proxy termination is still recommended for production, but direct TLS is supported for self-contained deployments.

# Bind the listener as HTTPS:
https:
enabled: true
ssl_cert_file: ./ssl/cert.pem
ssl_key_file: ./ssl/key.pem

# Optional: redirect plain-HTTP requests to HTTPS instead of refusing them
enforce-https:
enabled: true

See: CONFIG_REFERENCE.md §2.9 HTTPS Configuration.

Startup Security Auditor​

At boot, flAPI scans the loaded config and emits structured warnings for:

  • Plaintext passwords in auth.users[*].password — recommend migrating to $pbkdf2-sha256$… MCF hashes.
  • MD5 password hashes (32-char hex) — recommend migrating to PBKDF2-SHA256.
  • MCP exposed without auth on a non-loopback bind — large blast radius for a misconfigured agent.
  • CORS wildcard combined with auth.enabled: true — credential-bearing requests across origins.

The warnings appear at INFO level in the startup logs; the server still starts. To opt into stricter behaviour, combine with mcp.strict-descriptions: true (refuses to start if any MCP tool description fails the prompt-injection hygiene scan).

Heartbeat​

A background worker that emits periodic health signals.

heartbeat:
enabled: true # Default: false
worker-interval: 10 # Seconds (default: 60)

See: CONFIG_REFERENCE.md §2.10 Heartbeat Configuration.

Remote Configuration & Templates (VFS)​

flAPI can load flapi.yaml itself, the SQL templates directory, and individual template-source: files from remote storage via DuckDB's Virtual File System. Supported schemes: https://, http://, s3://, s3a://, s3n://, gs://, az://, abfs://, file:// (defaults: file and https only — additional schemes are enabled by loading the relevant DuckDB extension in a connection's init: block).

# Load main config from HTTPS or S3
./flapi --config https://example.com/configs/flapi.yaml
./flapi --config s3://my-bucket/configs/flapi.yaml
# Or point the template root at a remote location
template:
path: s3://my-bucket/templates/

Cloud-storage credentials are read from the usual environment variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION, GOOGLE_APPLICATION_CREDENTIALS, AZURE_STORAGE_ACCOUNT, AZURE_STORAGE_KEY, …).

See: CONFIG_REFERENCE.md §2.11 Storage Configuration (VFS).

Telemetry​

flAPI sends anonymous application_start / application_stop events to PostHog by default. To opt out:

telemetry:
enabled: false # Default: true

Opt-out precedence (highest wins): --no-telemetry CLI flag → FLAPI_NO_TELEMETRY=1 → telemetry.enabled: false → DATAZOO_DISABLE_TELEMETRY=1.

See: CONFIG_REFERENCE.md §2.12 Telemetry Configuration.

Environment Variables in Configuration​

You can substitute environment variables anywhere in YAML using the ${VAR_NAME} syntax. Only variables matching the patterns in template.environment-whitelist are exposed.

template:
environment-whitelist:
- '^FLAPI_.*'
- '^DB_.*'

connections:
postgres-db:
properties:
host: '${DB_HOST}'
password: '${DB_PASSWORD}'

Complete Example​

project-name: example-flapi-project
project-description: An example flAPI project

template:
path: './sqls'
environment-whitelist:
- '^FLAPI_.*'

connections:
customers-parquet:
properties:
path: './data/customers.parquet'

duckdb:
db_path: ./flapi_cache.db
access_mode: READ_WRITE
threads: 8
max_memory: 8GB
default_order: DESC

ducklake:
enabled: true
alias: cache
metadata-path: ./data/cache.ducklake
data-path: ./data/cache
retention:
keep-last-snapshots: 10
max-snapshot-age: 30d

mcp:
enabled: true
port: 8081
host: localhost

auth:
enabled: false

rate_limit:
enabled: true
max: 100
interval: 60

heartbeat:
enabled: true
worker-interval: 10

enforce-https:
enabled: false

telemetry:
enabled: true

Next Steps​

🍪 Cookie Settings