Permission profiles
Three built-in profiles decide how wide the boundary is. This lesson runs all three and watches the difference.
| Profile | What the documentation says |
|---|---|
:read-only | Keeps local command execution read-only |
:workspace | Allows writes inside the active workspace roots and the system temp directories |
:danger-full-access | Removes local sandbox restrictions, for when that breadth is intentional |
Read only
codex sandbox -P :read-only -- python3 -c "open('a.txt','w').write('x')"PermissionError: [Errno 1] Operation not permitted: 'a.txt'
The same refusal as lesson 3, now asked for by name.
Workspace
codex sandbox -P :workspace -- python3 -c "open('a.txt','w').write('x'); print('wrote a.txt')"wrote a.txt
The write went through, because the file is inside the workspace. This is the profile most real work happens in: the agent can edit your project and run your tests without asking, and cannot touch the rest of the machine.
The part people miss
Workspace is described in terms of writes, so it is easy to assume the network is included. It is not.
codex sandbox -P :workspace -- python3 -c "import urllib.request; print(urllib.request.urlopen('https://example.com').status)"urllib.error.URLError: <urlopen error [Errno 8] nodename nor servname provided, or not known>
Not a refusal message, a DNS failure: from inside the sandbox the name does not resolve. A test suite that fetches something, or an install that reaches a registry, fails like this. Knowing the shape of that error saves an hour.
Full access
codex sandbox -P :danger-full-access -- python3 -c "import urllib.request; print('status', urllib.request.urlopen('https://example.com').status)"status 200
codex sandbox -P :danger-full-access -- python3 -c "open('/tmp/outside.txt','w').write('ok'); print('wrote /tmp/outside.txt')"wrote /tmp/outside.txt
Both limits gone in the same profile: the network answers and a file outside the project is written. The name is doing its job, and the two runs above are what it means in practice.
Choosing
| Situation | Profile |
|---|---|
| Reading an unfamiliar repository | :read-only |
| Normal work in a repository you own | :workspace |
| An install or a test suite that genuinely needs the network | Widen deliberately, for that run |
| Anything you cannot describe | Not full access |
You can also write your own profile under [permissions.<name>] in the config file and make it the default, which is lesson 13. An organisation can restrict which profiles are even selectable.
- Run your project's test suite under
:workspaceand see whether it needs the network. - Find the one command in your workflow that genuinely needs to leave the sandbox. Lesson 7 is about that.
This is what real progress feels like.