Permissions#
PacketCode evaluates every built-in and MCP tool against a permission profile. The result is allow, ask or deny. Ordered rules can narrow the decision for a specific tool or command prefix.
Before you start#
- The project is under version control.
- You understand which files and commands the task requires.
- Important credentials are not exposed to the process unnecessarily.
Profile and rule example#
A [permissions.profiles.<name>] table defines a custom profile, and
[permissions] profile selects it by name. The name must not be a built-in
profile or one of its aliases — balanced, ask, read_only, accept_edits,
auto, full and the rest — because a built-in name resolves to the built-in
profile and the table beside it is then ignored without a warning.
[permissions]
profile = "reviewed"
[permissions.profiles.reviewed]
default = "ask"
read_file = "allow"
search_codebase = "allow"
list_directory = "allow"
write_file = "ask"
patch_file = "ask"
execute_command = "ask"
spawn_agent = "ask"
mcp = "ask"
[[permissions.rules]]
tool = "execute_command"
action = "deny"
command_prefix = ["rm"]
reason = "refuse deletes from the agent"
To run a built-in profile instead, set profile = "balanced" and omit the
profiles table. Ordered rules apply either way.
Use deny rules as a floor for actions that should never be approved. A prompt approval is scoped to the option shown; do not interpret it as proof that the command is safe.
How the deny floor is applied#
A deny rule whose prefix is written from plain command words is checked on every allow, including an allow that came from a session grant or a skill's allowed-tools list. Such a deny is not weakened by a later allow.
The comparison sees through shell quoting, so "git" push matches a git push
deny. When the command reaches the denied program indirectly — sh -c, sudo,
xargs or a scripting interpreter such as python -c — or when an option makes
the match impossible to settle from the command string alone, as in
git -C . push, the decision escalates to an approval prompt instead of an
allow. A floor that cannot be evaluated does not read as "not denied".
Warning: write every deny prefix from plain command words. Options in the
command under test are skipped while it is compared against the prefix, so a
prefix that carries an option of its own — ["rm", "-rf"], for example — never
matches the command as typed, and a later session or skill allow then lets it
run. Indirect forms such as sh -c still escalate, but the direct command does
not. Use ["rm"], which covers every rm invocation including rm -rf.
Files PacketCode will not read#
read_file, search_codebase and @-mention expansion refuse dotenv secret
files: .env and any .env.<suffix>. The example spellings .env.example,
.env.sample, .env.template and .env.dist are exempt. PacketCode reads
provider keys from the project .env and the data home's .env itself, so
inlining one of those files would copy credentials into the transcript, the
stored session and every later provider request.
This is a name rule, not a sandbox. execute_command is unchanged and a shell
can still read any file the account can, which is why that tool is
approval-gated and shows the command before it runs.
Clients connected over ACP#
When a client connects to packetcode acp, the permission modes the server
advertises are capped at the profile the server itself runs. A client may narrow
its session but never widen it. The default balanced profile and any custom
profile both resolve to ask, so such a server offers only ask and read-only.
Raising the ceiling means raising what the server itself enforces. A configured
profile of bypass, full or trusted, or starting the server with
packetcode acp --permission-mode bypass, offers the full range;
accept-edits and auto raise it part of the way. Setting trust_mode under
[behavior] is the only option that raises the ceiling without naming a
profile, because it raises the policy to full on its own.
Verify#
- Start a session in a disposable repository.
- Request a file read and confirm it proceeds under the profile.
- Request a harmless file edit and confirm an approval appears.
- Request a command matched by a deny rule and confirm it does not run.
- Request the same command through
sh -cand confirm it is denied or asked, never allowed. - Ask for a
.envfile to be read and confirm the tool refuses it. - Inspect Git status to verify no unapproved change occurred.
The policy limits PacketCode's decisions, not the authority of the operating system account. Run untrusted projects in an appropriate external sandbox.
If it does not work#
| Symptom | Check | Recovery |
|---|---|---|
| An allowed action is still refused | Whether a deny rule applies — deny is a floor | An explicit deny is not weakened by a later allow |
| A file you expect to be readable is refused | Whether it is on the never-read list | See A file read is refused |
| An ACP client is refused a session | The client's own permissions, not the profile | See An ACP client is refused a session |
| A rule appears to have no effect | Whether the profile is the active one | Do not widen the policy to make an error stop — confirm which profile is loaded first |