Skip to main content

Configuration

Odudu is configured by environment variables, read once when the server or a command starts. A value that does not fit its type or bounds stops it from starting, and the message names the variable. A variable marked secret holds a credential: keep it out of images, logs and source control.

What you must set​

The server does not start without ODUDU_DATABASE_URL and ODUDU_KEK. The console is on by default, so by default it also needs the variables below; set ODUDU_CONSOLE=false to run without it.

  • ODUDU_APP_DATABASE_URL, when NODE_ENV is production.
  • ODUDU_TLS, when NODE_ENV is production, where it must be true.
  • ODUDU_SMTP_FROM, when ODUDU_SMTP_HOST is set.
  • ODUDU_PUBLIC_BASE_URL, when the console is on (ODUDU_CONSOLE, which defaults to true) or NODE_ENV is production.
  • ODUDU_CONSOLE_CLIENT_KEY, when the console is on (ODUDU_CONSOLE, which defaults to true).

Server​

VariableTypeDefaultDescription
NODE_ENVone of development, test, productiondevelopmentThe environment the server runs in. production makes the server refuse to boot unless it has ODUDU_APP_DATABASE_URL, ODUDU_TLS=true, ODUDU_PUBLIC_BASE_URL and a ODUDU_KEK that is not the published example, and with ODUDU_ALLOW_PRIVATE_CLIENT_URLS off.
ODUDU_HTTP_HOSTstring0.0.0.0The address the HTTP server listens on.
ODUDU_HTTP_PORTinteger, 1 to 65,5353000The port the HTTP server listens on.
ODUDU_TRUST_PROXYtrue or falsefalseWhether to trust what a reverse proxy in front of the server reports about the client: its address, which is recorded in audit events and keys the rate limits. It does not decide the issuer or any cookie. Turn it on only behind a proxy that overwrites X-Forwarded-*.
ODUDU_TLS_CLIENT_CERT_HEADERstringx-ssl-client-s-dnThe header a proxy puts the subject of a client certificate in, read for tls_client_auth at the token endpoint and only while ODUDU_TRUST_PROXY is on. Compared in lower case.
ODUDU_TLStrue or falsenone; required when NODE_ENV is production, where it must be trueStates that the connection to the user is HTTPS, terminated here or by a proxy in front of the server. It gives every cookie Secure and a __Host- or __Secure- name, and NODE_ENV=production refuses to boot while it is off.
ODUDU_LOG_LEVELone of fatal, error, warn, info, debug, trace, silentinfoThe lowest severity the server logs. silent logs nothing.
ODUDU_PUBLIC_BASE_URLstringnone; required when the console is on (ODUDU_CONSOLE, which defaults to true) or NODE_ENV is productionThe origin the server is reached at, with no path: the issuer of every tenant, the base every mailed link and the console’s redirect URI are built from, and the source of the passkey relying party id. Never taken from a request header. Required when NODE_ENV=production. Without it (local development) the issuer is read from the request.
ODUDU_INSTRUMENT_DIRstring/app/instrumentThe directory of the stylesheet and fonts every server-rendered page links.
ODUDU_DOCStrue or falsetrueWhether the server serves its documentation under /docs, on its own address. Set false to turn the route off; /docs then answers 404.
ODUDU_DOCS_DIRstring/app/docsThe directory of the built documentation, as the release image lays it out. A directory with no build, or one that is not the build, makes the documentation answer 503 and the log names this variable; the rest of the server starts.

Database​

VariableTypeDefaultDescription
ODUDU_DATABASE_URLURL, secretrequiredThe PostgreSQL connection URL of the owner role. The server applies migrations with it at start and odudu init creates the service role with it. It can switch row-level security off, so production serves traffic through ODUDU_APP_DATABASE_URL instead.
ODUDU_MIGRATIONS_DIRstringnoneA directory of migrations to apply in place of the ones built into the release.
ODUDU_APP_DATABASE_URLURL, secretnone; required when NODE_ENV is productionThe PostgreSQL connection URL of the role the server serves traffic with, which row-level security applies to. Required when NODE_ENV=production. Commands that read every tenant refuse a role that is a superuser or bypasses row-level security.

Encryption​

VariableTypeDefaultDescription
ODUDU_KEKstring, secretrequiredThe key-encryption key: 32 random bytes, base64-encoded. It wraps every signing key and console session token and keys pagination cursors, so changing it makes the stored keys unreadable. Generate one with openssl rand -base64 32.

Rate limits​

VariableTypeDefaultDescription
ODUDU_THROTTLE_LIMITinteger, 1 to 10,00010Requests allowed per origin in each window on the routes that cost a password hash or a mail send. Over the budget the server answers 429.
ODUDU_THROTTLE_WINDOW_SECONDSinteger, 1 to 3,60060The length of the per-origin window, in seconds.
ODUDU_LOGIN_THROTTLE_LIMITinteger, 1 to 10,0005Sign-in submissions allowed per address and username in each window.
ODUDU_LOGIN_THROTTLE_WINDOW_SECONDSinteger, 1 to 3,60060The length of the sign-in window, in seconds.
ODUDU_CLIENT_SECRET_THROTTLE_LIMITinteger, 1 to 10,0005Failed client_secret_basic and client_secret_post attempts allowed per client in each window at the token endpoint.
ODUDU_CLIENT_SECRET_THROTTLE_WINDOW_SECONDSinteger, 1 to 3,60060The length of the client secret window, in seconds.

Retention​

VariableTypeDefaultDescription
ODUDU_RETENTION_GRANT_SECONDSinteger, 60 to 31,536,000604800How long odudu reap keeps a grant (refresh token family) after nothing can read it. A retention window, not a lifespan: it can raise how long rows are kept, never lower it below what reuse detection needs.
ODUDU_RETENTION_OFFLINE_GRANT_SECONDSinteger, 60 to 31,536,0002592000The retention window of an offline grant, the same kind of window as ODUDU_RETENTION_GRANT_SECONDS.
ODUDU_RETENTION_AUTHORIZATION_CODE_SECONDSinteger, 60 to 31,536,0003600How long an authorization code that never produced a grant is kept. A code that did is removed with the grant family it produced.
ODUDU_RETENTION_AUTHENTICATION_SESSION_SECONDSinteger, 60 to 31,536,0003600How long a finished or expired sign-in attempt is kept. This is where most of the rows are.
ODUDU_RETENTION_ACTION_TOKEN_SECONDSinteger, 60 to 31,536,000604800How long a spent or expired mailed action token, or a registration nobody opened, is kept.
ODUDU_RETENTION_REGISTRATION_TOKEN_SECONDSinteger, 60 to 31,536,000604800How long a spent or expired registration token is kept.
ODUDU_RETENTION_SESSION_SECONDSinteger, 60 to 31,536,00086400How long an ended or expired user session is kept.
ODUDU_RETENTION_EMAIL_SENT_SECONDSinteger, 60 to 31,536,000604800How long a delivered email stays in the outbox, counted from its delivery, so an operator can answer whether a link ever went out.
ODUDU_RETENTION_EMAIL_FAILED_SECONDSinteger, 3,600 to 31,536,0002592000How long an email that used up every attempt stays, counted from its last attempt. Long, because nothing else records the failure.
ODUDU_RETENTION_LOGOUT_DELIVERED_SECONDSinteger, 60 to 31,536,000604800How long a delivered back-channel logout is kept, counted from its delivery.
ODUDU_RETENTION_LOGOUT_FAILED_SECONDSinteger, 3,600 to 31,536,0002592000How long a back-channel logout that used up every attempt is kept, counted from its last attempt.

Background passes​

VariableTypeDefaultDescription
ODUDU_REAP_ENABLEDtrue or falsetrueWhether the server runs the retention pass itself. Set it to false when you schedule odudu reap externally, for example as a cron entry or a Kubernetes CronJob.
ODUDU_REAP_INTERVAL_SECONDSinteger, 60 to 86,4003600Seconds between retention passes, plus up to a tenth of that as random jitter.
ODUDU_OUTBOX_ENABLEDtrue or falsetrueWhether the server sends queued email itself. Set it to false when you schedule odudu send-mail; with neither running, queued mail is never sent.
ODUDU_OUTBOX_INTERVAL_SECONDSinteger, 5 to 86,40015Seconds between passes that send queued email.
ODUDU_OUTBOX_BATCH_SIZEinteger, 1 to 1,00020Messages sent per tenant in one pass, so one tenant’s backlog cannot starve another’s.
ODUDU_OUTBOX_MAX_ATTEMPTSinteger, 1 to 1005Attempts a message gets before it is left for an operator to read. Lowering it reclassifies messages already queued: one past the new ceiling stops being retried and starts its failed-email retention window.
ODUDU_OUTBOX_RETRY_BACKOFF_SECONDSinteger, 1 to 86,40060The delay before the first retry of a message; each further attempt doubles it.
ODUDU_LOGOUT_SENDER_ENABLEDtrue or falsetrueWhether the server delivers back-channel logout tokens itself. Set it to false when you schedule odudu send-logouts; with neither running, relying parties of an ended session are never told.
ODUDU_LOGOUT_SENDER_INTERVAL_SECONDSinteger, 5 to 86,40015Seconds between passes that deliver back-channel logout tokens.
ODUDU_LOGOUT_SENDER_BATCH_SIZEinteger, 1 to 1,00020Deliveries claimed per tenant in one pass.
ODUDU_LOGOUT_SENDER_LEASE_SECONDSinteger, 1 to 3,60030How long a claimed delivery stays invisible to other passes: what a process killed between claiming and sending costs.
ODUDU_LOGOUT_SENDER_RESPONSE_TIMEOUT_MSinteger, 100 to 60,0005000Milliseconds one delivery may take, connecting and answering together, before it is abandoned for this pass.

Mail​

VariableTypeDefaultDescription
ODUDU_SMTP_HOSTstringnoneThe SMTP relay to send mail through. Unset, the server logs each message instead of sending it. Needs ODUDU_SMTP_FROM.
ODUDU_SMTP_PORTinteger, 1 to 65,535587The port of the SMTP relay.
ODUDU_SMTP_FROMstringnone; required when ODUDU_SMTP_HOST is setThe address mail is sent from. Required when ODUDU_SMTP_HOST is set.
ODUDU_SMTP_USERNAMEstringnoneThe user name to authenticate to the SMTP relay with.
ODUDU_SMTP_PASSWORDstring, secretnoneThe password to authenticate to the SMTP relay with.
ODUDU_SMTP_STARTTLStrue or falsefalseWhether to require STARTTLS before sending. It is required whenever ODUDU_SMTP_USERNAME and ODUDU_SMTP_PASSWORD are set, so credentials never travel in the clear.

Admin console​

VariableTypeDefaultDescription
ODUDU_CONSOLEtrue or falsetrueWhether the server serves the admin console under /console. While on it needs ODUDU_PUBLIC_BASE_URL and ODUDU_CONSOLE_CLIENT_KEY.
ODUDU_CONSOLE_CLIENT_KEYstring, secretnone; required when the console is on (ODUDU_CONSOLE, which defaults to true)The private key the console authenticates with as every tenant’s built-in admin client: an ES256 JWK, base64-encoded. odudu console keygen prints a new one. Required while the console is on.
ODUDU_CONSOLE_CLIENT_KEY_PREVIOUSstring, secretnoneThe key being replaced, kept registered on every tenant until the pass that drops it. A private or a public JWK, base64-encoded; only the public half is used.
ODUDU_CONSOLE_DIRstring/app/consoleThe directory of the built console’s static files, as the release image lays it out.

Outbound requests​

VariableTypeDefaultDescription
ODUDU_ALLOW_PRIVATE_CLIENT_URLStrue or falsefalseLets the server fetch a client’s jwks_uri or send its back-channel logout to a private address. For development and conformance testing; NODE_ENV=production refuses to boot with it on. A loopback address is refused regardless.
ODUDU_ALLOW_PRIVATE_SMTP_HOSTStrue or falsefalseLets a tenant’s own SMTP relay (set through the admin API) be at a private address, which an internal relay legitimately is. Not refused under NODE_ENV=production. Loopback, link-local and multicast addresses are refused regardless.

Read by commands and the image​

These are read from the environment by a command or the release image rather than by the server’s configuration, so a mistake in them does not stop the server.

VariableDescription
ODUDU_ADMIN_EMAILThe address odudu init gives the first administrator when --admin-email is not passed. A blank value counts as unset.
ODUDU_ADMIN_PASSWORDThe password odudu init gives the first administrator in place of a generated one. It is an environment variable and never an option, so it does not appear in a process listing. A blank value counts as unset.
ODUDU_VERSIONThe version odudu --version prints. The release image sets it; elsewhere it is dev.