Aller au contenu

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 login never 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 mcp exposes no account changes, executable approval, confirmations or interaction answers. Of the human-only operations it exposes only turn.send, and approval_respond, which the Node refuses unless a person granted the Project's coordinators the answer (D-199, default none; MAIA_NODE_HEADLESS_APPROVALS=off ignores 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.json is 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 login writes auth.json without Maia's key checks; Desktop voice reads AI_GATEWAY_API_KEY from its environment or auth.json without 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, /opt and /srv stay 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.revoke and 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

  1. Preserve immutable evidence and suspend destructive retention for the exact affected scope.
  2. Revoke the exact Connection, peer, device, Node, Project or capability; never use an unresolved broad target.
  3. Fence active assignments and reconcile in-flight external effects before retrying work.
  4. Rotate compromised credentials and keys through their owning backend; never copy old secrets into diagnostic files.
  5. 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.
  6. Validate recovery and rollback before restoring the capability.
  7. 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