# Security model — agent behavior isolation Agent behavior — which models run, what skills / permissions / MCP servers they get, and the golden rules they follow — is defined **only** by this `agents` repository. A caller repository must not be able to change it. ## For caller repos Call the shared workflow pinned to this repo's `main`: ```yaml uses: ffaerber/agents/.gitea/workflows/agent.yml@main secrets: inherit ``` Do **not** point `uses:` at a fork or a non-`main` ref. The trigger gate, the agent registry, and the isolation controls all live here on `main`; a caller that repoints it opts out of these protections. ## How isolation is enforced at runtime The agent runs inside the caller repo's checkout, and opencode auto-discovers project-level config from the working tree. Because opencode has **no flag to disable that discovery**, the run (`scripts/run-agent.sh`) quarantines the caller-controlled behavior files for the duration of each run so they cannot override the agent's configuration or execute code on the runner (which holds the workflow secrets): - `opencode.json` / `opencode.jsonc` — provider, model, permission, `mcp` - `.opencode/` — plugins, skills, agents, commands, tools - `AGENTS.md` / `CLAUDE.md` — instructions They are moved aside before opencode starts and restored after it exits, so the committed tree is unchanged. The authoritative configuration comes from `~/.config/opencode/` (written by `scripts/install-opencode.sh`), and the authoritative golden rules from `scripts/agent-rules.md`, injected into the agent prompt. **`opencode.json` / `.opencode/` are fully blocked** — never re-introduced — because they can change config or execute code. **`AGENTS.md` / `CLAUDE.md` are treated as repo notes, not rules.** A caller repo legitimately uses its `AGENTS.md` to document repo-specific mechanics (build/deploy/migration conventions) the agent needs. So its text is captured and injected into the prompt as explicitly **subordinate** context — useful for how the repo works, but unable to change agent behavior, grant permissions, or override the golden rules. It is never auto-loaded by opencode as top-level instructions. **Consequence:** an agent cannot durably edit these quarantined files *during a run* — its changes to them are not persisted. Change them via a normal human PR instead.