Grant writes with policy overlays¶
A policy overlay is a small YAML fragment of network_policies that is
composed with a running sandbox's policy and pushed to it with
openshell policy set. Overlays make one extra capability active for one
sandbox, without editing the baseline policy and without recreating the
sandbox.
Use an overlay when the baseline's read-only grants are not enough for the task at hand, for example to let an agent open a pull request or push a branch. The baseline policy and the source-control provider profiles deliberately permit API reads, clone, and fetch only; see GitHub and GitLab.
Overlays change only network_policies. Filesystem, Landlock, and process
settings always come from the live sandbox, because they become static once the
sandbox starts. Changing those still requires a new sandbox with an edited
policy.
Available overlays¶
Each file under policy-overlays/ grants one capability, so capabilities can be
granted and revoked independently:
| Overlay | Grants | Does not grant |
|---|---|---|
github-issues-prs.yaml |
GraphQL and gh api REST writes for issues, comments, pull requests, reviews, labels, assignees |
Merges, auto-merge, REST DELETE, destructive mutations, git push |
github-push.yaml |
HTTPS git push to github.com |
GitHub API writes |
github-graphql-audit.yaml |
Debugging only: switches the GitHub GraphQL entry to audit so blocked operations appear in the logs |
Anything intended for routine use |
gitlab-com-issues-mrs.yaml |
glab REST writes for issues, notes, merge requests, and MR notes on gitlab.com |
GraphQL mutations, deletes, approvals, merges, push |
gitlab-com-push.yaml |
HTTPS git push to gitlab.com |
Issue or MR authorship |
ubuntu-updates.yaml |
APT reads from archive.ubuntu.com and security.ubuntu.com |
Filesystem permissions needed to install packages |
github-issues-prs.yaml scopes its REST endpoint to gh, so use gh api
rather than curl for those writes.
Apply and revert¶
The helper needs openshell, python3, and PyYAML on the gateway host. Launch
the sandbox with --keep so it outlives the agent, look up the name OpenShell
assigned to it, then apply overlays from your ExOShell checkout:
./run-exoshell-agent.sh --keep --policy policies/policy.yaml /path/to/project
openshell sandbox list --selector managed-by=exoshell
# Enable GitHub issue and PR writes.
./policy-overlays/apply.py --sandbox <sandbox-name> github-issues-prs.yaml
# Combine independent capabilities.
./policy-overlays/apply.py --sandbox <sandbox-name> github-issues-prs.yaml github-push.yaml
# Inspect the live-to-final change without applying it.
./policy-overlays/apply.py --sandbox <sandbox-name> --dry-run github-issues-prs.yaml
# Restore this sandbox's recorded baseline and remove every active overlay.
./policy-overlays/apply.py --sandbox <sandbox-name> --revert
# Start from the baseline, then enable exactly the named capability.
./policy-overlays/apply.py --sandbox <sandbox-name> --revert github-issues-prs.yaml
Bare names are looked up in policy-overlays/ and the .yaml suffix is
optional. Applying the same overlay twice is idempotent. Delete the retained
sandbox when the work is finished; overlays live only as long as it does.
An overlay widens what the agent can do
A granted capability stays active for the whole session, for every command
the agent runs. Grant the narrowest overlay that unblocks the task, prefer
--dry-run first, and revert when the task is done.
Where --revert finds the baseline¶
--revert reads network_policies from an explicit --base-file, or otherwise
from the sandbox annotation exoshell.policy-source-file. The launcher records
the resolved absolute policy path there when it creates a sandbox with a
selected policy, so revert works from any working directory. It reads the file's
current contents rather than a creation-time snapshot.
Sandboxes created before that feature, direct OpenShell launches, and
--no-policy launches carry no annotation and need an explicit baseline:
The helper fails with an instruction to supply --base-file rather than
guessing from launcher configuration. Supply one explicitly after moving the
policy file or when managing a sandbox from another host, because the
annotation records a path on the launching host.
Write your own¶
An overlay replaces every network_policies entry it names as a whole; it
does not merge recursively with the live or baseline entry. Repeat every field
the replacement entry needs. Entries with distinct names compose. For another
GitLab or GitHub Enterprise instance, add a separate provider profile, baseline
policy key, and host-specific overlays instead of substituting hostnames, so
each instance's grants stay auditable.
For the complete composition rules, local validation checks, and instructions
for contributing an overlay, see
policy-overlays/README.md
and ADR-0044.