---
title: "Security Model"
type: concept
tags: [security, self-hosting, operator, advanced, well-established]
created: 2026-08-10
updated: 2026-08-10
sources: ["raw/github_doc-apps-docs-content-docs-security-model-mdx.md"]
confidence: high
multica_version: "v0.4.22"
---

## Definition

Multica's security model is defined by a single fact: when an agent picks up a task, the daemon spawns an AI coding tool (Codex, Claude Code, and so on) as a child process that runs with the **full permissions of the operating-system user running the daemon**. Multica makes no filesystem-sandbox guarantee — the real isolation boundary has to be placed *around* the daemon, not expected *from* Multica itself (raw/github_doc-apps-docs-content-docs-security-model-mdx.md).

## How It Works

**The boundary is the daemon's OS user.** A task can read and write every file that user can, use that user's credentials, and reach the network without restriction. This is a deliberate design choice, not an oversight: agents are asked to install dependencies, run builds, drive cloud CLIs, and use tooling that expects a normal home directory. A partial filesystem sandbox breaks that work in hard-to-diagnose ways (the tool silently reports "not logged in" or uses the wrong account) while not actually protecting the thing that matters most — it cannot stop a task from reading credentials and exfiltrating them over the network.

**Recommended isolation setups**, lightest to strongest: (1) a dedicated Unix `multica` user scoped only to the repos/credentials agents need; (2) a container with only the necessary mounts and secrets; (3) a full virtual machine. Whichever is chosen, every credential reachable from that environment should be treated as a credential the agent may use — scope tokens narrowly and prefer per-purpose deploy keys over a personal SSH key.

**What Multica *does* isolate** (blast-radius reduction, not a security boundary against an actively escaping task):
- Per-task working directory under `~/multica_workspaces/`, so concurrent tasks don't collide on the same checkout.
- Per-task agent state — Codex tasks get a task-scoped `CODEX_HOME` for config/sessions/skills, keeping per-task settings out of `~/.codex/`.
- Task-scoped API tokens — the `mat_`-prefixed `MULTICA_TOKEN` handed to a task is bound to that agent and task by the server, so it cannot act as the user or as another agent (see [[concepts/auth-and-tokens]]).

**What is explicitly *not* a boundary.** Multica runs agents unattended, so tool-native approval prompts are answered automatically, and the filesystem sandbox is off on the default path: Codex runs with `sandbox_mode = "danger-full-access"` and Claude Code with `--permission-mode bypassPermissions`. The one narrow exception is Windows, where a user has explicitly opted into Codex's native sandbox (`windows.sandbox = "unelevated"` or `"elevated"`) — Multica honors that and keeps `workspace-write` for those tasks, but which platform/tool/version combinations sandbox anything at all is a compatibility detail that shifts over time, so every task should be treated as unsandboxed by default. Tasks also inherit the daemon user's real `HOME` and `XDG_*` variables — this is what lets host CLIs like `gh`, `aws`, `kubectl`, and `gcloud` work inside a task exactly as in a normal shell, but it also means everything under that home is reachable. Linux previously ran Codex tasks under a `workspace-write` sandbox with a redirected per-task `HOME`; that was removed because it left host CLIs unconfigured inside tasks and, since it only restricted writes, never stopped a task from reading and exfiltrating credentials. Linux now matches the macOS and Windows default.

**Checking what a task actually ran with.** The daemon logs the effective sandbox mode at warn level whenever a task starts unsandboxed:

```bash
multica daemon logs --lines 200 | grep "codex sandbox"
```

To confirm the effective Codex configuration for a specific task, read the managed block inside that task's `config.toml` under its `CODEX_HOME` — the section between `# BEGIN multica-managed` and `# END multica-managed` is written by the daemon on every run.

## Key Parameters

- The isolation boundary = the OS user (or container/VM) the daemon runs as — not anything Multica configures internally.
- Codex default: `sandbox_mode = "danger-full-access"`; Claude Code default: `--permission-mode bypassPermissions`.
- Windows-only opt-in exception: `windows.sandbox = "unelevated"` or `"elevated"` keeps `workspace-write` for Codex tasks.
- Per-task working directory root: `~/multica_workspaces/` (configurable via `MULTICA_WORKSPACES_ROOT`, see [[concepts/configuration]]).
- Per-task `CODEX_HOME` isolates Codex config/sessions/skills per task.
- `MULTICA_TOKEN` for a run is a task-, agent-, and workspace-scoped `mat_` token, not the user's own PAT.

## When To Use

Read this before running the self-host daemon under your own personal user account (see [[concepts/self-hosting]]) — the recommended pattern is always a dedicated `multica` Unix user, a container, or a VM, chosen by how strong an isolation guarantee your infrastructure needs versus how much provisioning effort you can afford. Use the `codex sandbox` log grep whenever you need to audit or prove what sandbox mode a specific run actually used, e.g. during a security review or incident investigation.

## Risks & Pitfalls

- If the daemon runs as a personal user account, a task can read SSH keys, edit shell profiles, and delete documents — Multica will not stop it (raw/github_doc-apps-docs-content-docs-security-model-mdx.md).
- Do not assume the coding tool's own sandbox/approval settings provide protection in Multica's unattended context — approvals are auto-answered and the filesystem sandbox is off by default on every platform except the Windows opt-in case.
- Do not assume Linux still gets the old `workspace-write` + redirected-`HOME` treatment — that protection was removed because it broke host CLI usage without actually stopping credential exfiltration; Linux now behaves like macOS and Windows (unsandboxed by default).
- Per-task working directories, per-task `CODEX_HOME`, and task-scoped tokens are conveniences for avoiding accidental collisions between concurrent tasks — they are explicitly *not* protection against a task that is actively trying to escape or exfiltrate data.
- Treat every credential reachable from the daemon's environment (its `HOME`, its cloud CLI logins, its SSH agent) as a credential an agent may use; scope tokens and deploy keys accordingly rather than reusing broad personal credentials.

## Related Concepts

- [[concepts/self-hosting]] — where the daemon is provisioned and where isolation choices (dedicated user, container, VM) are actually made.
- [[concepts/auth-and-tokens]] — the task-scoped `mat_` token referenced above.
- [[concepts/members-and-roles]] — why workspace role (`owner`/`admin`/`member`) is a separate axis from what a task on disk can reach.
- [[concepts/configuration]] — `MULTICA_WORKSPACES_ROOT` and other daemon-side environment variables mentioned here.

## Sources

- raw/github_doc-apps-docs-content-docs-security-model-mdx.md
