> ## Documentation Index
> Fetch the complete documentation index at: https://supaschema.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Configuration

> Configuration options, defaults, environments, validators, and examples for supaschema.

`supaschema.config.json` is the project-owned place for persistent defaults. Read it as four decisions, not as a flat list of switches.

| Decision                          | Config fields                                                                                                              | Default meaning                                                                                                                                                                                                                                     |
| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Schema tree and migration context | `schemaPaths`, `migrationsDir`                                                                                             | Read every nested `.sql` file under `database/schemas`, diff toward `dir:database/schemas`, write migrations to `database/migrations`, read existing migrations as source intent, and use generated lineage there as migration-tree baseline proof. |
| Diff baseline                     | `sources.from`, `schemaPaths`                                                                                              | Diff from `"auto"` to the configured schema tree. Explicit alternate targets use `--to`.                                                                                                                                                            |
| Generated contracts               | `typesFile`, `zodFile`, `zodTypesImportPath`, `workflow.type_generation`, `workflow.zod_generation`, `workflow.type_usage` | `supaschema types` creates or refreshes TypeScript and Zod outputs, and agents use Zod validators at runtime boundaries when configured.                                                                                                            |
| Apply policy                      | `workflow.migration_sync`, `sync.targets`                                                                                  | Keep bare `sync` apply-capable by default for one target with `mode: "auto"`; remote targets also require their approval environment variable.                                                                                                      |

Use the detailed field reference when the project needs a non-default path, source, generated-output policy, validator, or apply target.

## Load order

`supaschema` looks for config in this order:

1. `--config <path>` (`.json`)
2. `supaschema.config.json` in the working directory
3. Built-in defaults

Unknown keys are rejected, so typos fail loudly.

The scaffolded config includes a `$schema` pointer to the shipped `supaschema-config.schema.json`, so editors can autocomplete and validate every key.

<Warning>
  Keep real credentials in environment variables and reference them as
  `$ENV_NAME`. Provider config files such as `supabase/config.toml`,
  `neon.toml`, Terraform, Bicep, CloudFormation, or Cloud Build files are used
  only to seed install-time defaults.
</Warning>

## Generated config

Generic PostgreSQL installs write explicit defaults so humans, agents, and editor schema validation agree on the same workflow.

Schema tree and diff target:

```json theme={null}
{
  "schemaPaths": ["database/schemas"],
  "sources": {
    "from": "auto"
  },
  "migrationsDir": "database/migrations"
}
```

`schemaPaths` is recursive. A root such as `database/schemas` can contain nested folders like `database/schemas/app/tables.sql` or `database/schemas/auth/policies/read.sql`; supaschema reads every nested `.sql` file and merges the parsed objects into one schema model. Its first entry is the only configured after-state owner. `migrationsDir` owns generated output, existing migration source intent, and generated-lineage baseline proof.

Generated contracts:

```json theme={null}
{
  "typesFile": "database.types.ts",
  "zodFile": "database.zod.ts",
  "workflow": {
    "type_generation": "create_or_refresh",
    "zod_generation": "create_or_refresh",
    "type_usage": "zod_validated"
  }
}
```

Apply policy:

```json theme={null}
{
  "workflow": {
    "migration_sync": "auto"
  },
  "sync": {
    "targets": {
      "local": { "mode": "auto", "environment": "local" },
      "remote": {
        "mode": "manual",
        "environment": "production",
        "remote": true,
        "requireApprovalEnv": "SUPASCHEMA_REMOTE_SYNC_APPROVED"
      }
    }
  }
}
```

`workflow.migration_sync: "auto"` keeps bare `supaschema sync` enabled. Target `mode` decides what is selected, but only one target may be automatic because cross-target apply is not atomic. Set a target to `"manual"` to omit it from bare sync, set `workflow.migration_sync` to `"manual"` to require `--target <name>`, or set it to `"disabled"` to block apply.

Provider detection can change the initial `schemaPaths` and `migrationsDir` values during install. Supabase installs also seed `managedSchemas` with the Supabase platform schema list and copy those names into `schemas.exclude`; generic PostgreSQL, Neon, RDS/Aurora, Cloud SQL, AlloyDB, and Azure PostgreSQL installs use `managedSchemas: []` unless you configure otherwise.

<Note>
  For the object classes, provider surfaces, and unsupported DDL boundaries that
  determine what belongs in your declarative tree, see the [support
  matrix](/docs/reference/support-matrix).
</Note>

The config schema is generated from `src/config/schema.ts` plus the shared contract in `src/config/contract.ts` into the shipped `supaschema-config.schema.json`. The installer consumes the generated `bin/config-contract.mjs` mirror from the same contract. This page is the public reference for those fields.

## Adapter

`adapter` has one current value: `auto`.

`auto` means provider-specific behavior is not selected through an adapter switch. Provider-specific setup is expressed through paths, `managedSchemas`, `transactionMode`, `excludedGrantRoles`, and explicit command flags such as `verify --ensure-environment`. Workflow consent lives in the `workflow` object.

## Workflow policy

The `workflow` object is the machine-readable contract used by agent hooks, CLI defaults, generated contract guidance, migration automation, and deploy safety gates.

| Field                       | Default                 | Allowed values                                                                                                                                                                                                                |
| --------------------------- | ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `workflow.schema_diff`      | `"on_schema_write"`     | `on_schema_write` runs `diff` from installed hooks after schema-tree SQL writes; `manual` leaves diff to a human or agent command; `disabled` prevents hook-driven diff.                                                      |
| `workflow.migration_check`  | `"after_schema_diff"`   | `after_schema_diff` runs `check` after hook-generated migrations; `required_before_complete` marks check as required before agents close schema work; `manual` skips hook-driven check.                                       |
| `workflow.migration_verify` | `"suggest_after_check"` | `suggest_after_check` tells agents to suggest `verify` after check when a database is reachable; `after_schema_diff` allows automation to verify after a generated migration; `manual` leaves verification entirely explicit. |
| `workflow.migration_sync`   | `"auto"`                | `disabled` refuses apply; `manual` leaves bare `sync` on the dry-run gate while allowing explicit `--target <name>` overrides; `auto` allows bare `sync` to use one target whose own `mode` is `"auto"`.                      |
| `workflow.type_safety`      | `"report_only"`         | `report_only` keeps type-contract diagnostics non-blocking; `deploy_blocking` fails sync before mutation on type-contract errors; `disabled` skips the type-safety gate.                                                      |
| `workflow.rls_safety`       | `"report_only"`         | `report_only` keeps RLS and least-privilege diagnostics non-blocking; `deploy_blocking` fails sync before mutation on RLS and least-privilege errors; `disabled` skips the RLS-safety gate.                                   |
| `workflow.type_generation`  | `"create_or_refresh"`   | TypeScript generated-output policy for the package workflow. `supaschema types` is the public command that refreshes `typesFile`.                                                                                             |
| `workflow.zod_generation`   | `"create_or_refresh"`   | Zod generated-output policy for the package workflow. `supaschema types` is the public command that refreshes `zodFile`.                                                                                                      |
| `workflow.type_usage`       | `"zod_validated"`       | `zod_validated` tells agents to use the generated Zod validators for runtime boundaries and derived validated types; `typescript_only` tells agents to use only the generated TypeScript shape.                               |

## Options

| Option                                | Default                                                                | Meaning                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| ------------------------------------- | ---------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `$schema`                             | scaffolded                                                             | JSON Schema pointer for editor tooling; ignored by the loader.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `adapter`                             | `"auto"`                                                               | Provider-neutral adapter sentinel. This is not a provider switch or workflow consent; see [Adapter](#adapter).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `cascade`                             | `"never"`                                                              | `CASCADE` is never emitted. This is not configurable away.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `destructiveChanges`                  | `"hint-required"`                                                      | `hint-required` blocks destructive operations until the object key is listed in `hints.destructive`; `block` always blocks; `allow` permits everything (not recommended).                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `environments`                        | `{}`                                                                   | Optional named database targets for the global `--env` flag and sync target references. `init` reuses existing database URL env names in `sync.targets` when possible, so do not create duplicate supaschema-only credentials.                                                                                                                                                                                                                                                                                                                                                                                                                |
| `excludedGrantRoles`                  | `[]`                                                                   | Grants and default privileges whose grantee or `FOR ROLE` matches are removed from extracted models (useful for platform roles such as `supabase_admin`).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `hints.allowedGrantees`               | `[]`                                                                   | Roles allowed by the free grant least-privilege rule. When non-empty, grants to other roles are reported by `scan` and `workflow.rls_safety`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `hints.requiredPolicyColumns`         | `{}`                                                                   | Table keys mapped to columns that every effective RLS policy predicate must reference, for example `{ "public.accounts": ["tenant_id"] }`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `hints.destructive`                   | `[]`                                                                   | Exact object keys (or `"*"`) approved for destructive drop/replace.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `hints.renames`                       | `[]`                                                                   | `{ "from": "<object key>", "to": "<object key>" }` pairs rendered as guarded `ALTER ... RENAME`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `idempotency`                         | `"required"`                                                           | Rendered SQL is replay-safe by construction. Not configurable away.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `lockTimeout`                         | `"5s"`                                                                 | Value for the `SET lock_timeout` migration preamble.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `workflow`                            | see [Workflow policy](#workflow-policy)                                | Hook automation, deploy safety gates, verification guidance, generated contract guidance, and apply policy.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `sync.targets.<name>`                 | `local` and `remote` targets                                           | Named sync targets. Each target sets `mode`, `runner`, and `historyTable`; it may use `databaseUrl`, use `environment`, or omit both for the runner/default URL fallback. Keep at most one target in `mode: "auto"`. Remote targets also set `requireApprovalEnv`.                                                                                                                                                                                                                                                                                                                                                                            |
| `managedSchemas`                      | `[]` for generic installs; Supabase platform set for Supabase installs | Schemas treated as externally managed. Objects inside these schemas cannot be claimed by the declarative tree unless you remove the schema from this list because the project truly owns it. Supabase installs also seed these schemas into `schemas.exclude`.                                                                                                                                                                                                                                                                                                                                                                                |
| `migrationsDir`                       | `"database/migrations"`                                                | Where zero-flag `diff` writes migrations, zero-arg `check` reads them, `verify` finds the newest pending file, planning reads existing migrations as source intent, and generated lineage proves the migration-tree baseline. Install can scaffold provider-specific folders; the canonical path table lives in [Setup](/docs/setup#path-selection). The `--migrations-dir` flag overrides per command.                                                                                                                                                                                                                                            |
| `typesFile`                           | `"database.types.ts"`                                                  | Where `supaschema types` writes generated TypeScript types.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `zodFile`                             | `"database.zod.ts"`                                                    | Where `supaschema types` writes the generated `SupaschemaZod` runtime validators (requires `zod` in the consuming project).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `zodTypesImportPath`                  | derived during joint generation                                        | Optional module specifier for the generated Zod file's type-only `Database` and `Json` import. During joint TypeScript/Zod generation, omitting it keeps the relative `.js` specifier derived from `typesFile`; Zod-only generation emits no type import unless this field is set.                                                                                                                                                                                                                                                                                                                                                            |
| `normalize`                           | `"deparse"`                                                            | Every object's SQL is rewritten into canonical form via `pgsql-deparser` (the pure-TypeScript companion of the `libpg-query` parser). Fidelity-gated per object: the canonical text is used only when it reparses to the identical location-stripped parse tree, otherwise the source text is kept with a `SUPA_NORMALIZE_*` warning. Hashes never change (identity is AST-based); rendered output is formatting-independent. Set `"off"` to keep source spelling verbatim. `check` always runs the round-trip proof and reports `SUPA_CHECK_DEPARSE_*` findings except for known third-party deparser gaps recorded in `src/sql/support.ts`. |
| `postgresVersion`                     | `"15+"`                                                                | Documentation of the supported floor; guards target PostgreSQL 15+ syntax.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `renameDetection`                     | `"hints-only"`                                                         | `hints-only` uses `hints.renames`; `off` disables rename handling entirely.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `schemaPaths`                         | `["database/schemas"]`                                                 | Paths read by `git:` sources and the default `--to dir:` target (the first entry). Install can scaffold provider-specific folders; the canonical path table lives in [Setup](/docs/setup#path-selection). Configure the final paths here. `_bootstrap` directories under schema roots are skipped as provider/bootstrap inventory.                                                                                                                                                                                                                                                                                                                 |
| `schemas.include` / `schemas.exclude` | `[]`                                                                   | Persistent schema filters applied to every extracted model (the CLI `--schema` flag composes on top).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `sources.from`                        | `"auto"`                                                               | Default before-state source for zero-source-flag `diff`, `plan`, and `verify`. For generation, `"auto"` resolves valid `git:HEAD` as a candidate source snapshot, but existing generated migrations must prove the same baseline through lineage; otherwise generation blocks with a baseline diagnostic. `empty:` is only for a first migration with no existing migration corpus. Pin `dump:`, `dir:`, `git:`, `catalog:`, or `empty:` when the project has a specific generation baseline. Use database-backed workflows for inspect, verify, selfcheck, drift, sync target safety, or catalog snapshot creation.                          |
| `statementTimeout`                    | `"60s"`                                                                | Value for the `SET statement_timeout` migration preamble.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `transactionMode`                     | `"per-migration"`                                                      | How `verify` applies the migration and how transaction hazards are graded. `per-migration` mirrors runners like `supabase db push` (one transaction per file); `per-statement` matches autocommit runners.                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `verify --ensure-roles` (CLI)         | off                                                                    | Pre-creates missing `NOLOGIN` roles referenced by grants, default privileges, and policies on the verification server. Roles are cluster-level and are never dropped.                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `validators`                          | `["internal-parser"]`                                                  | Additional external validators to run during `check` (see below).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |

## Validate and repair

Use `config validate` when an agent or CI job needs a machine-readable check of path fields, source defaults, and inline credential risks:

```bash theme={null}
supaschema config validate --json
```

If `.supaschema/install.json` records pending path confirmation, `config validate` exits with an error until `supaschema.config.json` explicitly sets `schemaPaths` and `migrationsDir`.

Use `init --dry-run --json` to inspect what install would write before changing the repository:

```bash theme={null}
supaschema init --dry-run --json
```

Use `init --repair` to rewrite `supaschema.config.json` from the canonical contract. Existing JSON values are preserved where they are valid; removed keys and unsupported values fail instead of being repaired. A normal install or `init` run leaves an existing JSON config untouched.

```bash theme={null}
supaschema init --repair
```

JavaScript config files are not loaded or converted. Move persistent settings into `supaschema.config.json`.

## Validators

`internal-parser` is always the correctness owner. Optional external validators run as subprocesses during `check` and `verify`:

* `squawk` / `squawk-cli` — runs the `squawk` binary
* `pgls` / `postgres-language-server` / `@postgres-language-server/cli` — runs `postgres-language-server check`
* `sqlfluff` — runs the external Python `sqlfluff lint --dialect postgres`

A configured validator that is not installed produces `SUPA_VALIDATOR_UNAVAILABLE` as an error: configured checks may not silently skip.

## Example

```json theme={null}
{
  "destructiveChanges": "hint-required",
  "excludedGrantRoles": [
    "supabase_admin",
    "supabase_auth_admin",
    "supabase_storage_admin",
    "dashboard_user",
    "pgbouncer",
    "authenticator"
  ],
  "hints": {
    "destructive": ["table:app.legacy_imports"],
    "renames": [{ "from": "table:app.accounts", "to": "table:app.customers" }]
  },
  "lockTimeout": "5s",
  "workflow": {
    "schema_diff": "on_schema_write",
    "migration_check": "after_schema_diff",
    "migration_verify": "suggest_after_check",
    "migration_sync": "auto",
    "type_safety": "report_only",
    "rls_safety": "report_only",
    "type_generation": "create_or_refresh",
    "zod_generation": "create_or_refresh",
    "type_usage": "zod_validated"
  },
  "sources": {
    "from": "auto"
  },
  "schemas": { "exclude": [], "include": ["app", "public"] },
  "statementTimeout": "60s",
  "transactionMode": "per-migration",
  "validators": ["internal-parser", "squawk"]
}
```
