Configuration¶
Configuration is split between backend environment variables and UI settings.
Configuration checklist¶
| Priority | Configure | Why |
|---|---|---|
| Required | DATABASE_URL, JWT secrets, credential encryption key, CORS_ORIGINS, frontend API routing |
The app must persist data, protect sessions and stored credentials, and accept requests only from the intended UI origin. |
| Required | INTERNAL_CRON_TOKEN when scheduler or CronJobs are enabled |
Internal automation endpoints must not be callable without the shared token. |
| Recommended | OIDC or LDAP provider settings | Enterprise identity is safer and easier to operate than local-only users. |
| Recommended | Feature flags for Manager, Portal, Browser, Ceph Admin, Storage Ops, billing, endpoint status, usage history, and quota alerts | Users should see only the surfaces that are intentionally launched. |
| Recommended | Healthcheck, billing, quota, usage-history, and notification-retention schedules | Operational data should be fresh enough to support troubleshooting and notification history should remain bounded. |
| Recommended | SMTP settings when quota alerts are enabled | Quota alerts need a deliverable notification path. |
| Optional | Branding color and login logo | Useful for tenant or lab identity, but not required for safe operation. |
Find the right configuration area¶
| You need to control... | Primary place | Also check |
|---|---|---|
| Login sessions, stored credentials, trusted origins | Backend environment and secret manager | APP_ENV, PUBLIC_ORIGIN, CORS_ORIGINS, ALLOWED_HOSTS, UI/API JWT rings, credential encryption, WebAuthn, trusted proxies, and secure cookies. |
| Which workspaces users can see | Admin app settings and feature force-locks | FEATURE_* env locks, user roles, UI groups, account links, Manager tool access. |
| Schedulers and internal automation | Runtime env, Compose scheduler, or Helm CronJobs | INTERNAL_CRON_TOKEN, healthcheckCronJob, billingCronJob, quotaMonitorCronJob, usageHistoryCronJob, notificationRetentionCronJob. |
| Health, metrics, billing, quota, and usage history freshness | App settings plus job schedules | Endpoint capability, retention env vars, latest collection logs. |
| Enterprise authentication | Admin Settings > Authentication or env-managed OIDC/LDAP providers | TLS verification, provider priority, write-only secrets, startup warnings. |
| Portal self-service behavior | Admin Portal settings | Portal account links, Storage Space defaults, access-key policy, IAM group projections. |
| Browser exposure | Browser app settings and sub-flags | Root Browser, Manager Browser, Portal Browser, Ceph Admin Browser, endpoint capability. |
| Notifications | Quota notification app settings plus runtime SMTP secret | SMTP_PASSWORD, user opt-in, global watch policy, test email action. |
Minimum day-one settings¶
Before onboarding real users, an operator should be able to name:
- where the application database lives and how it is backed up
- where the credential encryption key and scheduler token are stored
- which trusted UI origins are allowed
- which workspaces are enabled by feature flags and app settings
- which scheduler jobs or CronJobs are enabled or intentionally disabled
- which endpoint is the first production-like storage backend
- which support page users should open when reporting failures
Backend runtime settings¶
Primary source of truth: backend/app/core/config.py.
Key areas:
- Security and auth:
APP_ENV, distinctUI_JWT_KEYS/API_JWT_KEYS,CREDENTIAL_KEYS, access/session lifetimes, secure host-only cookie settings,PUBLIC_ORIGIN,ALLOWED_HOSTS,TRUSTED_PROXY_CIDRS, WebAuthn, and OIDC/LDAP environment providers. Production requires a non-emptyTRUSTED_PROXY_CIDRSlist containing the precise ingress or reverse-proxy CIDRs. Forwarded client addresses are ignored for untrusted direct peers. - Outbound targets:
USER_SUPPLIED_S3_ENDPOINT_ALLOWED_HOSTSandBUCKET_MIGRATION_WEBHOOK_ALLOWED_HOSTS. In production, an empty list blocks the corresponding user-controlled destinations. Entries match only the exact hostname; use an explicit*.example.comentry for subdomains. The wildcard does not include the apex hostname. User-supplied S3 endpoints remain HTTPS and public. Webhooks remain HTTPS by default; private HTTP webhooks require bothBUCKET_MIGRATION_WEBHOOK_ALLOW_PRIVATE_TARGETS=trueand an explicit host allowlist entry. - Database:
DATABASE_URL(SQLite defaults tobackend/app.db; relative SQLite paths are normalized againstbackend/). Multi-backend deployments require PostgreSQL. - CORS:
CORS_ORIGINS. - Feature force-locks:
FEATURE_MANAGER_ENABLED,FEATURE_PORTAL_ENABLED,FEATURE_BROWSER_ENABLED,FEATURE_CEPH_ADMIN_ENABLED,FEATURE_STORAGE_OPS_ENABLED,FEATURE_BILLING_ENABLED,FEATURE_ENDPOINT_STATUS_ENABLED. - Internal scheduler auth:
INTERNAL_CRON_TOKEN. - Billing, quota monitoring, usage history collection, and healthcheck behavior.
- Backend replica and lease coordination:
BACKEND_REPLICAS,OPERATION_LEASE_TTL_SECONDS, andBILLING_OPERATION_LEASE_TTL_SECONDS. - Shared history retention:
BILLING_DAILY_RETENTION_DAYS,QUOTA_HISTORY_HOURLY_RETENTION_DAYS,QUOTA_HISTORY_DAILY_RETENTION_DAYS. - User notification retention:
USER_NOTIFICATIONS_RETENTION_DAYS(default90;0disables purge) and the dailyNOTIFICATION_RETENTION_CRON_SCHEDULECompose job ornotificationRetentionCronJobHelm job. - Quota SMTP secret:
SMTP_PASSWORD. - Interactive storage budgets:
STORAGE_INTERACTIVE_CONNECT_TIMEOUT_SECONDS(default2),STORAGE_INTERACTIVE_READ_TIMEOUT_SECONDS(default5), andSTORAGE_INTERACTIVE_MAX_ATTEMPTS(default2). These bound UI-facing S3, IAM, SNS, and STS calls. Long-running S3 streams, bulk inventories, and file transfers keep the same connect/retry budget but useSTORAGE_LONG_RUNNING_READ_TIMEOUT_SECONDS(default60) for socket reads. - RGW Admin availability probes use
RGW_ADMIN_PROBE_TIMEOUT_SECONDS(default3) while ordinary Admin Ops and bucket-statistics calls keep their separateRGW_ADMIN_TIMEOUT_SECONDSandRGW_ADMIN_BUCKET_LIST_STATS_TIMEOUT_SECONDSbudgets.
Before enabling the production profile, inventory persisted destinations without printing URLs or credentials:
The command reports only uncovered hostnames and exits non-zero while an existing user-created S3 connection or migration webhook is outside its allowlist. Admin-registered storage endpoints are intentionally excluded.
First-administrator bootstrap¶
There are no administrator identity or password environment variables. The bootstrap is explicitly enabled only by issuing a token after migrations:
The token is 256 bits, valid for 15 minutes and single-use. Only its SHA-256
digest, issuance/expiration timestamps and consumption state are persisted. The
printed URL uses PUBLIC_ORIGIN and places the token after #, so reverse
proxies and HTTP access logs do not receive it. The browser removes the fragment
immediately and does not write it to browser storage.
POST /api/auth/bootstrap/first-admin accepts the token only in
X-BucketReef-Bootstrap-Token, requires the exact trusted Origin, applies the
authentication rate limit by client IP and returns a generic unavailable error
for absent, expired, invalid or consumed tokens. Issuing another token revokes
the previous one while the database has no users.
Use python -m app.scripts.create_first_admin when a direct console workflow is
required. Use reset_last_superadmin_mfa only to recover the sole existing
super-administrator. Recovery never reactivates initial bootstrap.
OIDC providers can be configured either from Admin Settings > Authentication or with nested environment variables:
- UI-managed OIDC providers are persisted in the
oidc_providersdatabase table. Theirclient_secretvalue is encrypted with the credential key and is write-only: read APIs return onlyhas_client_secret. - Environment-managed providers use
OIDC_PROVIDERS__<key>__...variables. They take priority over any UI provider with the sameprovider_idand appear locked/read-only in Admin Settings > Authentication. OIDC_STATE_TTL_SECONDSremains a backend runtime setting and is not editable from the UI.
Common environment fields:
OIDC_PROVIDERS__<key>__DISPLAY_NAMEOIDC_PROVIDERS__<key>__DISCOVERY_URLOIDC_PROVIDERS__<key>__CLIENT_IDOIDC_PROVIDERS__<key>__CLIENT_SECRETOIDC_PROVIDERS__<key>__REDIRECT_URIOIDC_PROVIDERS__<key>__SCOPES- optional behavior fields:
PROMPT,ENABLED,ICON_URL,USE_PKCE,USE_NONCE,ALLOWED_ALGORITHMS,ALLOWED_HOSTS,LINKING_POLICY, andTRUSTED_EMAIL_DOMAINS.trusted_emailis OIDC-only and requires exact, normalized domains plus the verified-email eligibility rules.
LDAP providers can be configured either from Admin Settings > Authentication or with nested environment variables:
- UI-managed LDAP providers are persisted in the
ldap_providersdatabase table. Theirbind_passwordvalue is encrypted with the credential key and is write-only: read APIs return onlyhas_bind_password. - Environment-managed providers use
LDAP_PROVIDERS__<key>__...variables. They take priority over any UI provider with the sameprovider_idand appear locked/read-only in Admin Settings > Authentication.
Common environment fields:
LDAP_PROVIDERS__<key>__DISPLAY_NAMELDAP_PROVIDERS__<key>__URL(ldaps://...orldap://...withSTART_TLS=true)- optional service credentials:
LDAP_PROVIDERS__<key>__BIND_DN/LDAP_PROVIDERS__<key>__BIND_PASSWORD; configure both together or omit both to search anonymously when directory ACLs permit it LDAP_PROVIDERS__<key>__USER_BASE_DNLDAP_PROVIDERS__<key>__USER_FILTERcontaining{username}- optional attributes:
EMAIL_ATTRIBUTE,NAME_ATTRIBUTE,SUBJECT_ATTRIBUTE - TLS and safety knobs:
START_TLS,TLS_VERIFY,TLS_CA_FILE,ALLOW_LEGACY_TLS,ALLOW_INSECURE.ALLOW_LEGACY_TLS=trueenables the OpenSSLDEFAULTcipher set for a provider that cannot negotiate the modern client defaults; prefer enabling ECDHE cipher suites on the LDAP server.
Provider keys must match [a-z0-9_-]+. ALLOW_INSECURE=true,
TLS_VERIFY=false, and ALLOW_LEGACY_TLS=true are rejected when
APP_ENV=production. LDAP email collisions are never linked automatically.
LDAP only authenticates the UI identity. First LDAP login creates a user with
ui_none; admins still grant roles and storage access in BucketReef.
App settings (persisted)¶
Primary model: backend/app/models/app_settings.py.
Persistence source: the app_settings database table.
APP_SETTINGS_PATH is an optional bootstrap import path. On startup or first
settings read, a deployment with an empty app_settings table imports the JSON
file once, then live reads and writes go through the database. Runtime database
errors are not hidden by a file fallback. Environment force-locks such as
FEATURE_PORTAL_ENABLED still override the effective value without changing the
persisted setting.
Managed from Admin UI:
- General feature toggles (
manager_enabled,portal_enabled,browser_enabled,ceph_admin_enabled,storage_ops_enabled,billing_enabled,endpoint_status_enabled). - Authentication settings (
allow_login_access_keys, endpoint selection for access-key login, custom login endpoints,require_passkey_for_admins,require_passkey_for_users,allow_user_profile_name_edit, andallow_user_external_identity_unlink). The defaults require passkeys only for Admins and keep both self-service permissions disabled. - Quota supervision toggles (
quota_alerts_enabled,usage_history_enabled). - Browser sub-flags (
browser_root_enabled,browser_manager_enabled,browser_portal_enabled,browser_ceph_admin_enabled). - Portal settings (
portal): standalone Browser access (browser_access_enabled, disabled by default), IAM key availability, private Storage Space creation, portal user access-key creation, server access log retention for newly created technical log buckets, max portal user keys, and bucket defaults. Portal settings can be overridden per account by a super-admin. The per-accountportal_settings_delegatedflag is disabled by default; when enabled, project Portal Managers can edit the same shared override from/portal/settings. Disabling delegation keeps the stored override effective but read-only in Portal.bucket_defaults.noncurrent_version_expiration_daysis the internal key for Version history retention; it is a positive integer (90 by default) and applies only when provisioning a new Storage Space with the default lifecycle enabled. Existing buckets are not reconciled automatically. - Manager tool flags and behavior: bucket migration, compare, integrity check, purge, usage stats, Ceph S3 User key management, and migration parallelism.
- Quota notification policy (
quota_notifications: threshold, SMTP non-secret fields, contact-email option).
On a fresh deployment with no persisted app settings, Endpoint Status and
Usage history are enabled by default. Quota alerts remains disabled until
explicitly enabled and configured.
The Browser surface is enabled on root /browser and inside Portal storage
spaces (/portal/storage-spaces/:spaceId) by default. Portal projects do not
appear in the root Browser until portal.browser_access_enabled is enabled
globally or by account override. Manager and Ceph Admin Browser integrations
remain disabled until explicitly enabled.
The Settings tab of an existing Storage Space is separate from project
defaults. Owners and Portal Managers can read the bucket's Versioning,
Lifecycle, and version history retention values. Only a project Portal Manager
can update an active space. These calls use the manager's personal IAM identity
and manage only the Portal lifecycle rules ExpireDeleteMarkers and
ExpireOldVersions; unrelated lifecycle rules are preserved.
Superadmins manage login behavior and UI-managed OIDC/LDAP providers from Admin
Settings > Authentication. The four access-key login options remain in
AppSettings.general and are persisted in the database; UI-managed OIDC and
LDAP providers are persisted separately in their own database tables.
FEATURE_PORTAL_ENABLED can force the Portal surface on or off. Account access
uses two independent axes: manager_role is account_administrator or null,
and portal_role is portal_user, portal_manager, or null. At least one
axis is required. Disabling Portal prevents new Portal selections but does not
rewrite or remove existing Portal roles; new links default to Manager
administrator while the feature is off and to Portal user while it is on.
The code-owned portal-user IAM group policy grants only
s3:ListAllMyBuckets and sts:GetSessionToken. The code-owned
portal-manager group adds the explicit Storage Space data-plane actions on
all buckets in the single RGW Account backing the project. Technical Portal
buckets add an explicit resource-policy denial for manager IAM principals.
Storage Space creation and bucket defaults remain backend workflows. Private
Owner and team Viewer/Editor projections are generated from database state;
Portal IAM policies are not editable settings.
Frontend runtime settings¶
VITE_API_URLfor API base URL in frontend build/runtime.- In container deployments, route
/apito backend via reverse proxy/ingress. - Browser identity always comes from
/api/auth/session; UI tokens must never be added toVITE_*values or browser storage.
From user error to configuration area¶
| User-facing symptom | Check here first |
|---|---|
| Login fails for LDAP/OIDC users | Auth provider variables, TLS settings, and startup warnings. |
| Menu or workspace is missing | App settings feature flags, user role, account links, and entitlements. |
| Browser or Portal files do not open | Browser sub-flags, selected context access, and endpoint capability. |
AccessDenied during an S3 action |
IAM/S3 policy and selected execution identity before changing UI flags. |
| Metrics, billing, quota, or history are stale | Scheduler/CronJob settings, INTERNAL_CRON_TOKEN, retention, and endpoint capabilities. |
| Quota emails do not arrive | Quota notification policy, SMTP non-secret fields, SMTP_PASSWORD, and user opt-in. |
Branding¶
Admin can set:
- primary accent color (
#RRGGBB) - optional login logo URL