faz.yaml
The complete schema for faz.yaml — every key, every type, every default — with an annotated reference example.
faz.yaml is the single config file for a faz instance. It declares which databases to connect, what permissions apply to each, and the global safety defaults. Every faz process reads it once at startup. There's no separate auth file, no separate routing config, no separate secrets store.
This page is the schema reference. For the concept walkthrough on permissions, see Permissions. For environment variables and CLI flags that affect a running instance, see Runtime options.
Annotated example
A complete faz.yaml looks like this:
databases:
- name: <database> # routing key used in queries; defaults to `type`
type: postgresql # one of 14 supported connector types
host: localhost
port: 5432
database: <db-name>
username: <username>
password: <password> # env interpolation NOT yet implemented — see Secrets
ssl: false
extra: {} # connector-specific extras
- name: <other-database>
type: mongodb
host: localhost
port: 27017
database: <db-name>
permissions:
- database: <database> # baseline + per-table overrides for this DB
access: R # baseline applies to every table
tables: # optional: tighten or loosen per table
<writable-table>: RW
<audit-table>: W
- database: <other-database>
access: R # baseline only; no overrides
safety:
max_rows_per_query: 5000 # default 1000 if omitted
query_timeout_seconds: 30 # default 30 if omitted
queries_per_minute: 60 # ROADMAP — not yet enforced
auto_block_sensitive: true # ROADMAP — not yet enforcedThe three top-level keys are databases, permissions, and safety. databases is mandatory; permissions is mandatory in practice (omit it and reads default to authorised — see below); safety is optional with sensible defaults.
databases:
A list of connection configs. Each entry produces one ConnectionConfig that faz uses to open and reuse a database connection.
| Field | Type | Default | Notes |
|---|---|---|---|
name | string | the value of type | Routing key. Used in queries (<name>.<table>) and permissions. |
type | string | required | One of the 14 connector type values below. |
host | string | localhost | Hostname or IP. |
port | integer | per-connector default (table below) | Listening port. |
database | string | "" | Database / schema / index / namespace, depending on connector. |
username | string | "" | Auth user. |
password | string | "" | Auth password. Env interpolation isn't implemented yet (see Secrets). |
ssl | boolean | false | Enable TLS. Some connectors ignore this (DynamoDB). |
extra | mapping | {} | Connector-specific keys (e.g. endpoint_url for DynamoDB). |
Supported type: values and their default ports
type | Default port | Notes |
|---|---|---|
postgresql | 5432 | |
mysql | 3306 | |
oracle | 1521 | Thin mode — no Oracle Instant Client. |
mongodb | 27017 | |
dynamodb | 8000 | Local default; AWS uses SDK endpoint resolution. |
cassandra | 9042 | |
couchdb | 5984 | |
elasticsearch | 9200 | |
opensearch | 9200 | |
weaviate | 8080 | gRPC + HTTP. |
qdrant | 6333 | |
milvus | 19530 | |
pinecone | 5081 | Local container; managed cloud uses index hostname. |
neo4j | 7687 | Bolt protocol. |
Per-connector specifics — what extra is used for, what database means, which fields matter — are documented on each connector's page in Databases.
name: — when to set it
Default: the connector's type value (e.g. "postgresql").
Set name explicitly when you connect more than one database of the same type, or when you want a friendly key in your queries:
databases:
- name: <pg-primary>
type: postgresql
host: <primary-host>
# ...
- name: <pg-replica>
type: postgresql
host: <replica-host>
# ...The agent then queries <pg-primary>.<table> or <pg-replica>.<table>. Permissions reference these names too: permissions: [{ database: <pg-primary>, access: R }, ...].
Duplicate names produce a startup warning and only the last entry is used.
access_mode: — not configurable
You may have seen access_mode: read_only in older docs or tools. It's not in the YAML schema. Connectors are always opened in read-only mode internally; write access is controlled exclusively by the per-table RBAC matrix. There is no setting here that lets a connector "be" read-write at the connection layer.
permissions:
A list of permission entries. Each entry covers one database with a mandatory baseline access level and an optional tables map of overrides.
| Field | Type | Required | Notes |
|---|---|---|---|
database | string | yes | Must match a databases: entry's name. |
access | string | yes | Baseline access level: R, W, RW, RA, RWA, A. |
tables | mapping | no | Map of table_name: access_level overrides. |
permissions:
- database: <database>
access: R
tables:
<writable-table>: RW
<audit-table>: W
<ddl-table>: AThe six access codes are documented on Permission levels. The conceptual model — layered lookup, the implicit R fallback, DenyPolicy.PARTIAL for federated queries — is on Permissions.
Omitting the permissions: block does not deny all queries. Authenticated requests fall back to an implicit R for any uncovered target, which means reads succeed against any connected database. Always declare an explicit entry for every database, even if it only restates R.
none is not an access level
There are six valid values: R, W, RW, RA, RWA, A. Writing access: none will produce a parse error at startup:
permissions[0] (database=<database>) has unknown access level 'none'.
Valid: ['R', 'W', 'RW', 'RA', 'RWA', 'A']To block reads on a specific table while leaving the database otherwise readable, use W (write-only — excludes SELECT). For a complete denial, scope access at the database role level outside faz. See Blocking a table from reads.
safety:
A mapping of global safety defaults applied by the Guardrails stage. Only two keys are enforced today:
| Key | Type | Default | Notes |
|---|---|---|---|
max_rows_per_query | integer | 1000 | Injected as LIMIT (SQL/Cypher), $limit / limit (MongoDB), size (Elasticsearch). |
query_timeout_seconds | integer | 30 | Injected as maxTimeMS (MongoDB), timeout (Elasticsearch). Hint-only on SQL connectors. |
Note the gap between the runtime default (1000) and the faz init template (5000) — the template is a starting point you're expected to tune. The runtime default only kicks in when the key is absent from faz.yaml.
safety:
max_rows_per_query: 5000
query_timeout_seconds: 60Keys that appear in faz init's template but are not yet enforced at runtime:
queries_per_minute— per-instance rate limiting, on the roadmap.auto_block_sensitive,sensitive_patterns— column-level redaction overlay, on the roadmap.
You can leave these in your config — the parser preserves unknown keys for forward compatibility — but don't rely on them yet.
Reload behaviour
faz.yaml is read once at startup. Edits don't hot-reload. Restart faz serve (or restart your MCP client to respawn the stdio server) to pick up changes. Use faz policy to confirm what's currently loaded.
Where the file is found
When faz runs without an explicit config path, it looks for:
- The path in the
FAZ_CONFIGenvironment variable, if set. ./faz.yamlin the current working directory../database.yaml(legacy fallback for older Phase 0 setups).
If none of those exist, you'll see:
no faz.yaml or database.yaml in <project_root>. Run `faz init` to generate a starter faz.yaml.To run faz against a specific config file, pass FAZ_CONFIG:
FAZ_CONFIG=/etc/faz/prod.yaml faz serveFAZ_CONFIG=/etc/faz/prod.yaml uv run faz serveFAZ_CONFIG=/etc/faz/prod.yaml python -m faz serveValidation errors at startup
faz validates the file aggressively at startup so misconfigurations fail loudly, not silently. Common errors:
- Unknown connector type:
unknown connector type 'mariadb'. Valid types: ['postgresql', ...]. Fix thetype:value. - Missing required field:
missing required field 'type'. Add the field. - Invalid access code:
permissions[0] (database=<database>) has unknown access level 'none'. Use one of the six valid codes. - Duplicate connector name: warning only — the last entry wins. Add an explicit
name:to disambiguate.
See Troubleshooting › Connection failed for runtime startup failures.
Related
- Permissions — the access-control model.
- Permission levels — operation matrix per code.
- Secrets — patterns for keeping passwords out of
faz.yaml. - Runtime options — env vars and CLI flags.
- Databases overview — per-connector specifics for
host,port,extra.