Skip to content

Environment Variables

All Sairo configuration is done through environment variables. This page lists every supported variable grouped by category.

VariableDefaultDescription
S3_ENDPOINT(required)S3-compatible endpoint URL
S3_ACCESS_KEY(required)S3 access key ID
S3_SECRET_KEY(required)S3 secret access key
S3_REGION(empty)S3 region
S3_MAX_POOL_CONNECTIONS32Max pooled connections per S3 client, so parallel crawl/delta list calls don’t serialize on a small pool
VariableDefaultDescription
UPLOAD_PROXY_CONCURRENCY3Files streamed in parallel through the proxy-upload fallback. Bounds peak server memory (~100 MB per in-flight file × this value). The default direct browser→S3 path uses no server memory.
MULTIPART_URL_EXPIRY3600Lifetime (seconds) of each presigned multipart part URL. Parts are signed just-in-time, so this only needs to cover a single part’s upload.
MAX_UPLOAD_SIZE5368709120 (5 GB)Maximum total size for a proxy upload request. Does not apply to direct browser→S3 uploads.
VariableDefaultDescription
AUTH_MODElocalAuthentication mode: local (username/password) or s3 (log in with S3 access key + secret; access is scoped to each user’s own keys via the provider’s IAM)
ADMIN_USERadminUsername for the default admin account
ADMIN_PASS(auto-generated)Password for the default admin account. If not set, a random password is printed to logs on first startup.
JWT_SECRET(auto-generated)Secret key for signing JWT tokens. Set explicitly for multi-instance deployments.
SESSION_HOURS24Session duration in hours
SECURE_COOKIEtrueSet to false for HTTP (non-HTTPS) deployments or cookies will silently fail
VariableDefaultDescription
RECRAWL_INTERVAL120Seconds between automatic reindex cycles for each bucket
DB_DIR/dataDirectory where SQLite index databases are stored
FULL_CRAWL_INTERVAL3600Seconds between full reconcile crawls for large buckets (delta crawls run on RECRAWL_INTERVAL in between)
LARGE_BUCKET_SECONDS60A bucket whose full crawl takes longer than this is treated as “large” and kept fresh with delta crawls + periodic full reconcile, instead of full re-crawls every interval

These bound how the incremental delta crawler discovers new data on large buckets. The defaults suit time-partitioned layouts (e.g. year=/month=/day=/hour=); they rarely need changing.

VariableDefaultDescription
DELTA_SAMPLE3000How many of the most recently-indexed objects to sample to locate the “hot” prefixes a delta crawl should re-list
DELTA_MAX_TARGETS40Cap on the number of hot prefixes re-listed per delta crawl
DELTA_BRANCH_FANOUT8Levels with more children than this are treated as time partitions (follow only the newest few); fewer means a descriptive branch (follow all)
DELTA_NEWEST_K2How many of the newest partitions to re-list at a partition level (current + just-rolled)
DELTA_MAX_DEPTH12Safety cap on prefix-walk depth
DELTA_LIST_CONCURRENCY16Parallel S3 list calls per level during delta discovery
DELTA_MAX_NODES2000Safety cap on folders visited per delta crawl
VariableDefaultDescription
LDAP_ENABLEDfalseEnable LDAP authentication
LDAP_SERVER(none)LDAP server URI (e.g., ldap://ldap.example.com:389 or ldaps://ldap.example.com:636)
LDAP_BASE_DN(none)Base DN for user searches (e.g., ou=people,dc=example,dc=com)
LDAP_USER_FILTER(sAMAccountName={username})LDAP search filter. {username} is replaced with the login username.
LDAP_BIND_DN(none)DN of the service account used to search for users
LDAP_BIND_PASSWORD(none)Password for the bind DN
LDAP_ADMIN_GROUP(none)LDAP group DN whose members are assigned the admin role
LDAP_DEFAULT_ROLEviewerDefault role for LDAP-provisioned users
VariableDefaultDescription
OAUTH_GOOGLE_CLIENT_ID(none)Google OAuth 2.0 Client ID
OAUTH_GOOGLE_CLIENT_SECRET(none)Google OAuth 2.0 Client Secret
OAUTH_GITHUB_CLIENT_ID(none)GitHub OAuth App Client ID
OAUTH_GITHUB_CLIENT_SECRET(none)GitHub OAuth App Client Secret
OAUTH_DEFAULT_ROLEviewerDefault role for OAuth-provisioned users
OAUTH_ALLOWED_DOMAINS(none)Comma-separated list of allowed email domains for Google OAuth

Generic OIDC SSO for any compliant provider. Enabled when OIDC_ISSUER and OIDC_CLIENT_ID are both set. See OAuth, OIDC & LDAP for per-provider setup.

VariableDefaultDescription
OIDC_ISSUER(none)Issuer URL, e.g. https://login.example.com/realms/main. Endpoints are auto-discovered from <issuer>/.well-known/openid-configuration
OIDC_CLIENT_ID(none)Client/application ID from your provider
OIDC_CLIENT_SECRET(none)Client secret. Omit for a public client (PKCE is always used)
OIDC_PROVIDER_NAMESSOLabel on the login button
OIDC_USERNAME_CLAIMpreferred_usernameClaim used as the local username (e.g. email for Google)
OIDC_SCOPESopenid profile emailRequested scopes
OIDC_DEFAULT_ROLEviewerRole for new users (they get no bucket access until an admin grants it)
OIDC_ALLOWED_DOMAINS(none)Comma-separated email-domain allowlist
OIDC_ADMIN_GROUP(none)If set, members of this group become admins (enables group→role mapping)
OIDC_GROUPS_CLAIMgroupsClaim that carries the user’s groups
OIDC_REQUIRE_VERIFIED_EMAILfalseReject logins whose email isn’t verified
OIDC_RP_LOGOUTfalseAlso end the IdP session on logout (single logout)
VariableDefaultDescription
APP_NAMESairoApplication name displayed in the UI and browser tab
PRIMARY_COLOR#3b82f6Primary theme color (hex code, e.g., #2563eb)
APP_LOGO(none)URL to a custom logo image displayed on the login page and sidebar
LOGIN_MESSAGE(none)Custom message displayed on the login page (supports plain text)
VariableDefaultDescription
RATE_LIMIT120/minuteGeneral API rate limit per IP
UPLOAD_RATE_LIMIT30/minuteRate limit for upload requests per IP

Login attempts are rate-limited with two layers: 10 per minute via slowapi and 10 per 5 minutes per IP via a hardcoded window. Neither is independently configurable.

VariableDefaultDescription
TELEMETRYtrueSend an anonymous usage heartbeat (schema v2: aggregate counts, instance health, and activation timestamps only — never names, keys, paths, or content). Set to false to disable entirely. See Telemetry.
TELEMETRY_INTERVAL3600Seconds between heartbeats.
TELEMETRY_URLhttps://dashboard.sairo.dev/api/v1/pingEndpoint the heartbeat is POSTed to. Override to point at your own collector (or leave unset to disable by setting TELEMETRY=false).
SAIRO_STORAGE_EPHEMERAL(auto)Optional hint for the telemetry id_persistence field: true if DB_DIR is ephemeral (e.g. emptyDir), false if durable. The Helm chart sets it from persistence.enabled; otherwise Sairo infers it from the mount table.
services:
sairo:
image: stephenjr002/sairo:latest
ports:
- "8000:8000"
environment:
# S3
S3_ENDPOINT: "https://s3.us-east-1.amazonaws.com"
S3_ACCESS_KEY: "AKIAIOSFODNN7EXAMPLE"
S3_SECRET_KEY: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
S3_REGION: "us-east-1"
# S3_PATH_STYLE is configured per-endpoint via the UI, not globally
# Auth
ADMIN_USER: "admin"
ADMIN_PASS: "super-secret-password"
JWT_SECRET: "a-long-random-string-for-signing"
SESSION_HOURS: "24"
SECURE_COOKIE: "true"
# Crawler
RECRAWL_INTERVAL: "120"
# Branding
APP_NAME: "My Storage"
PRIMARY_COLOR: "#2563eb"
LOGIN_MESSAGE: "Welcome to the storage portal"
# Rate Limiting
RATE_LIMIT: "120/minute"
UPLOAD_RATE_LIMIT: "30/minute"
volumes:
- sairo-data:/data
volumes:
sairo-data: