Bring your own backends
Choose your storage, compute, and identity providers β and switch them later without migrating your notebooks.
A provider-agnostic platform to store, manage, and run marimo notebooks. No database β bring your own storage, compute, and identity.
Pick your storage, compute, and auth backends to generate ready-to-paste config (.env, Helm, or Docker Compose) and the equivalent library wiring code β live, no install required.
Any S3-compatible store: CoreWeave CAIOS, AWS S3, MinIO, Tigris, Ceph, or Cloudflare R2 via its S3 endpoint. Point `*_S3_ENDPOINT` at the provider.
Modal sandboxes.
App-native OpenID Connect (the production backend).
No managed AI. The marimo assistant still works if a user supplies their own key in marimo settings.
# --- Storage ---
MARIMOHUB_STORAGE_BACKEND=s3
MARIMOHUB_STORAGE_S3_BUCKET=orgname-marimohub
MARIMOHUB_STORAGE_S3_ENDPOINT=https://s3.us-east-1.amazonaws.com
MARIMOHUB_STORAGE_S3_REGION=us-east-1
MARIMOHUB_STORAGE_S3_ACCESS_KEY_ID= # secret
MARIMOHUB_STORAGE_S3_SECRET_ACCESS_KEY= # secret
MARIMOHUB_STORAGE_S3_FORCE_PATH_STYLE=true
# --- Compute ---
MARIMOHUB_COMPUTE_BACKEND=modal
MARIMOHUB_COMPUTE_IMAGE=ghcr.io/orgname/marimo-sandbox:latest
MARIMOHUB_COMPUTE_IDLE_TIMEOUT=20m
MARIMOHUB_COMPUTE_SANDBOX_HOSTNAME=hub.example.com
MARIMOHUB_COMPUTE_WORKDIR=/workspace
MARIMOHUB_COMPUTE_ASSET_URL=https://cdn.jsdelivr.net/npm/@marimo-team/frontend@{version}/dist
MARIMOHUB_COMPUTE_MODAL_TOKEN_ID= # required, secret
MARIMOHUB_COMPUTE_MODAL_TOKEN_SECRET= # required, secret
MARIMOHUB_COMPUTE_MODAL_APP_NAME=marimohub
# --- Auth ---
MARIMOHUB_AUTH_BACKEND=oidc
MARIMOHUB_AUTH_OIDC_ISSUER=https://accounts.example.com
MARIMOHUB_AUTH_OIDC_CLIENT_ID= # required
MARIMOHUB_AUTH_OIDC_CLIENT_SECRET= # required, secret
MARIMOHUB_AUTH_OIDC_REDIRECT_URI=https://hub.example.com/api/auth/callback
MARIMOHUB_AUTH_OIDC_AUDIENCE=
MARIMOHUB_AUTH_SESSION_SECRET= # required, secret
MARIMOHUB_AUTH_ALLOWED_EMAIL_DOMAINS=example.com,example.org
# --- Managed AI ---
MARIMOHUB_AI_BACKEND=none
# --- Options ---
MARIMOHUB_PERSIST_WORKSPACE=sourceHow to provision and connect each backend you picked above.
Works with any S3-compatible store (AWS S3, MinIO, Tigris, Ceph, CoreWeave CAIOS, or Cloudflare R2 via its S3 endpoint).
MARIMOHUB_STORAGE_BACKEND=s3
MARIMOHUB_STORAGE_S3_BUCKET=orgname-marimohub
MARIMOHUB_STORAGE_S3_ENDPOINT=https://s3.us-east-1.amazonaws.com # omit for AWS
MARIMOHUB_STORAGE_S3_REGION=us-east-1
MARIMOHUB_STORAGE_S3_ACCESS_KEY_ID=β¦ # secret β or use the SDK default chain
MARIMOHUB_STORAGE_S3_SECRET_ACCESS_KEY=β¦ # secret
Your store must support conditional writes
marimohub uses S3 If-Match to update notebooks safely and refuses to start on
a store that doesn't honor it. AWS S3, R2, Tigris, CoreWeave CAIOS, and recent
MinIO all qualify; very old MinIO/Ceph builds may not.
MinIO / Ceph need path-style addressing
Set MARIMOHUB_STORAGE_S3_FORCE_PATH_STYLE=true for MinIO and Ceph, or requests
to the bucket will fail to resolve.
CAIOS (CoreWeave AI Object Storage) is CoreWeave's S3-compatible store and the
storage half of the CKS deployment. Use the s3 backend and
point the endpoint at CAIOS:
MARIMOHUB_STORAGE_BACKEND=s3
MARIMOHUB_STORAGE_S3_BUCKET=orgname-marimohub
MARIMOHUB_STORAGE_S3_ENDPOINT=https://cwobject.com
MARIMOHUB_STORAGE_S3_ACCESS_KEY_ID=β¦ # CAIOS access key (secret)
MARIMOHUB_STORAGE_S3_SECRET_ACCESS_KEY=β¦ # CAIOS secret key (secret)
MARIMOHUB_COMPUTE_BACKEND=modal
MARIMOHUB_COMPUTE_MODAL_TOKEN_ID=β¦ # secret
MARIMOHUB_COMPUTE_MODAL_TOKEN_SECRET=β¦ # secret
MARIMOHUB_COMPUTE_IMAGE=ghcr.io/orgname/marimo-sandbox:latest
MARIMOHUB_COMPUTE_IDLE_TIMEOUT=20m # auto-stop idle kernels to control spend
No infrastructure to run
Modal is fully serverless β nothing to provision or scale, and you pay only for running kernels. The easiest path if you don't already run a cluster.
Cold starts & shared workspaces
A freshly-started kernel can take a few seconds to boot; a warm sandbox image
(Sandbox image) helps. If multiple apps share one Modal
workspace, set MARIMOHUB_COMPUTE_MODAL_APP_NAME so marimohub only reaps its
own sandboxes.
App-native OpenID Connect β the production backend. marimohub discovers the
provider's endpoints automatically from the issuer's
/.well-known/openid-configuration, so you only supply an issuer, client
credentials, and a redirect URI.
MARIMOHUB_AUTH_BACKEND=oidc
MARIMOHUB_AUTH_OIDC_ISSUER=https://accounts.example.com
MARIMOHUB_AUTH_OIDC_CLIENT_ID=β¦
MARIMOHUB_AUTH_OIDC_CLIENT_SECRET=β¦
MARIMOHUB_AUTH_OIDC_REDIRECT_URI=https://hub.example.com/api/auth/callback
MARIMOHUB_AUTH_SESSION_SECRET=β¦ # signs the session cookie (HS256, β₯32 bytes)
MARIMOHUB_AUTH_ALLOWED_EMAIL_DOMAINS=example.com # REQUIRED allowlist (verified email); `*` allows all
# MARIMOHUB_AUTH_OIDC_AUDIENCE=β¦ # optional: expected ID-token audience (the client id is enforced anyway)
The redirect URI is always https://<your-host>/api/auth/callback. Register
it with your provider exactly as you set it here, or login fails with a
redirect_uri_mismatch error. ALLOWED_EMAIL_DOMAINS is required β
marimohub fails closed rather than admitting every account the IdP
authenticates; list your domains or set * to allow all.
Generate a session secret with openssl rand -base64 32.
https://hub.example.com/api/auth/callback
(and http://localhost:3000/api/auth/callback for local testing).MARIMOHUB_AUTH_OIDC_ISSUER=https://accounts.google.com
MARIMOHUB_AUTH_OIDC_CLIENT_ID=β¦apps.googleusercontent.com
MARIMOHUB_AUTH_OIDC_CLIENT_SECRET=β¦
MARIMOHUB_AUTH_ALLOWED_EMAIL_DOMAINS=example.com # a single domain is also sent to Google as the `hd` hint
See Google's OpenID Connect docs.
https://hub.example.com/api/auth/callback.# tenant-scoped issuer (use `organizations` or `common` for multi-tenant)
MARIMOHUB_AUTH_OIDC_ISSUER=https://login.microsoftonline.com/<tenant-id>/v2.0
MARIMOHUB_AUTH_OIDC_CLIENT_ID=<application-client-id>
MARIMOHUB_AUTH_OIDC_CLIENT_SECRET=β¦
https://hub.example.com/api/auth/callback as a Sign-in redirect URI.MARIMOHUB_AUTH_OIDC_ISSUER=https://<your-org>.okta.com
MARIMOHUB_AUTH_OIDC_CLIENT_ID=β¦
MARIMOHUB_AUTH_OIDC_CLIENT_SECRET=β¦
If you use an Okta authorization server, the issuer is
https://<your-org>.okta.com/oauth2/<server-id>. See
Okta's OIDC docs.
https://hub.example.com/api/auth/callback.# note the trailing slash on the issuer
MARIMOHUB_AUTH_OIDC_ISSUER=https://<tenant>.auth0.com/
MARIMOHUB_AUTH_OIDC_CLIENT_ID=β¦
MARIMOHUB_AUTH_OIDC_CLIENT_SECRET=β¦
See Auth0's OIDC docs.
Managed AI is off β the default:
MARIMOHUB_AI_BACKEND=none
The marimo AI assistant still works if a user supplies their own API key in marimo's settings. Turn on managed AI to provide a key for everyone.