This document is for security researchers, operators, and integrators who need to understand manta's security model end-to-end or who have found a potential vulnerability.
For deeper technical detail on each control, see
ARCHITECTURE.md §Security model. For
the removal of the previously-shipped manta-read-only JWT-role gate,
see MIGRATING.md §5.12.
For the user-facing description of the CLI-side read-only flag that
remains, see GUIDE.md §13.
Do not open a public GitHub issue for a suspected vulnerability. We use private disclosure channels:
- Preferred — GitHub Security Advisories. Open a private advisory at https://github.com/eth-cscs/manta/security/advisories/new. This keeps the report invisible to the public while the fix is prepared.
- Fallback — email. If you cannot use GitHub Security Advisories,
email the maintainers directly:
- Manuel Sopena Ballesteros —
msopena@cscs.ch - Miguel Gila —
miguel.gila@cscs.chUse a subject prefix like[manta-security]so the report routes correctly. PGP is not currently configured for these addresses — if you need encrypted transport, reach out first to coordinate.
- Manuel Sopena Ballesteros —
Please include, at minimum:
- The version (
manta --versionandmanta-server --version) where you observed the issue. - A reproduction (HTTP request, CLI invocation, or test script).
- The impact you assess (what an attacker can do).
- Your disclosure timeline preference, if any.
We will acknowledge receipt within 5 working days and provide a status update within 15 working days. If the report is in scope, a fix and coordinated disclosure timeline will be agreed before any public discussion of the issue.
manta 2.x is the actively-maintained line; the 1.x series did not have a server binary and is no longer maintained.
| Version | Status | Security fixes |
|---|---|---|
2.0.0-beta.x (current) |
active development | yes — on main |
2.0.0 (when released) |
active | yes — backported to the release branch |
1.x |
unmaintained | no |
During the 2.0.0-beta.x series, fixes land on main and ride out on
the next beta tag. There is no separate security branch — operators
running a pinned beta should plan to upgrade promptly when an advisory
lands.
manta is a 3-tier system. The sequence below shows the bootstrap auth call and a subsequent authenticated request:
Sequence: bootstrap (auth) then a subsequent authenticated request.
sequenceDiagram
autonumber
participant CLI as User CLI
participant MS as manta-server
participant K as Keycloak / IdP
participant B as CSM / OCHAMI
participant Kf as Kafka (optional)
Note over MS: chokepoint — every CSM/OCHAMI call proxies through here
Note over MS: /v2/auth/* sub-router<br/>rate_limit + body-redaction layers
CLI->>MS: POST /v2/auth/token<br/>{username, password}
MS->>K: exchange credentials
K-->>MS: bearer token
MS-->>CLI: { token }
MS->>Kf: audit { outcome, username, source_ip, site }
Note over MS: /v2/* sub-router<br/>TimeoutLayer
CLI->>MS: {method} /v2/{resource}<br/>Authorization: Bearer …
MS->>B: proxied call with bearer
B-->>MS: backend response (signature verified upstream)
MS-->>CLI: 2xx / 4xx
For the user-facing read-only flow specifically, see GUIDE.md §13 — Read-only access. For where the middleware layers sit in the request pipeline, see ARCHITECTURE.md → Middleware layer stack.
- CLI side (
mantabinary): a thin client that runs on operator workstations. Holds the user's bearer token in a 0600 cache file under the platform config dir. Never speaks to CSM/OCHAMI directly. - Server side (
manta-serverbinary): the credential-handling chokepoint. Receives user/password onPOST /v2/auth/token, exchanges them with the per-site backend, returns the bearer token to the CLI. Subsequent authenticated endpoints proxy backend calls using the user's token. - Upstream (CSM / OpenCHAMI / Keycloak): not part of this repo. Signature verification of the bearer token happens here, at the first backend round-trip.
Because manta-server sees every authentication attempt and holds
per-site service-account tokens (for k8s, Vault, Gitea), it is a
single point of compromise for every site it serves. Operate it
accordingly.
| Control | Where | Notes |
|---|---|---|
| TLS required by default | manta-server |
Server fails closed without cert + key. Pass --allow-http only when TLS terminates upstream. |
| HSTS on every response | manta-server |
Strict-Transport-Security: max-age=31536000; includeSubDomains. No-op over plain HTTP per RFC 6797. |
Per-source-IP rate limit on /v2/auth/* |
manta-server |
[server].auth_rate_limit_per_minute (default 60). Implementation in server::auth_middleware::rate_limit. |
| Generic 401 on every auth failure | manta-server |
server::handlers::auth_token returns identical "invalid credentials" body regardless of whether the user was unknown or the password was wrong. Detail stays in server-side tracing::warn!. |
| Audit event per auth attempt | manta-server |
When [auditor.kafka] is configured, server::common::audit::send_auth_audit emits { outcome, username, source_ip, site }. Credentials are never logged. |
Body redaction on /auth/* log spans |
manta-server |
server::auth_middleware::strip_body_for_logs. |
| CLI-side read-only guard | manta-cli |
Refuses mutating verbs locally when cli.toml has read_only = true, before any HTTP request leaves the process. Client-side accident guard only — manta-server does not enforce this; see GUIDE.md §13. |
| 0600 mode on cached tokens | manta-cli |
Token cache file written with 0600 perms under the platform config dir; never logged. |
| Control | Notes |
|---|---|
| TLS termination, WAF, reverse-proxy rate limit | First line of defence; manta-server's in-process limiter is belt-and-braces. |
| Service-account scoping at CSM / Vault | Limit what the manta-server-issued tokens can do at the backend. |
| Network segmentation | Treat manta-server as a privileged host. |
[server].migrate_backup_root set explicitly |
Confines POST /migrate/{backup,restore} paths. Server returns 400 for those endpoints when unset, even for admin callers. |
No local signature verification. manta_shared::common::jwt_ops
decodes the JWT body without verifying its signature. This is
documented inline at the top of that module. (manta-server's
server::common::jwt_ops is a re-export shim over it, kept so
existing call sites resolve — the caveat lives at the canonical
path.) Consequences:
- The
is_user_adminrole gate is advisory in the sense that a forged token passing the decode step is detected only at the first backend round-trip, where CSM/OCHAMI rejects it. - The role gate is still useful as defence in depth: it reduces the blast radius of a token whose signature does verify but whose user's permissions should be tighter than what the backend would otherwise allow.
- Local JWKS-based signature verification (per-site cache,
kid-based rotation) is the long-term direction. The role gate inherits that verification automatically when it lands; no per-gate work needed.
Single point of compromise. As noted above, owning manta-server
gives an attacker visibility into every auth attempt and access to
configured service-account tokens. Mitigations are split between
code (rate limit, generic 401, body redaction) and ops (TLS
termination upstream, service-account scoping, network segmentation).
Deferred: forwarding the original client IP to Keycloak via
X-Forwarded-For on the upstream auth call. Tracked as a follow-up
because the current AuthenticationTrait::get_api_token signature in
manta-backend-dispatcher does not take a header argument; landing
this requires a sibling-repo upgrade.
- TLS: ring (the
rustlsCryptoProvider); 1.2/1.3 perrustlsdefaults. Configure cipher suites and protocol versions at your reverse proxy if you need to constrain them further. - JWT decode:
base64::prelude::BASE64_URL_SAFE_NO_PADwith a fall-back toBASE64_STANDARD. No signature verification (see Known limitations). - Password handling: credentials submitted to
/v2/auth/tokenare deserialised intoserdetypes, forwarded to the configured backend, and dropped. They are not written to disk; they are not emitted to any log span (seestrip_body_for_logs).
- Code-quality issues that are not security-relevant — open a regular GitHub issue.
- Vulnerabilities in upstream sibling crates (
csm-rs,ochami-rs,manta-backend-dispatcher) — report directly against those repos. If you're unsure where a finding belongs, send it here and we will triage. - Vulnerabilities in the user's identity provider (Keycloak, etc.) or in the backends (CSM, OpenCHAMI) — out of manta's scope; report upstream.