Configuration¶
The host, database, API and bucket are always the caller's. stacs has no defaults that
point at any deployment, and reads a config only when one is named with --config.
# stacs.toml -- committed in the catalogue's own repository. Values are examples.
[catalogue]
api = "https://stac.example.org" # STAC API base URL
collection_id = "my-collection"
bucket_url = "https://my-bucket.example.org" # serves collection.json and the items
[assets]
require = "data" # every item must carry this asset key
forbid = ["legacy"] # no item may carry any of these
[transport] # only for commands that write
host = "user@stac-host.example.org"
db = "pgstac"
env_file = "/srv/stac/.env" # sourced on the host before loading
workdir = "/srv/stac" # cd here on the host
path_prepend = "/usr/local/bin"
pg_host = "localhost"
pg_port = 5432
pg_user = "pgstac"
password_env = "POSTGRES_PASSWORD" # the NAME of a variable the env_file defines
pypgstac = ["uv", "run", "pypgstac"] # the launcher on the host
[tuning] # optional
page_size = 10000 # keyset page size for full enumerations
chunk = 500 # ids per lookup when checking what was just written
fetch_workers = 20
[queryables."my:property"] # optional: item properties clients can filter on
type = "string" # a JSON Schema fragment, one table per property
title = "My property"
Flags override the catalogue and transport settings. The asset rules can be added to by a
flag but never loosened: a declared require cannot be replaced, and --forbid-asset
adds keys. Pointing at another collection id does not drop them.
Queryables are loaded for the catalogue's own collection_id and no other.
pgstac serves /collections/<id>/queryables from its own table, never from the collection
body, and its loader replaces every row of a name that the collection is served,
including a shared or global one. So each catalogue declares its own, and rows for
different collections coexist. register loads a queryable only when it is missing or
served with a different definition, after the items, and never with an index (each load
replaces the row, and with it any index set on that name by hand). Removing a
declaration leaves its row in place: nothing is deleted. Queryables are loaded last,
once the collection and items are verified and the collection is registered. A name the
collection is then served with a different definition may come from a shared or global
row, so register reads every other collection's definition of it just before the load
and again after it, whatever happened in between, and fails if one was lost or changed. The host needs pypgstac 0.9.6 or later.
No setting is a secret. Writes go over ssh to the STAC host, which runs
pypgstac load --method upsert there; the database password stays on the host and is
named (password_env), never given. Each load first asks that connection which database
it reached and refuses anything but db. The config refuses unknown keys, so a password
line is an error rather than a silently ignored secret.