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

# Secure QM setup

> Choose snapshot, strict-direct, or Fly-contained QM collection without sending infrastructure credentials to Xerg Cloud.

Xerg's QM adapter is platform-independent. It consumes a sanitized `qm-snapshot/v1`; database access belongs to an operator-controlled collector. Choose the narrowest collection mode your PostgreSQL environment supports.

## Snapshot mode

Snapshot mode needs no database connection. Receive an authorized owner-only artifact and audit it directly:

```bash theme={null}
xerg doctor --runtime qm --qm-snapshot ./qm-snapshot.jsonl
xerg audit --runtime qm --qm-snapshot ./qm-snapshot.jsonl
```

The artifact identifies its collection mode and trust boundary. Auditing a snapshot never requires the source deployment's identity key.

## Strict direct mode

Use strict direct mode for local, Docker, AWS, external PostgreSQL, or any Fly-backed PostgreSQL where an administrator can create a genuinely isolated role.

```bash theme={null}
xerg connect qm --print-sql > xerg-qm-export-v1.sql
```

The reviewed script creates portable `xerg_export/v1` security-barrier views, bounded-query indexes, and `xerg_reader`. Set the reader password separately through the database secret manager. The role is `NOSUPERUSER NOCREATEDB NOCREATEROLE NOINHERIT NOREPLICATION NOBYPASSRLS`, owns no database or schema, belongs to no other role, cannot read or write QM base tables, and can select only the export views.

Provision one reader URL and one 32-byte identity key per deployment:

```text theme={null}
XERG_QM_DATABASE_URL
XERG_QM_IDENTITY_KEY
```

`XERG_QM_DATABASE_URL_<NAME>` is also accepted. Public endpoints require TLS. Public commands reject general `DATABASE_URL`, owner credentials, unsafe privileges, and DSN arguments.

```bash theme={null}
xerg connect qm --database-url-env XERG_QM_DATABASE_URL
xerg doctor --runtime qm
```

Doctor fails closed on excess privilege, missing indexes, changed columns, or a contract fingerprint mismatch. Collection never falls back to base tables.

## Fly-contained mode

Fly Managed Postgres's managed reader inherits `pg_read_all_data`, so Xerg does not present it as a restricted reader. Use the separate [Fly-contained workflow](/docs/qm-fly), which installs views and indexes only:

```bash theme={null}
xerg connect qm --print-views-sql > xerg-qm-views-v1.sql
```

The one-shot exporter runs inside QM core, uses QM's existing `DATABASE_URL` only in that process, and discloses `privilegeBoundary: process` plus `databaseLeastPrivilege: false`. No database URL or Fly token is sent to Xerg Cloud or a QM sandbox.

For offline snapshot audit from QM Slack, current Fly Sprites require a separate, explicitly approved CLI bootstrap inside the administrator's private persistent Sprite; the configured sandbox OCI image is not applied to that Sprite. See [QM on Fly.io](/docs/qm-fly). The Sprite receives neither the database/Fly authority used by the core exporter nor the deployment identity key.

## Identity key lifecycle

The identity key may be 64 hex characters, a 32-byte base64 value, or exactly 32 UTF-8 bytes. Generate it once, keep it in the source/operator secret manager, and back it up through your existing recovery procedure. Xerg stores only a non-secret fingerprint.

Restoring the same key preserves pseudonymous identity and comparison continuity. Losing or rotating it starts a new boundary. Rotation is never automatic; confirm it explicitly with `xerg connect qm --rotate-identity` only when you accept that boundary or suspect compromise.

The saved `~/.xerg/qm.json` profile contains only `direct-reader` plus an environment-variable name, or `contained-operator` plus a Fly app name, and the key fingerprint. It never contains credentials.
