Moderation and instance settings
Moderation
| Tool | What it does |
|---|---|
| Reports | Viewers report content; staff are actually notified, rather than the report landing in a table nobody opens. |
| Sensitive content | A per-user policy for how sensitive content is handled, plus creator-applied content warnings. |
| Registration approval | REGISTRATION_REQUIRE_APPROVAL=true files signups into an admin approval queue instead of creating accounts. |
| Quarantine | New uploads can be held until reviewed rather than published on transcode completion. |
| Blocks | Account-level and instance-level blocks. These are yours — they are not synchronised with federated peers. |
| Audit envelope | Job and admin actions carry an audited envelope with an allow-list of fields and a sensitiveKeys denylist, guarded by a static test. |
Registration policy is a policy, not a security control
REGISTRATION_ENABLED=false is still the right default for a private launch,
but it is no longer the thing standing between a bot and your admin account.
The first admin is claimed, not registered: while the instance has an empty
users table and an unredeemed token, every signup path answers
403 owner_claim_required, and the only way in is the one-time token the api
mints at boot. See Quickstart, step 3.
Two consequences worth knowing:
- An instance that already has users and no outstanding token is implicitly claimed and never mints one — upgrading an existing install does not suddenly print a bootstrap credential.
- If users exist but the owner was never claimed, the api re-mints on every boot, so an unclaimed token sitting in an old log can never stay a live admin credential.
OWNER_CLAIM_TOKEN pins the mint to a fixed value for test harnesses.
config.validate() refuses it in production; it is not an operator knob.
Open the doors when you are ready:
REGISTRATION_ENABLED=true
REGISTRATION_REQUIRE_APPROVAL=true # optional: queue signups for review
then up -d again.
The instance settings registry
The admin console's configuration UI is not hand-written. It is rendered from a
registry: internal/instancesettings holds a typed, validated,
runtime-mutable set of settings, each carrying page and section metadata, and the
UI is generated from that metadata. Over a hundred settings are registered
today; the registry itself is the authoritative list.
Changing one takes effect without a restart. Runtime knobs reach workers through provider-func closures, read at request or job time rather than baked in at boot, and the server reloads its settings overlay when a value is written.
The env-versus-database doctrine
| Lives in | What |
|---|---|
| Environment only | Secrets, and anything that is unsafe to change while the process is running — database and Redis DSNs, key-encryption keys, PUBLIC_BASE_URL, TRANSCODING_PACKAGER, the master federation switches |
| The settings registry | Anything an operator should be able to change from the admin console — instance identity, signup policy, upload policy, transcoding threads and concurrency, moderation defaults |
The rule is worth stating plainly, because it explains why a setting you want is sometimes not in the UI: effective capability is the setting AND the boot configuration. Turning a feature on in the admin console cannot conjure a service that the compose profiles did not start.
Two runtime levers matter for anyone running near the hardware floor:
transcoding_threads— set to vCPU − 1.transcoding_concurrency— leave at 1. Raising it multiplies both CPU and scratch disk, at roughly 4 ×UPLOAD_MAX_SIZEper concurrent job.
See Configuration for how to read the current registry, and Requirements and sizing for the numbers behind those two.