Configuration reference
The backend is configured only through RMM_* environment variables
(entrosity-axis.backend/internal/config). Invalid values stop it at start with a list
of every problem.
- Nested sections (
S3,SMTP,RETENTION) accept one or two underscores:RMM_S3_ENDPOINT=RMM_S3__ENDPOINT. - In production, compose derives several variables from the ones at the
top of
deploy/.env(see Installation). - In development,
make dev-backendandmake migrateloaddeploy/.env. - Entrosity Edge and Sphere have their own servers and settings:
EDGE_*(includingEDGE_MASTER_KEYand the connector release keys) in Running Entrosity Edge,SPHERE_*in Running Entrosity Sphere.
Names, TLS and HTTP
| Variable | Default | Meaning |
|---|---|---|
PLATFORM_DOMAIN, RMM_DOMAIN, PLATFORM_OLD_DOMAINS, RMM_FILES_DOMAIN, ACME_EMAIL | none | Caddy site names and ACME account (compose only; see Compose-only settings). |
RMM_ENV | dev | dev, test or prod. prod: JSON logs, secure cookies, and the development example secrets are refused. |
RMM_PUBLIC_URL | http://localhost:8080 | Axis's public address, including its path: the URL given to new agents and connectors, and the issuer of the event stream tokens (compose: https://$PLATFORM_DOMAIN/axis). |
RMM_PORTAL_URL | = public URL | Browser URL of Axis, including its path: https://$PLATFORM_DOMAIN/axis in compose. Links in alert e-mails start with it. In development http://localhost:5175/axis (the Hub's dev server, which proxies /axis). |
RMM_HTTP_ADDR | :8080 | API listener. |
RMM_METRICS_ADDR | :9091 | Internal listener for /metrics and /debug/pprof. Never expose it publicly; empty disables it. |
RMM_CORS_ORIGINS | http://localhost:5173 | Allowed browser origins, comma separated, no wildcards (compose: https://$PLATFORM_DOMAIN). Not needed when the portal is same-origin. |
RMM_TRUSTED_PROXIES | none | CIDRs allowed to set X-Forwarded-For (compose: 172.30.0.0/24). |
RMM_API_RATE_PER_SECOND, RMM_API_RATE_BURST | 20, 60 | Portal API rate limit per client IP. Does not apply to agents and connectors. |
RMM_ENROLL_RATE_PER_MINUTE | 60 | Agent and connector enrollments per IP. Raise it for mass roll-outs behind one NAT address. |
RMM_LOG_LEVEL | info | debug, info, warn or error. |
RMM_NODE_URL | http://<hostname>:<port of RMM_HTTP_ADDR> | Where the other backend replicas reach this one directly (not through Caddy), for remote desktop sessions whose agent and viewer are on different replicas. The default works in the compose stack; set it when replicas cannot resolve each other's hostnames. https:// is supported (certificates are verified against the system roots). |
Database
| Variable | Default | Meaning |
|---|---|---|
RMM_DATABASE_URL | none (required) | Connection URL. Production connects as rmm_app. |
RMM_DATABASE_ROLE | rmm_app | Role the pool switches to after connecting (SET ROLE), so row-level security applies even when connecting as the owner. Empty when the login already is the application role. |
RMM_DATABASE_MAX_CONNS | 20 | Pool size per backend. Keep replicas × this below max_connections (200) minus 20. |
RMM_DATABASE_STATEMENT_TIMEOUT | 30s | Upper bound for any statement. |
RMM_APP_DATABASE_PASSWORD | none | Used by migrate up: enables the rmm_app login with this password. |
POSTGRES_PASSWORD | none | Owner (rmm) password: migrations and backups (compose). |
Secrets
| Variable | Meaning |
|---|---|
RMM_JWT_SECRET | Signs the one-minute event stream tokens (POST /auth/sse-token). At least 32 bytes (raw or base64). Users' access tokens come from Entrosity Hub. |
RMM_JWT_SECRET_OLD | Previous JWT secret during a rotation (Key rotation). |
RMM_MASTER_KEY | AES-256 key (exactly 32 bytes, base64) for secrets at rest: AD passwords, push tokens, queued e-mails. |
RMM_MASTER_KEY_OLD | Previous master key during a rotation (decrypt only). |
RMM_RELEASE_SIGNING_KEY | Ed25519 key (base64 seed or private key) that signs agent/connector releases. make release-keygen prints a pair. |
RMM_RELEASE_TOKEN | Bearer token for release automation (at least 32 characters). Empty disables it. |
Sign-in on Entrosity Hub
Users sign in on Entrosity Hub; Axis has no passwords or sessions of its
own. Axis accepts only the Hub's product tokens (EdDSA, audience rmm),
verified with the Hub's public keys, and keeps a copy of the Hub's users,
organizations (its tenants) and roles, which it pulls from the Hub's
internal API (Architecture).
The first three variables are required: without them the backend does not
start.
| Variable | Default | Meaning |
|---|---|---|
RMM_PLATFORM_URL | none (required) | The Hub's public origin (compose: https://$PLATFORM_DOMAIN, for example https://hub.entrosity.com): the issuer of its tokens and where browsers sign in. Must equal the Hub's PLATFORM_PUBLIC_URL. In development http://localhost:5175. |
RMM_PLATFORM_INTERNAL_URL | none (required) | The Hub's internal listener (compose: http://platform:8081; development http://localhost:8091), reached directly, never through Caddy: signing keys (/internal/v1/jwks.json) and access snapshots. |
RMM_PLATFORM_TOKEN | none (required) | Axis's bearer token on the Hub's internal API (at least 32 characters; the Hub's PLATFORM_PRODUCT_TOKENS entry for rmm, in compose PLATFORM_PRODUCT_TOKEN_RMM). |
RMM_PLATFORM_SYNC_INTERVAL | 30s | How often each replica pulls the access snapshot (at least 1s). |
RMM_MATRIX_INTERNAL_URL | empty (no screen wall) | Entrosity Matrix's internal API for the screen wall (rooms and teachers' room rights), e.g. http://matrix:8086 on the compose network. Compose sets it when MATRIX_AXIS_TOKEN is set. |
RMM_MATRIX_AXIS_TOKEN | empty | Bearer token there: the same value as Matrix's MATRIX_AXIS_TOKEN (at least 32 characters; required with RMM_MATRIX_INTERNAL_URL). |
RMM_VERTEX_INTERNAL_URL | empty (no Vertex) | Entrosity Vertex's internal API, e.g. http://vertex:8088: Axis relays the connectors' secrets requests and result chunks of Vertex jobs there (Running Entrosity Vertex). |
RMM_VERTEX_AXIS_TOKEN | empty | Bearer token of both directions between Axis and Vertex: the same value as Vertex's VERTEX_AXIS_TOKEN (at least 32 characters; required with RMM_VERTEX_INTERNAL_URL). |
RMM_INTERNAL_ADDR | :8089 | Axis's internal listener for Vertex (the tenant's connectors and Vertex jobs). Runs only while Vertex is configured; required then. Never expose it publicly. |
The signing keys are fetched at start and every 10 minutes, and again (at most once a minute) when a token names an unknown key. If the Hub is unreachable, Axis keeps the keys it has; until it has any, every token is refused.
Object storage
| Variable | Default | Meaning |
|---|---|---|
RMM_S3_ENDPOINT | none | Endpoint the backend uses (compose: http://minio:9000). |
RMM_S3_PUBLIC_ENDPOINT | = endpoint | Endpoint in presigned URLs that agents and browsers use (compose: https://$RMM_FILES_DOMAIN). |
RMM_S3_BUCKET | rmm-packages | Bucket name. |
RMM_S3_ACCESS_KEY, RMM_S3_SECRET_KEY | none | Credentials. |
RMM_S3_USE_SSL | false | TLS to the endpoint. |
Without object storage, package uploads and releases are unavailable
(storage_unavailable).
Mail
| Variable | Default | Meaning |
|---|---|---|
RMM_SMTP_HOST | none | SMTP server. |
RMM_SMTP_PORT | 25 | Port. |
RMM_SMTP_USER, RMM_SMTP_PASS | none | Credentials. |
RMM_SMTP_FROM | rmm@localhost | Sender address. |
Axis sends only alert e-mails and digests; invitations and password resets are the Hub's. E-mails are queued in the database and sent by a background job, so a mail outage delays them but loses nothing. Their content is encrypted with the master key while queued.
Agents, packages and retention
| Variable | Default | Meaning |
|---|---|---|
RMM_MIN_AGENT_VERSION | none | Agents and connectors older than this get the newest release at once, ignoring the rollout percentage. |
RMM_AGENT_MSI_URL | none | Fixed agent MSI URL for AD pushes, only when object storage is not used (development). Pushed installs are then not hash-checked. |
RMM_WINGET_SOURCE_URL | public winget source | Index source for the package wizard's winget search; off for offline installations. |
RMM_RETENTION_SNAPSHOT_DAYS | 30 | Raw inventory snapshots. |
RMM_RETENTION_METRICS_DAYS | 90 | Device metrics (monthly partitions are dropped). |
RMM_RETENTION_JOB_DAYS | 90 | Finished jobs, script runs and remote desktop sessions (tenants can set 7–730). |
RMM_RETENTION_AUDIT_DAYS | 365 | Audit log (tenants can set 30–3650). |
RMM_RETENTION_ADSYNC_RUN_DAYS | 90 | AD sync run history. |
RMM_RETENTION_ALERT_DAYS | 180 | Resolved alerts. |
RMM_RETENTION_DELETED_PACKAGE_DAYS | 7 | Files of deleted packages. |
Retention runs daily in batches of 10,000 rows. Device sign-ins are always deleted 7 days after the sign-out; that period is not configurable.
winget
The winget index is refreshed about daily (checked every 6 hours and at
start when stale). Devices without winget install App Installer from files
under releases/winget/ in the bucket (the .msixbundle plus its .appx
dependencies); upload them once.
Entrosity Hub server (PLATFORM_*)
Settings of platform-server, Entrosity Hub's service (the sign-in
portal for all Entrosity products). In production compose sets most of them
from the values in the next section.
| Variable | Default | Meaning |
|---|---|---|
PLATFORM_ENV | dev | dev, test or prod. Production refuses the development example secrets and requires an https public URL. |
PLATFORM_PUBLIC_URL | http://localhost:5175 | The Hub's origin (for example https://hub.entrosity.com): issuer of its tokens (RMM_PLATFORM_URL must match), base of e-mailed links, and the origin its CSRF guard accepts. |
PLATFORM_HTTP_ADDR | :8090 | Public API (/api/platform/v1), behind Caddy. Compose: :8080. |
PLATFORM_INTERNAL_ADDR | :8091 | Internal API for products (signing keys, access snapshots). Never routed by Caddy; must differ from the HTTP address. Compose: :8081. |
PLATFORM_METRICS_ADDR | :9092 | Prometheus metrics (platform_*). |
PLATFORM_DATABASE_URL | none (required) | Connection URL of the platform database. The service connects as platform_app; migrate up as the owner. |
PLATFORM_DATABASE_ROLE | platform_app | Role the pool switches to after connecting. |
PLATFORM_DATABASE_MAX_CONNS, PLATFORM_DATABASE_STATEMENT_TIMEOUT | 10, 30s | Pool size and statement bound. |
PLATFORM_APP_DATABASE_PASSWORD | none | Used by migrate up: enables the platform_app login with this password. |
PLATFORM_JWT_SIGNING_KEY | none (required) | Ed25519 key that signs every Hub token: base64 of a 32-byte seed (openssl rand -base64 32) or a 64-byte private key. Its public half is published as the JWKS. |
PLATFORM_JWT_SIGNING_KEY_OLD | none | Previous signing key during a rotation: still verifies, and stays in the JWKS. |
PLATFORM_MASTER_KEY, PLATFORM_MASTER_KEY_OLD | none (required), none | AES-256 keys (32 bytes, base64) for TOTP seeds and queued e-mails; rotate-master-key re-encrypts with the new one. |
PLATFORM_PRODUCT_TOKENS | none | Bearer tokens of products on the internal API, product:token separated by commas (for example rmm:<32+ characters>). |
PLATFORM_CORS_ORIGINS, PLATFORM_TRUSTED_PROXIES | none | Allowed browser origins; proxies whose X-Forwarded-For is trusted. |
PLATFORM_API_RATE_PER_SECOND, PLATFORM_API_RATE_BURST | 20, 60 | General per-IP API limit. |
PLATFORM_AUTH_RATE_PER_MINUTE, PLATFORM_EMAIL_RATE_PER_MINUTE | 10, 5 | Attempts per minute at sign-in and the other public auth endpoints (invitations, password reset), per client IP and per e-mail address; more are refused with rate_limited (429). At least 1. |
PLATFORM_SMTP_HOST, _PORT, _USER, _PASS, _FROM | none, 25, none, none, platform@localhost | Mail server for invitations and password resets. |
PLATFORM_LOG_LEVEL | info | debug, info, warn or error. |
Compose-only settings
| Variable | Default | Meaning |
|---|---|---|
RMM_VERSION | latest | Image tag. Set by upgrade.sh and deploy.sh. |
WEB_HTTP_PORT, WEB_HTTPS_PORT | 80, 443 | Where Caddy's ports 80 and 443 are published; 127.0.0.1:8080 and 127.0.0.1:8443 behind an existing nginx (TLS). |
RMM_BACKEND_IMAGE, RMM_WEB_IMAGE | ghcr.io/entrosity/axis-backend, …/entrosity-web | Image names. |
RMM_BACKEND_MEMORY | 2g | Backend container memory limit. |
RMM_BACKEND_GOMEMLIMIT | 1400MiB | Go heap target; keep it at about 70 % of the limit. |
PG_SHARED_BUFFERS, PG_EFFECTIVE_CACHE_SIZE | 1GB, 3GB | About 25 % and 75 % of RAM. |
PG_WORK_MEM, PG_MAINTENANCE_WORK_MEM, PG_MAX_CONNECTIONS | 16MB, 256MB, 200 | PostgreSQL tuning. |
PG_ARCHIVE_MODE, PG_ARCHIVE_COMMAND | off, /bin/true | WAL archiving for point-in-time recovery. |
MINIO_ROOT_USER, MINIO_ROOT_PASSWORD | none | MinIO credentials (also given to the backend as S3 keys). |
RMM_BACKUP_DIR, RMM_BACKUP_KEEP_DAYS | ./backups, 14 | Backup location and retention. |
RMM_BACKUP_S3_ENDPOINT, _BUCKET, _ACCESS_KEY, _SECRET_KEY | none | Off-site backup copy. |
GRAFANA_ADMIN_PASSWORD | none | Grafana admin (monitoring compose). |
PLATFORM_DOMAIN | none (required) | The host name of the Hub, Axis (/axis) and the documentation (/docs), for example hub.entrosity.com; DNS must point at the host. Sets PLATFORM_PUBLIC_URL, PLATFORM_CORS_ORIGINS, and the backend's RMM_PLATFORM_URL (https://$PLATFORM_DOMAIN), RMM_PUBLIC_URL and RMM_PORTAL_URL (https://$PLATFORM_DOMAIN/axis) and RMM_CORS_ORIGINS. |
RMM_DOMAIN | none (required) | Axis's host name from before the Hub (for example manage.entrosity.com). Serves only the API of agents, connectors and scripts that use it (/api/*, /manage/api/*); browsers are redirected to https://$PLATFORM_DOMAIN/axis. |
PLATFORM_OLD_DOMAINS | none | Earlier host names of the Hub, space separated (for example portal.entrosity.com), set by the move script. They serve Axis's API under /axis/api and /manage/api for devices enrolled there and redirect everything else to the same path on PLATFORM_DOMAIN. |
PLATFORM_APP_DATABASE_PASSWORD, PLATFORM_JWT_SIGNING_KEY, PLATFORM_MASTER_KEY (and _OLD) | none (required, except _OLD) | Passed to the Hub as above. |
PLATFORM_PRODUCT_TOKEN_RMM | none (required) | Axis's token on the Hub's internal API: becomes PLATFORM_PRODUCT_TOKENS=rmm:<token> and the backend's RMM_PLATFORM_TOKEN. |
PLATFORM_SMTP_FROM | RMM_SMTP_FROM | Sender of the Hub's e-mails (the Hub uses the RMM_SMTP_* server). |
PLATFORM_BACKEND_IMAGE, PLATFORM_MEMORY | ghcr.io/entrosity/hub-backend, 512m | The Hub's image name and memory limit. |