Skip to content

Configuration

qnop is configured in two places, and knowing which is which saves a lot of time:

  • Environment variables — infrastructure. Where the database is, where the bucket is, which secrets to use. Changing them needs a restart.
  • Administration → Settings — everything an operator tunes while the system runs: SMTP, upload limits, self-registration, retention. These are not environment variables.

Every environment variable is prefixed QNOP_.

These have no usable default. Each ships as CHANGE_ME, which is rejected at startup — the server refuses to boot rather than run insecurely.

VariablePurposeRequirement
QNOP_AUTH_JWT_SECRETsigns access tokens≥ 32 characters
QNOP_AUTH_ENCRYPTION_KEYencrypts secrets held at rest (e.g. OIDC client secrets)≥ 32 characters
QNOP_AUTH_ENCRYPTION_SALTkey-derivation salthex-encoded, ≥ 16 characters
Terminal window
QNOP_AUTH_JWT_SECRET="$(openssl rand -base64 48)"
QNOP_AUTH_ENCRYPTION_KEY="$(openssl rand -base64 48)"
QNOP_AUTH_ENCRYPTION_SALT="$(openssl rand -hex 32)"

Note the salt uses -hex, not -base64.

VariableDefaultPurpose
QNOP_DB_HOSTlocalhostPostgres host
QNOP_DB_PORT5432Postgres port
QNOP_DB_NAMEqnopdatabase name
QNOP_DB_USERNAMEqnopuser
QNOP_DB_PASSWORDqnoppassword

The defaults are development values — set all of them in production. The standard SPRING_DATASOURCE_* variables override the URL assembled from these if you need full control.

VariableDefaultPurpose
QNOP_S3_ENDPOINT(empty)endpoint URL — leave empty for real AWS S3
QNOP_S3_BUCKETqnop-documentsbucket name
QNOP_S3_ACCESS_KEYqnopaccess key
QNOP_S3_SECRET_KEYqnop_secretsecret key
QNOP_S3_REGIONus-east-1region, or the placeholder your vendor requires
QNOP_S3_PATH_STYLE_ACCESStruetrue for MinIO; set false for AWS S3
QNOP_S3_AUTO_CREATE_BUCKETfalsecreate the bucket on first start
QNOP_S3_REAPER_GRACE_PERIODPT1Hgrace before a staged, unreferenced object is swept
QNOP_S3_REAPER_CRON0 30 3 * * *when that sweep runs

The defaults are tuned for the bundled MinIO. Pointing at AWS S3 means clearing the endpoint and flipping QNOP_S3_PATH_STYLE_ACCESS to false.

VariableDefaultPurpose
QNOP_HTTP_FORWARD_HEADERS_STRATEGYnoneset framework behind a trusted reverse proxy
QNOP_CORS_ALLOWED_ORIGINShttp://localhost:5173comma-separated exact origins; not needed for the embedded UI
QNOP_HTTP_SHUTDOWN_GRACE30sgraceful-shutdown drain
QNOP_HTTP_CONNECTION_TIMEOUT20sconnection timeout
QNOP_HTTP_KEEP_ALIVE_TIMEOUT20skeep-alive reap
QNOP_HTTP_REQUEST_TIMEOUT30sasync dispatch cap

Outbound timeouts — used for OIDC discovery, JWKS fetches and SMTP — are QNOP_HTTP_CLIENT_OUTBOUND_CONNECT_TIMEOUT (5s), QNOP_HTTP_CLIENT_OUTBOUND_READ_TIMEOUT (15s), and the QNOP_HTTP_CLIENT_SMTP_* trio (10s connect, 30s read, 30s write).

VariableDefaultPurpose
QNOP_UPLOAD_MULTIPART_LIMIT_MB55servlet-level multipart ceiling
VariableDefaultPurpose
QNOP_AUTH_OIDC_FRONTEND_BASE_URL(empty)where to return after OIDC login; empty = same origin
QNOP_AUTH_OIDC_ALLOW_PRIVATE_DISCOVERY_URISfalseSSRF guard — see below
QNOP_AUTH_RATE_LIMIT_TRUSTED_PROXY_CIDRS(empty)which hops may set the client IP

OIDC providers themselves are not configured by environment variable — they are managed at runtime under Administration → OIDC providers. See Authentication.

VariableDefaultPurpose
QNOP_ADMIN_PASSWORD(unset)fixed initial admin password

Unset, qnop generates a one-time password on first start and forces a change at first login. Set, it uses yours and skips the forced change.

These live in Administration → Settings and change without a restart. The list matters because operators regularly go looking for them in the environment:

  • General — application name, base URL, default language and timezone.
  • Uploadsdocument_max_file_size_mb (default 25), attachment_max_file_size_mb (default 10).
  • SMTP — enabled, host, port, credentials, encryption, from-address and from-name. Mail is configured here, not in the environment.
  • Authentication — self-registration and its default role, password reset and its token lifetime.
  • Notifications — whether review e-mails are sent.
  • Review — free reattach, finalize-with-open-annotations, and the archive and purge retention windows.

A number of further variables exist and bind by naming convention, but are not part of the documented contract and can change without notice: token lifetimes (QNOP_AUTH_ACCESS_TOKEN_TTL, QNOP_AUTH_REFRESH_TOKEN_TTL), the re-anchoring similarity thresholds (QNOP_REANCHORING_*), the per-endpoint rate-limit budgets (QNOP_AUTH_RATE_LIMIT_*), and the maintenance cron expressions (QNOP_S3_ORPHAN_REAPER_CRON, QNOP_REVIEW_ARCHIVE_CRON, QNOP_REVIEW_PURGE_CRON). Reach for them only with a specific reason.