*magenta-permissions.txt*        Sandbox Permissions Configuration      *magenta-permissions*

                            MAGENTA PERMISSIONS
                  Updating Sandbox Permissions Configuration

==============================================================================
CONTENTS                                            *magenta-permissions-contents*

    1. Overview ................................ |magenta-permissions-overview|
    2. How Sandboxing Works .................... |magenta-permissions-how|
    3. Configuration Locations ................ |magenta-permissions-locations|
    4. Sandbox Config Structure ............... |magenta-permissions-structure|
    5. Configuration Fields ................... |magenta-permissions-fields|
    6. Path Matching ........................... |magenta-permissions-matching|
    7. Path Resolution ......................... |magenta-permissions-resolution|
    8. How to Update Permissions .............. |magenta-permissions-update|
    9. Common Scenarios ........................ |magenta-permissions-scenarios|
   10. Merging Behavior ........................ |magenta-permissions-merging|

==============================================================================
OVERVIEW                                            *magenta-permissions-overview*

This guide helps you update magenta's sandbox configuration when
encountering sandbox violations.

==============================================================================
HOW SANDBOXING WORKS                                 *magenta-permissions-how*

Magenta uses OS-level sandboxing (via @anthropic-ai/sandbox-runtime) to
constrain shell commands. The sandbox:
  - Shell commands run inside a macOS sandbox that restricts filesystem and
    network access
  - File IO uses application-level checks against the sandbox config as the
    single source of truth
  - When sandbox is unavailable (unsupported platform, missing deps), all
    shell commands and file writes prompt the user for approval

==============================================================================
CONFIGURATION LOCATIONS                          *magenta-permissions-locations*

Project-level: `.magenta/options.json` in the project root
User-level: `~/.magenta/options.json` in the home directory

User-level settings apply across all projects. Project-level settings are
merged with user-level (arrays concatenate, enabled overwrites).

==============================================================================
SANDBOX CONFIG STRUCTURE                          *magenta-permissions-structure*

The sandbox configuration is defined in a JSON file with the following
structure:~
>json
  {
    "sandbox": {
      "filesystem": {
        "allowWrite": ["./"],
        "denyWrite": [".env", ".git/hooks/"],
        "denyRead": ["~/.ssh", "~/.gnupg", "~/.aws", "~/.bashrc", "~/.zshrc"],
        "allowRead": ["~/.magenta", "~/.claude"]
      },
      "network": {
        "allowedDomains": ["registry.npmjs.org", "github.com", "*.github.com"],
        "deniedDomains": []
      },
      "requireApprovalPatterns": ["git\\s+push", "rm\\s+-rf"],
      "bwrapSandboxViolationPatterns": ["CredentialsProviderError"]
    }
  }
<

==============================================================================
CONFIGURATION FIELDS                              *magenta-permissions-fields*

filesystem.allowWrite~
    Paths where writing is allowed. Default: ["./"] (current working
    directory).

filesystem.denyWrite~
    Paths within allowed areas where writing is denied.
    Default: [".env", ".git/hooks/"].

filesystem.denyRead~
    Paths where reading is denied. Default includes explicit literal paths
    for credentials (~/.ssh, ~/.aws, ~/.gnupg, etc.) and shell configs
    (~/.bashrc, ~/.zshrc, etc.). Literal paths use subpath matching.

filesystem.allowRead~
    Paths to re-allow reading within denied regions.
    Default: ["~/.magenta", "~/.claude"]. Takes precedence over denyRead.

network.allowedDomains~
    Domains that commands can access. Supports wildcards
    (e.g., "*.github.com").

network.deniedDomains~
    Domains that are explicitly blocked.

requireApprovalPatterns~
    Regex patterns that trigger an approval prompt before the command runs.
    If a command matches any pattern, the user is prompted to approve it
    before execution — the command is never sandboxed. This prevents partial
    execution of compound commands (e.g., git commit && git push where git
    commit runs before the sandbox blocks git push). Default: [].

bwrapSandboxViolationPatterns~
    (Linux only) Regex patterns matched against stderr lines to detect
    sandbox violations caused by bubblewrap. When a sandboxed command fails
    and stderr matches any pattern, the user is prompted to retry without
    the sandbox. Default: ["Permission denied", "EPERM",
    "Operation not permitted", "Read-only file system", "EROFS", "EACCES",
    "CredentialsProviderError"]. User and project patterns concatenate
    with the defaults.

==============================================================================
PATH MATCHING                                      *magenta-permissions-matching*

There are two matching modes depending on whether a path contains glob
characters (*, ?, [):

Literal paths (e.g., ~/.ssh)~
    Use subpath matching — blocks the path itself AND everything under it.
    So ~/.ssh blocks ~/.ssh, ~/.ssh/id_rsa, ~/.ssh/keys/foo, etc.

Glob patterns (e.g., ~/.*)~
    Use regex matching where * matches any characters except / (single
    directory level) and ** matches across directory boundaries. So ~/.* 
    blocks ~/.ssh and ~/.bashrc but NOT ~/.ssh/id_rsa.

Important: The defaults use explicit literal paths for known sensitive
locations (credentials, shell configs). Literal paths provide subpath
matching which blocks the directory and everything under it. Review the
defaults and add any project-specific sensitive paths your environment
requires.

==============================================================================
PATH RESOLUTION                                  *magenta-permissions-resolution*

~/ expands to the user's home directory
./ expands to the current working directory
Relative paths are resolved relative to the current working directory
Absolute paths are used as-is

==============================================================================
HOW TO UPDATE PERMISSIONS                         *magenta-permissions-update*

1. Read the existing options file (project or user level, as appropriate)
2. Add or merge the new sandbox entries
3. Write the updated JSON back to the file

If the file doesn't exist, create it with just the sandbox key.

==============================================================================
COMMON SCENARIOS                                 *magenta-permissions-scenarios*

Sandbox blocked a network request~
    Add the domain to network.allowedDomains:
>json
    {
      "sandbox": {
        "network": {
          "allowedDomains": ["registry.npmjs.org"]
        }
      }
    }
<

Sandbox blocked writing to a path~
    Add the path to filesystem.allowWrite:
>json
    {
      "sandbox": {
        "filesystem": {
          "allowWrite": ["/tmp/build"]
        }
      }
    }
<

Sandbox blocked reading a config file~
    Add the path to filesystem.allowRead:
>json
    {
      "sandbox": {
        "filesystem": {
          "allowRead": ["~/.config/myapp"]
        }
      }
    }
<

    Note: Since project settings merge by concatenating arrays, you cannot
    remove a user-level deny from project settings. Instead, update the
    user-level config directly.

Command should always require approval~
    Add a regex pattern to requireApprovalPatterns:
>json
    {
      "sandbox": {
        "requireApprovalPatterns": ["git\\s+push", "rm\\s+-rf"]
      }
    }
<

    This prompts for approval before running the command — no sandboxed
    execution occurs first.

Sandbox violation detection on Linux (bwrap)~
    On macOS, the seatbelt sandbox provides a built-in violation log that
    reports exactly which operations were blocked and why. On Linux,
    bubblewrap (bwrap) works differently — it creates isolated filesystem
    namespaces where restricted paths simply do not exist. The sandboxed
    process sees ordinary ENOENT or EPERM errors indistinguishable from
    normal failures, and bwrap provides no violation reporting mechanism.

    To detect sandbox-caused failures on Linux, magenta matches stderr
    output against configurable regex patterns. When a sandboxed command
    fails and stderr matches any pattern, the user is prompted to approve
    retrying the command without the sandbox. The default patterns cover
    common permission errors (EPERM, EACCES, "Permission denied", etc.).

    If a sandboxed command fails due to a missing resource and the error
    message does not match any default pattern, add a pattern:
>json
    {
      "sandbox": {
        "bwrapSandboxViolationPatterns": ["MyCustomError"]
      }
    }
<
    Patterns are JavaScript regex strings tested against each stderr line.
    Project and user patterns concatenate with the built-in defaults.

==============================================================================
MERGING BEHAVIOR                                  *magenta-permissions-merging*

When project settings are merged with user settings:

Arrays concatenate~
    Project allowWrite is appended to user allowWrite, project denyRead is
    appended to user denyRead, and project allowRead is appended to user
    allowRead.

denyRead always includes defaults~
    The mandatory defaults (~/.ssh, ~/.gnupg, ~/.aws, shell configs, etc.)
    are always enforced; user config can only add more deny rules, never
    remove them.

allowRead takes precedence~
    If a path appears in both denyRead and allowRead, the allow rule wins.

vim:tw=78:ts=8:noet:ft=help:norl:
