Gateway application manifest (v1)
This document defines substratum-gateway.json, an optional JSON file for operational gateway settings (database URL, HTTP bind, CORS, blockstore, logging). It complements substratum-triangle-v1 (mesh/triangle slice only).
When it is used
- Release gateway binaries: if
SUBSTRATUM_GATEWAY_CONFIGpoints to a file, or./substratum-gateway.jsonexists in the process working directory, the file is read and merged with the process environment. - Debug (
cargo run): the gateway JSON file is ignored for operational settings — use.env+ env vars. An optional cwd.envis loaded viabootstrap_dotenvat the start ofload_operational_from_env_only/load_operational_mergedwhen present (non-fatal if missing). - Precedence: for every field, a non-empty environment variable always wins over the file. Docker, Kubernetes, and Compose therefore keep injecting secrets and overrides as today.
File locations
| Mechanism | Path |
|---|---|
| Explicit path | SUBSTRATUM_GATEWAY_CONFIG=/path/to/substratum-gateway.json |
| Default (cwd) | ./substratum-gateway.json |
JSON shape (schema_version 1)
| Field | Type | Required in file | Description |
|---|---|---|---|
schema_version | integer | yes | Must be 1. |
kind | string | yes | Must be substratum.gateway.application_v1. |
database_url | string | no* | Postgres URL for the app pool. |
database_admin_url | string | no | Bootstrap URL for SeaORM migrations (bootstrap_database). |
postgres_password | string | no | Same semantics as env POSTGRES_PASSWORD. |
public_base_url | string | no* | Public base URL (no trailing slash). |
host | string | no* | Bind IP, e.g. 0.0.0.0. |
port | integer | no* | Bind port. |
cors_allowed_origins | string[] | no* | Allowed browser origins (env uses comma-separated string). |
rust_log | string | no | tracing filter; default info if unset everywhere. |
log_json | bool | no | JSON logs when true (only if env SUBSTRATUM_LOG_JSON is unset). |
s3_access_key | string | no | Enables S3 blockstore when set (with secret). |
s3_secret_key | string | no | S3 secret (env S3_SECRET_KEY overrides). |
s3_region | string | no | Default us-east-1. |
s3_bucket | string | no | Default substratum-blocks. |
s3_endpoint | string | no | Custom S3-compatible endpoint. |
flat_fs_blocks_path | string | no | FlatFS block path when S3 is not used; default ./data/blocks. |
atproto_appview_url | string | no | AppView for public handle resolution; default Bluesky public AppView. |
pds_url | string | no | Internal gateway → PDS base URL; default http://127.0.0.1:3000. |
pds_public_url | string | no | Browser-reachable PDS URL for OAuth; default http://localhost:3000. |
pds_handle_domain | string | no | Account handle TLD (e.g. test → alice.test); not the PDS OAuth issuer host. |
pds_oauth_issuer_origin | string | no | OAuth issuer origin; when unset, derived from pds_public_url. Set to none to disable URL rewriting. |
pds_admin_password | string | no | PDS admin password for proxied signup invite codes. |
pds_signup_enabled | bool | no | Enable POST /api/v1/pds/signup; when unset, enabled if pds_admin_password is set. |
*After merge with env, each required operational value must be satisfied by env or file (see gateway process_env). Env keys use SCREAMING_SNAKE_CASE (e.g. PDS_HANDLE_DOMAIN overrides pds_handle_domain in the file).
Example (illustrative)
json
{
"schema_version": 1,
"kind": "substratum.gateway.application_v1",
"database_url": "postgres://substratum_gateway:secret@127.0.0.1:5432/substratum",
"public_base_url": "https://gateway.example",
"host": "0.0.0.0",
"port": 8080,
"cors_allowed_origins": ["https://app.example"],
"rust_log": "info",
"flat_fs_blocks_path": "/var/lib/substratum/blocks",
"pds_url": "http://127.0.0.1:3000",
"pds_public_url": "http://localhost:3000",
"pds_handle_domain": "test",
"pds_oauth_issuer_origin": "http://localhost:3000"
}Related
substratum-triangle-v1.md— triangle / mesh manifest.apps/gateway/AGENTS.md— env table and loading rules.