Access & accounts.
How you get in, what an account gets you, and — for teams running their own instance — the environment Essarion Science expects.
§ 01Accounts
Essarion Science uses email and password sign-in, with a session issued as a signed cookie. Every research model is available to any signed-in account: there is no per-model gate and no model-tier quota.
GOOGLE_* variables present in the environment are unused by this product.§ 02Sign in with Essarion
Deployments can optionally delegate authentication to a shared Essarion ID provider. The Sign in with Essarion button only renders when the backend reports that SSO is configured, so email and password sign-in keeps working with none of it set.
Essarion ID is its own user system
Essarion IDs live in their own table with their own email and password, separate from the table backing an app's normal sign-in. Being signed into Essarion Science is not being signed into Essarion ID, and an app session token cannot pass as an Essarion ID one — the session JWTs carry different type claims.
Everything after the handshake is ordinary. The client app turns the id_token into a local user row, linked by subject — never by unverified email — and then issues its normal session cookie. Once through the door, an Essarion ID login behaves exactly like an email and password login.
Linking an existing account
An email that already belongs to a local account is never silently taken over. It is linked by proving the password:
- In provider mode, an existing local account is turned into an Essarion ID through a claim step that carries the verified hash across.
- In client mode, a callback that lands on such an account sends the user to a link screen with a signed, 15-minute token and asks for that account's password before attaching the Essarion ID.
Both routes in keep working afterwards.
The authorization step
In provider mode, the authorize endpoint never signs anyone in by itself. It validates the OAuth request and redirects to the Essarion ID screen, which lists the IDs already signed in on that browser, lets a visitor create or sign into one, and posts the confirmed account to the approve endpoint — which is what mints the authorization code.
Configuration
| Variable | Role | Notes |
|---|---|---|
| ESSARION_ID_ISSUER | client | Base origin of the provider. Leave unset to hide the button entirely. |
| ESSARION_ID_CLIENT_ID | client | This app's registered client id, e.g. essarion-science. |
| ESSARION_ID_SECRET | both | HS256 secret shared between the provider and its clients. |
| ESSARION_ID_CLIENTS | provider | Allowlist of client_id=origin pairs. The only accepted redirect URI is {origin}/api/auth/essarion/callback, matched exactly. |
| ESSARION_ID_CLIENT_NAMES | provider | Optional client_id=Display Name pairs for the account chooser copy. |
§ 03Budgets and metering
Token usage is metered per run against the account it belongs to. Two variables control the policy:
| Variable | Effect |
|---|---|
| BIOMED_MONTHLY_TOKEN_BUDGET | Monthly model-token cap for metered accounts. |
| ADMIN_EMAILS | Comma-separated emails granted unlimited access. |
§ 04Running your own instance
Essarion Science ships as a single FastAPI web service: /api/* is served by FastAPI, and the built client is served from the same process.
Required
| Variable | Purpose |
|---|---|
| OPENROUTER_API_KEY | Preferred model provider. Planning and synthesis route through OpenRouter using OPENROUTER_MODEL. |
| XAI_API_KEY | Fallback provider, used when OpenRouter is unset. |
| DATABASE_URL | Postgres or SQLite connection string for auth and run ownership. |
| JWT_SECRET | Signs the auth session cookies. |
Recommended
| Variable | Purpose |
|---|---|
| ENVIRONMENT | Set to production in production. |
| COOKIE_SECURE | Defaults to true when ENVIRONMENT=production. |
| APP_BASE_URL | Public frontend origin. |
| API_BASE_URL | Public backend origin — set when the API is on its own domain or subdomain. |
Optional
| Variable | Default / effect |
|---|---|
| OPENROUTER_MODEL | Model used through OpenRouter. |
| GROK_MODEL | Model used through the XAI fallback. |
| BIOMED_PLANNER_LOOP | Routes runs through the reactive planner loop. On by default. |
| CORS_ORIGINS | Comma-delimited origins for credentialed dev access. |
| MAX_CONCURRENT_SCRAPES | Concurrent fetch limit. Defaults to 5. |
| MAX_CONCURRENT_FETCHES | Concurrent fetch limit. Defaults to 5. |
| LOG_LEVEL | Defaults to INFO. |
Database and rate-limit keys for the science connectors themselves are covered in Data sources — all optional, all limit-raising rather than enabling.
Build and start
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
uvicorn main:app --reload
Build command: bash build.sh
Start command: ./start.sh
The build step installs the toolchain, builds the client bundle, installs Python dependencies, and applies database migrations before the service starts serving traffic.
§ 05Security posture
Tenant isolation, credential hashing, transport, and audit posture follow the platform-wide model documented in Security. Two Science-specific boundaries are worth restating: the notebook kernel validates every cell against a static AST validator with a restricted builtin set before execution, and the shell sandbox runs each command in its own subprocess under CPU, memory, file-size, and descriptor limits. Both are described in The workbench.