# Security notes
[Feature docs index](README.md) ยท [Repository README](../../README.md)
## Protect credentials and local data
- Never commit `auth.json`, tokens, API keys, account ids, live auth output, or transcripts containing secrets. Review tool calls and output in sensitive repositories.
- Keep `settings.json` non-secret. Use environment references for sensitive MCP HTTP headers and store MCP OAuth tokens under `$MC_HOME/mcp-tokens/<server>.json`.
- Use provider-keyed auth: Codex requires OAuth; Anthropic uses `ANTHROPIC_API_KEY` or the `anthropic` API-key record. OpenAI keys are not substitutes for either.
- Prefer environment variables for short-lived tests and private `auth.json` for longer-lived use. On Unix, it must be owner-only (`0600` or stricter); CLI writes use `0600` and reject symlinked auth files before parsing.
- Provider credentials authenticate assistant transport only, never Cargo, Git, or GitHub. Cargo installation uses Cargo's own authentication and is not performed by magi-code.
- `web` reads `EXA_API_KEY` only from the process environment, not settings/auth files or other provider keys.
- Set `MC_HOME` to isolate test config/state; otherwise files live under `~/.magi-code`. To inspect broad legacy session permissions, run `magi-code sessions repair-permissions --dry-run`. The repair never follows links or recurses and fails closed on unsafe layouts. See [Troubleshooting](troubleshooting.md#session-context-and-skill-problems).
Codex refreshes OAuth before applicable use, performs network exchange outside auth locks, and rejects stale/competing refresh writes. Provider generations survive logout. See [Provider authentication](provider-authentication.md).
MCP names must be `mcp__<server>__<tool>`, at most 64 UTF-8 bytes total. Both components must be non-empty ASCII letters, digits, `_`, or `-`, without `__`. Server ids cannot end in `_`; tool names may. See [MCP tools](mcp-stdio-tools.md).
## Understand tool boundaries
`bash`/`shell` guardrails are not OS-level isolation. Sandbox hostile repositories or untrusted prompts separately. File containment checks also do not prevent every filesystem race; see [Tools and safety](tools-and-safety.md#safety-boundaries).
`read` URL resources accept only public HTTP(S): no auth, custom headers, cookies, bodies, redirects, JavaScript, or local/private destinations. Downloads are capped at 512 KiB and redacted output at 48 KiB. Resolved private, loopback, link-local, unspecified, and multicast IPs are rejected before network access; validated DNS addresses are pinned.
`web` sends public research queries and validated public URLs to Exa. It rejects URL credentials and resolved private addresses, bounds responses, and redacts results. Exa controls page fetching; unlike direct `read`, this does not pin Exa's DNS or redirect behavior. Cached open/find make no network requests. The removed browser/ax bridges no longer run subprocesses.
## Subprocess environment boundaries
The profiled child processes below use explicit deny-by-default environment profiles rather than inheriting all ambient variables. Credential-shaped ambient variables are excluded from every profile. The ambient user shell is the intentional exception.
| Ambient user shell (`bash` / `shell`) | On Unix, inherits the full ambient environment and invokes `/bin/bash -lc`. On Windows, it uses PowerShell (`pwsh`, then `powershell.exe`) with `-NoProfile -NonInteractive -Command`. It has no OS-level sandbox. |
| Sanitized hooks | On Unix, invokes `/bin/bash --noprofile --norc -c`. On Windows, it uses PowerShell (`pwsh`, then `powershell.exe`) with `-NoProfile -NonInteractive -Command`. Both use the Shell profile: `PATH`, `HOME`, `USER`, `LOGNAME`, `SHELL`, `TMPDIR`, `LANG`, and the exact locale list below, plus the Windows startup baseline on Windows. |
| Ast-grep | `PATH`, `HOME`, `TMPDIR`, `LANG`, the exact locale list below, plus the Windows startup baseline on Windows. |
| LSP | `PATH` only. |
| MCP stdio | `PATH` plus the Windows startup baseline on Windows, then the explicit configured MCP `env` overlay. |
For Shell and Ast-grep, the locale entries are exactly `LC_CTYPE`, `LC_NUMERIC`, `LC_TIME`, `LC_COLLATE`, `LC_MONETARY`, `LC_MESSAGES`, `LC_PAPER`, `LC_NAME`, `LC_ADDRESS`, `LC_TELEPHONE`, `LC_MEASUREMENT`, `LC_IDENTIFICATION`, and `LC_ALL`; no other `LC_*` variables are included. The Windows startup baseline is exactly `ComSpec`, `PATHEXT`, `SystemRoot`, and `WINDIR`, where the profile includes it. These are environment controls, not OS-level sandboxing.