Skip to content

Security overview

Magellon is deployed on-premises or in a private cloud. Your cryo-EM data never leaves your infrastructure. On top of that, the platform implements a multi-layer security model that controls who can log in, what they can do, and which sessions they can see.

Every API request passes through five independent layers before a result is returned:

LayerWhat it enforces
1 — AuthenticationVerifies the caller’s identity using a signed JWT token. Unauthenticated requests receive 401 Unauthorized.
2 — Endpoint authorizationChecks whether the authenticated user’s role permits the specific endpoint and action being requested (e.g. admin:write vs viewer:read). Returns 403 Forbidden on failure.
3 — Casbin policy evaluationEvaluates fine-grained, policy-based access rules (role → resource → action → effect). Supports wildcard resource matching and explicit deny policies.
4 — Row-level security (RLS)Automatically appends WHERE session_id IN (...) to every database query, restricting results to sessions the current user is authorized to access. No application code needed per query.
5 — Database accessMySQL executes only the RLS-filtered query. The final result set contains exclusively rows the requesting user is permitted to see.

Layers are independent: passing Layer 1 does not bypass Layer 4. A request that reaches the database query stage still only retrieves the rows the user owns.

Magellon uses JWT (JSON Web Token) authentication.

  • Tokens are issued at login and expire after a configurable interval.
  • Tokens are validated on every request — there is no stateful session cookie.
  • Tokens are signed; a tampered or forged token is rejected at Layer 1.
API access

If you are calling the Magellon API programmatically (e.g. from a script), include the token in the Authorization: Bearer <token> header. Retrieve a token from POST /auth/login with your username and password.

Magellon uses Casbin to evaluate role-based access control (RBAC) policies. The built-in roles are:

RoleTypical capabilities
adminFull access — manage users, install/uninstall plugins, import sessions, read all data
operatorRun imports, manage plugins, read session data for their assigned sessions
viewerRead-only access to sessions they have been granted

Roles are assigned per user by an administrator in the user management panel. A user can hold multiple roles.

Default deny

Magellon’s policy engine defaults to deny. A user with no role assigned can log in but cannot access any resource or data until a role is explicitly granted.

Row-level security — your data stays yours

Section titled “Row-level security — your data stays yours”

The most important data-isolation guarantee in Magellon is row-level security (RLS). It works like this:

  1. When a user logs in, the system resolves the set of session IDs they are permitted to access.
  2. Every subsequent database query — images, jobs, results, metadata — has WHERE session_id IN (...) automatically added by a SQLAlchemy event listener.
  3. No application code needs to be aware of this; the filter is applied at the ORM level, globally.

In practice: a user assigned to Session A cannot see data from Session B, even if they craft a direct API call. The query-level filter enforces this regardless of the API endpoint.

Credentials (database passwords, JWT signing secret, broker credentials) are loaded exclusively from environment variables and the .env file at startup. No credentials are hardcoded in the application code or container images. See Environment Settings for the list of configurable secrets.

Change default credentials before production

The default Docker Compose configuration ships example credentials (database password, RabbitMQ password, JWT secret) that are suitable for local development only. Replace them all before deploying to a shared or externally reachable host.

For a production deployment, verify the following:

  • .env contains non-default values for all credential variables
  • The Magellon UI and API are behind a TLS-terminating reverse proxy (nginx, Caddy, or a cloud load balancer) — Magellon itself does not serve HTTPS
  • Port 15672 (RabbitMQ management UI) is not exposed externally
  • Port 3306 (MySQL) is not exposed externally
  • The shared data directory (MAGELLON_HOME_PATH) is readable only by the user running the containers
  • JWT token expiry is set to a reasonable interval for your security policy

All access-control decisions are logged — who requested what resource, which policy matched, and whether access was granted or denied. Logs are written to the CoreService container’s stdout and forwarded to your log aggregator via standard Docker logging drivers.