Security · Architecture
Designing the permission model for a coding agent
In build 1.15.9, a task that had already run a shell command refused to accept an elevation to Full access. The access menu closed without a message, and the level appeared stuck at its previous value.
Last updated
The defect was reported as a stuck setting. It was not. The persistent shell belonging to the task had been opened under the earlier access level, and granting a new one would have left a process running with permissions that no longer matched the configuration.
ClearFrame now closes the task's persistent shell before applying the change. The release note for 1.15.9 states the resulting behaviour: the level selected is the level that applies, "and a switch that is still refused tells you why instead of closing silently."
The repair is the visible part of a permission model that is mostly invisible until it is tested. The model itself has three levels.
Three levels
The application names them for what they permit. The descriptions below are its own.
| Level | Scope |
|---|---|
| Read only | The task can inspect the project and cannot modify it. |
| Workspace access | Changes are confined to the project folder. The default for ordinary work. |
| Full access | The task can read and change files available to the macOS user account. |
Elevation is requested in a dialog rather than configured in advance. The dialog states the consequence in the same words used to name the level — that the task can read and change files available to the user account — so the decision is made against a description of its scope rather than a label.
A global preference set before the task begins would move that decision to the moment when the least is known about what the task will need.
Why long-lived processes complicate permissions
Most permission models assume the unit of work is a command. That assumption fails once a task keeps a shell session alive across turns, which is what allows an agent to remain in the correct directory, retain an environment and hold a long-running process.
A process that outlives the decision that created it carries the old decision with it. Any tool that supports both persistent shells and mid-task permission changes has to decide what happens to that process. Closing it keeps the displayed setting and the running reality in agreement.
The second half of the repair
Closing the shell was one change. The other was making the refusal audible. A control that declines an action and reports nothing is indistinguishable, from the user's side, from a control that is broken. The 1.15.9 note records both: the level applies, and a switch that is still refused explains itself.
What the levels do not claim
They bound the scope of a task. They are not a sandbox against hostile code: a task with workspace access runs as the user. ClearFrame does not present access levels as a security certification, and the security page states what is claimed, including the absence of any third-party certification.
Remote execution is a separate boundary. Where it is used, it runs in a separate workspace, and local files are not uploaded automatically.
What Full access permits, exactly
The dialog does not describe Full access as unlimited. It states that the task can read and change files available to the macOS user account, which is a boundary with a definition rather than an absence of one. Files owned by another user, protected by system integrity protection, or reachable only with elevated privileges remain out of reach.
The distinction matters when reading the level name. "Full" describes the scope the application can offer, not the machine. A reader who takes it to mean root privileges will misjudge the risk in both directions: expecting more capability than exists, and less caution than the level warrants.
Why the default is the middle level
Workspace access is the default for a reason that is about the shape of agent work rather than about caution. Nearly all coding tasks read and write files inside one project. A default of Read only would require an elevation prompt for the first legitimate write of every task, and a prompt that appears every time is a prompt that gets dismissed without reading.
A default of Full access would remove the prompt entirely and leave the scope undisclosed. The middle level keeps the prompt meaningful: it appears when a task genuinely needs to reach outside the project, which is the moment a person should think about it.
The elevation record
Because elevation happens mid-task, it has to be visible after the fact. A reviewer reading a change set needs to know which access level the task was running at when it produced them, since a change that reaches outside the project is consistent with Full access and inconsistent with Workspace access. A diff on its own does not carry that context.
Why the fix took the shape it did
The alternative to closing the persistent shell would have been to keep it running and treat the new level as applying only to subsequent commands. That is defensible in a diagram and wrong in practice, because the shell retains the environment and working directory it was opened with, and a command issued after the change would still run against the old context. Closing the shell makes the setting true rather than approximately true.
Related reading
Choosing an access level, in the documentation. The defect and its resolution are recorded in the 1.15.9 release note, and the boundary of what the product claims is set out at Security.