Environment variables
Every environment variable the AIOE API reads, with its default and what it does.
The API reads its whole configuration from the environment when it starts, and refuses to start when a required value is missing. Set these on the API container: in docker-compose.yml, in your Helm values, or in the Azure template's parameters. Keep secrets (database passwords, keys, client secrets) in your secret store, never in a committed file.
This page lists 74 variables. "Sometimes" in the Required column means the variable is required only in the case its description gives.
Service
Where the API listens and how it describes itself.
| Variable | Default | Required | What it does |
|---|---|---|---|
AIOE_EDITION | enterprise | No | Which edition this deployment is. enterprise is self-hosted AIOE: one organisation per identity provider issuer. cloud is the multi-organisation Mojo Up AI Cloud mode with its own sign-in. |
CONSOLE_URL | http://localhost:5173 | No | The address of the web console, without a trailing slash. Used in links the API sends, such as invitations and approval pages. |
NODE_ENV | development | No | Set to production in production. Development-only features stay off in production whatever else is set. |
PORT | 3001 | No | The port the API listens on. |
PUBLIC_URL | http://localhost:3001 | No | The address workbenches, nodes and phones use to reach the API, without a trailing slash. |
Database and cache
Where the platform keeps its records, and the shared cache that lets you run more than one replica.
| Variable | Default | Required | What it does |
|---|---|---|---|
DATABASE_URL | Sometimes | The PostgreSQL connection string. Required when STORE is postgres. | |
REDIS_URL | No | A Redis connection string. Set it when you run more than one API replica, so relay connections and events reach every replica. Unset means one replica. | |
STORE | memory | No | Where records are kept: postgres for any real installation, memory for a throwaway evaluation (everything is lost on restart). |
Your organisation and identity provider
The organisation created at start-up and the identity provider its people sign in with.
| Variable | Default | Required | What it does |
|---|---|---|---|
AIOE_BOOTSTRAP_API_SCOPE | Sometimes | The scope clients request for the API, for example api://aioe.example.com.au/access. Required when AIOE_BOOTSTRAP_TENANT is set. | |
AIOE_BOOTSTRAP_DOMAINS | No | Comma-separated email domains that belong to the organisation, for example example.com.au,example.com. Workbenches use them to find the organisation from a work email. | |
AIOE_BOOTSTRAP_OIDC_AUDIENCE | Sometimes | The audience the API accepts in access tokens from your identity provider (with Microsoft Entra ID, the API app registration's client ID). Required when AIOE_BOOTSTRAP_TENANT is set. | |
AIOE_BOOTSTRAP_OIDC_CLIENT_ID | Sometimes | The client ID the console and workbenches sign in with. Required when AIOE_BOOTSTRAP_TENANT is set. | |
AIOE_BOOTSTRAP_OIDC_ISSUER | Sometimes | Your identity provider's OIDC issuer URL. The issuer of a person's token selects their organisation. Required when AIOE_BOOTSTRAP_TENANT is set. | |
AIOE_BOOTSTRAP_ORGANISATION | No | The organisation's display name. Defaults to the slug. | |
AIOE_BOOTSTRAP_TENANT | No | A short identifier (slug) for the organisation to create at start-up. Unset means no organisation is created from the environment. |
Tokens, devices and the relay
How long sign-ins and device codes last, and how the relay treats workbenches.
| Variable | Default | Required | What it does |
|---|---|---|---|
AIOE_ACCESS_TOKEN_TTL | 3600 | No | Seconds a device access token issued by the platform lasts. |
AIOE_DEVICE_CODE_TTL | 600 | No | Seconds a workbench's enrolment code stays valid while someone approves it. |
AIOE_DEVICE_POLL_INTERVAL | 5 | No | Seconds between a device's checks on whether its code has been approved. The minimum is 1. |
AIOE_NODE_CODE_TTL | 86400 | No | Seconds a node's join request waits for an approver. |
AIOE_OFFLINE_AFTER | 90 | No | Seconds without a heartbeat before a workbench shows as offline. |
AIOE_REFRESH_TOKEN_TTL | 2592000 | No | Seconds a device refresh token lasts. |
AIOE_RPC_TIMEOUT | 30 | No | Seconds a remote-control request through the relay waits for the workbench to answer. |
Keys and secrets
Keys the platform uses to protect what it holds. Keep these in your secret store.
| Variable | Default | Required | What it does |
|---|---|---|---|
AIOE_SECRETS_KEY | No | A 32-byte AES-256-GCM key, base64-encoded, that encrypts the secrets the platform holds for workbenches and nodes. Unset means no secrets can be stored. | |
AIOE_SIGNING_KEY | No | The Ed25519 private key (a JWK, as JSON) that signs requests the platform sends over the overlay network. Generated at start-up when unset; set it so every replica and every restart uses the same key. |
Overlay network
The WireGuard overlay, its gateway and relays. Leave these unset if you use the outbound relay only.
| Variable | Default | Required | What it does |
|---|---|---|---|
AIOE_GATEWAY_SECRET | No | The secret shared with the overlay gateway. | |
AIOE_GATEWAY_URL | No | The private address of the overlay gateway. Set together with AIOE_GATEWAY_SECRET; unset means remote control uses the relay only. | |
AIOE_MESH_KEEPALIVE | 25 | No | Seconds between WireGuard keepalives. |
AIOE_MESH_MTU | 1280 | No | The MTU of the overlay interface. |
AIOE_MESH_OFFLINE_AFTER | 120 | No | Seconds without a status report before an overlay member shows as offline. |
AIOE_MESH_POLL_INTERVAL | 30 | No | Seconds between an overlay member's checks for changes to the network. |
AIOE_MESH_RELAYS | [] | No | The overlay relays, as a JSON array of objects with id, region, host, port and optionally publicKey. |
AIOE_MESH_STUN | stun.cloudflare.com:3478,stun.l.google.com:19302 | No | Comma-separated STUN servers overlay members use to find their public address. |
AIOE_RELAY_UPSTREAM | No | The overlay relay service the API passes relay traffic through to. Unset means the API host does not serve it. |
Integrations
Optional connections to other services.
| Variable | Default | Required | What it does |
|---|---|---|---|
AIOE_ENTRA_CLIENT_SECRET | No | The API's own Microsoft Entra client secret, which lets it act on a person's behalf with Azure DevOps. Unset means Azure DevOps links use a personal access token only. | |
EXPO_ACCESS_TOKEN | No | An Expo push access token, if your Expo project requires one for push notifications to the mobile app. Pushes are sent without it otherwise. |
Logging and telemetry
Logs and OpenTelemetry. Telemetry is off unless an exporter endpoint is set.
| Variable | Default | Required | What it does |
|---|---|---|---|
AIOE_ENVIRONMENT | No | The deployment environment name reported with telemetry (for example production). Falls back to NODE_ENV. | |
LOG_LEVEL | info | No | The log level (pino levels: trace, debug, info, warn, error, fatal). |
OTEL_EXPORTER_OTLP_ENDPOINT | No | The OpenTelemetry collector's OTLP/HTTP endpoint. Traces and metrics are exported only when this is set. | |
OTEL_EXPORTER_OTLP_HEADERS | No | Headers sent to the collector, as comma-separated key=value pairs (for example an API key). | |
OTEL_LOG_LEVEL | No | Set to debug to log the OpenTelemetry SDK's own diagnostics. | |
OTEL_METRIC_EXPORT_INTERVAL | 30000 | No | Milliseconds between metric exports. |
OTEL_SERVICE_NAME | aioe-api | No | The service name reported with traces and metrics. |
Releases and licensing
Where this platform follows releases from, and the licence it holds.
| Variable | Default | Required | What it does |
|---|---|---|---|
AIOE_LICENCE | Sometimes | The enterprise licence token from the customer portal (starts with saa1.). The console's Settings → Licence can install one instead. Without a licence the deployment runs an unlicensed trial, after which its workbenches and nodes are licensed as Free. self-hosted | |
AIOE_LICENCE_CHECK_IN | 1 | Sometimes | 1 (default) checks in with the portal on the schedule the licence names, which also renews it. 0 for air-gapped installs, which paste a new token each term. self-hosted |
AIOE_LICENCE_TRIAL_DAYS | 30 | Sometimes | How long an unlicensed deployment runs as Enterprise before its devices are licensed as Free, counted from the first start of a build that knows licences. Default 30. self-hosted |
AIOE_PORTAL_PUBLIC_KEY | No | The portal's Ed25519 public key that signs enterprise licences and Cloud entitlements (base64 SPKI or PEM; comma-separate two during a rotation). Without it a pasted licence cannot be checked. | |
AIOE_PORTAL_URL | No | The Mojo Up customer portal's API, used for licence check-in (and, on Mojo Up AI Cloud, Teams billing). Default https://api.mojoup.com.au. | |
AIOE_RELEASES_SYNC_HOURS | 6 | No | Hours between pulls of the upstream index. Default 6; an administrator's Check now on the Updates page pulls at once. |
AIOE_RELEASES_UPSTREAM | No | The release index this platform follows. By default Mojo Up AI Cloud follows the customer portal's index and a self-hosted AIOE follows Mojo Up AI Cloud (https://ai.mojoup.com.au/releases/v1/index.json). Empty follows nothing: the Updates page then shows only what the fleet runs. | |
AIOE_RELEASES_UPSTREAM_JWKS | No | Where the upstream publishes the keys its index is signed with. Derived from the upstream address for a self-hosted AIOE (Mojo Up AI Cloud signs its index); set it to empty to follow an unsigned private mirror. |
Mojo Up AI Cloud edition
Read only when AIOE_EDITION is cloud. A self-hosted Enterprise installation leaves these unset.
| Variable | Default | Required | What it does |
|---|---|---|---|
AIOE_CLOUD_ACCESS_TTL | 900 | No | Seconds a person's Cloud access token lasts. |
AIOE_CLOUD_AUTH_RATE_LIMIT | 30 | No | Sign-in requests allowed per minute from one address. |
AIOE_CLOUD_ENTITLEMENT_GRACE_DAYS | 7 | No | How long a cached entitlement is honoured past its expiry while the portal cannot be reached. Default 7; after that the team is on the free plan until the portal answers, and nothing is deleted. |
AIOE_CLOUD_ENTITLEMENT_REFRESH_HOURS | 6 | No | How often every team's entitlement token is pulled again from the portal. Default 6. |
AIOE_CLOUD_FACEBOOK_CLIENT_ID | No | Facebook Login: the app ID. | |
AIOE_CLOUD_FACEBOOK_CLIENT_SECRET | No | Facebook Login: the app secret. | |
AIOE_CLOUD_GITHUB_CLIENT_ID | No | GitHub sign-in: the OAuth app's client ID. | |
AIOE_CLOUD_GITHUB_CLIENT_SECRET | No | GitHub sign-in: the OAuth app's client secret. | |
AIOE_CLOUD_GOOGLE_CLIENT_ID | No | Google sign-in: the OAuth client ID. Google sign-in is offered only when both its ID and secret are set. | |
AIOE_CLOUD_GOOGLE_CLIENT_SECRET | No | Google sign-in: the OAuth client secret. | |
AIOE_CLOUD_INVITATION_DAYS | 7 | No | Days an invitation link stays valid. |
AIOE_CLOUD_MICROSOFT_CLIENT_ID | No | Microsoft sign-in: the application (client) ID. | |
AIOE_CLOUD_MICROSOFT_CLIENT_SECRET | No | Microsoft sign-in: the client secret. | |
AIOE_CLOUD_PORTAL_KEY | No | The shared integration key for Teams billing: the bearer on Cloud's calls to the portal and the key the portal signs its pushes with. Billing is offered only when this and the public key are both set. | |
AIOE_CLOUD_PORTAL_PUBLIC_KEY | No | Older name for AIOE_PORTAL_PUBLIC_KEY; still read. | |
AIOE_CLOUD_PORTAL_URL | https://api.mojoup.com.au | No | Older name for AIOE_PORTAL_URL; still read. |
AIOE_CLOUD_REDIRECTS | No | Extra comma-separated addresses a sign-in may return to, beyond the console's callback and the mobile app. | |
AIOE_CLOUD_REFRESH_TTL | 2592000 | No | Seconds a person's Cloud refresh token lasts. Refresh tokens rotate on every use. |
AIOE_EMAIL_FROM | Mojo Up <no-reply@mojoup.com.au> | No | The sender of sign-in codes and invitations. |
AIOE_SMTP_URL | No | The SMTP URL for sign-in codes and invitations. Unset means codes are written to the log, which is for development only. |
Development and testing
Never set these in production.
| Variable | Default | Required | What it does |
|---|---|---|---|
AIOE_DEV_AUTH | 0 | No | Set to 1 to accept development sign-ins without an identity provider. Ignored when NODE_ENV is production. |
AIOE_ENTRA_TOKEN_ENDPOINT | No | A test hook: where to exchange tokens instead of the organisation's issuer. |
Other
Variables the reference has not yet grouped.
| Variable | Default | Required | What it does |
|---|---|---|---|
AIOE_BACKUP_ESCROW_RECIPIENT | No | The platform recovery service's public key as JSON, so backups can also be unlocked by it. Unset means backups are unlocked only by the person's devices, their Emergency Kit and the organisation recovery key. | |
AIOE_BACKUP_QUOTA_BYTES | No | Self-hosted: the most encrypted-backup storage each person may use in the organisation, in bytes. Unset means no limit. Mojo Up AI Cloud's limits are its plans'. |