Maia security policy
Status: pre-release. Only the current main revision receives security fixes;
source-candidate and canary packages carry no production support claim.
Reporting
Do not disclose a suspected vulnerability, credential, transcript, artifact or exploit in a public issue or discussion.
Repository collaborators create a private draft advisory under the Maia repository's Security -> Advisories. Include the affected revision and component, prerequisites, exact reproduction, impact, evidence with secrets removed and any suggested mitigation. If the advisory channel is unavailable, contact a repository owner through an existing private channel and ask only for a secure reporting path until one is provided.
The first response target is three business days. Triage assigns severity, affected versions and identities, containment owner, evidence hold, rotation needs, fix and validation owners, and the disclosure decision. A response target is not a remediation guarantee.
Supported scope
In scope today: the local Maia Node, the maia CLI and its maia mcp server,
the Desktop app built from source, and Codex CLI and Claude Code executor
workers. Not yet supported or qualified: remote Node access and enrollment,
A2A ingress, external MCP ingress, telemetry export, voice tool proposals and
any deployment beyond loopback. Do not expose a Node outside 127.0.0.1.
Guarantees today
- Loopback only. The Node listens on
127.0.0.1, checks the exact Host, rejects browser-origin requests and authenticates a bearer token before reading a request body. The token sits in an owner-only (0600) file in an owner-only (0700) profile directory and changes at every restart. - Credentials. Model-provider credentials live in
$MAIA_HOME/auth.json; the Node accepts that file only as an owner-only regular file (0600, no symbolic link, one hard link). Worker-account credentials stay in the vendor CLI's own config root; Maia never reads them.maia loginnever accepts an API key as a command argument. - Workers. Executor Sessions run only a human-approved executable whose path and SHA-256 were recorded. A reading worker reads its worktree: Codex under Maia's read-only permission profile, Claude Code with Read, Grep and Glob. A coding worker also edits files and runs commands: Codex under Maia's write profile, which adds write grants for the worktree and its own cache; Claude Code with Edit, Write, NotebookEdit and Bash. Claude's Bash runs only inside Claude's sandbox (unsandboxed commands refused, home and Node private root unreadable); a guard checks the paths of Claude's file tools, and a path outside the worktree needs a person's yes (Git metadata never). Worker commands get no network. Neither harness loads user MCP servers or, for Claude Code, settings and hooks; a coding worker gets only Maia's worker MCP, which runs outside the tool sandbox with the Session credential. Reading workers never ask for approval. A coding Claude worker asks a person about paths outside its worktree and its questions; a coding Codex worker asks only questions, and Codex refuses escalations itself. On Linux, workers run under the cgroup v2 process host with Landlock, and launch fails closed without it; a Codex tree keeps Landlock's scoping but not its filesystem rules, which Codex's own bubblewrap sandbox replaces for the commands it runs; the app-server, the worker MCP server and anything Codex runs outside bubblewrap are trusted not to touch the cgroups of their own or other trees (D-110).
- Coordinator surface.
maia mcpexposes no account changes, executable approval, confirmations or interaction answers. Of the human-only operations it exposes onlyturn.send, andapproval_respond, which the Node refuses unless a person granted the Project's coordinators the answer (D-199, default none;MAIA_NODE_HEADLESS_APPROVALS=offignores every grant). The coordinator mark is self-asserted, so the grant constrains only correctly identified requests. - Mutations. Connection and integration changes require an authenticated operator without an Invocation attachment, an expected revision or command ID, and a receipt.
- Voice. Maia stores no raw audio. The renderer gets a 60-second Gateway client token, never the Gateway key.
Known limits
- No managed secret store yet (secrets):
auth.jsonis plain JSON protected by file mode; on macOS the Pi RPC worker path writes a per-Session copy of a leased OAuth credential that is not removed afterwards;maia agent loginwritesauth.jsonwithout Maia's key checks; Desktop voice readsAI_GATEWAY_API_KEYfrom its environment orauth.jsonwithout the Node's file checks. - Claude's file tools run in the Claude process, outside its sandbox: a link
swapped in between the guard's check and the write can escape the
worktree. Claude's Bash reads are a deny list, so
/tmp,/optand/srvstay readable; Codex's reads are an allow list that also covers a few system paths (vendor executors). - Containment bounds a worker's process tree, not its OS user. Separate prompts, Sessions, processes or worktrees are not full isolation between coordinator owners (Node isolation).
- Session-bound worker credentials and guards (S18) and holds of one exact
Project or account (S20) are source candidates, not qualified releases. Node
and capability holds,
capability.revokeand remote authentication (MN0–MN1) are planned, not built. - Not yet built for enterprise use: SSO, MFA and multiple users; a tamper-evident audit log; encryption at rest; signed releases and updates; a public reporting channel. The enterprise readiness plan lists every gap.
The threat boundaries, secret handling, kill switches, backup and incident runbooks are in operations; credentials and sign-in are in providers.
Handling a report
- Preserve immutable evidence and suspend destructive retention for the exact affected scope.
- Revoke the exact Connection, peer, device, Node, Project or capability; never use an unresolved broad target.
- Fence active assignments and reconcile in-flight external effects before retrying work.
- Rotate compromised credentials and keys through their owning backend; never copy old secrets into diagnostic files.
- Reproduce on an isolated fixture, add a failing test at the lowest useful boundary, make the smallest fix and run the affected fault and contract tests.
- Validate recovery and rollback before restoring the capability.
- Disclose only after affected users can remediate.
Out of scope
Reports that rely only on a documented pre-release non-goal are not vulnerabilities unless they show a boundary escape, authority bypass, secret exposure, cross-scope access, evidence loss or a misleading security claim. Social engineering, denial of service against third-party providers, and testing infrastructure the reporter does not own or is not authorized to test are prohibited.
Imported from Maia OS docs at a2175bb