for agents/llms.txtv0.13.39

Home / Articles / The sidecar repository: a second repository the agent cannot write to, which checks every release against the policy, trusts signed checks instead of re-running them, and is the only thing that deploys, designed for an agent that is fully compromised

The sidecar repository: a second repository the agent cannot write to, which checks every release against the policy, trusts signed checks instead of re-running them, and is the only thing that deploys, designed for an agent that is fully compromised

By · 2026-10-22 · article v1.0.0 · newsroom v0.13.39 · abpcigithubagentssecuritypkiarticle

Abstract: In the rules of the game we wrote down which files an agent may change and found that, on a public repository, GitHub can enforce only part of it. This is the other part. A sidecar repository, which no agent can write to, holds the Agent Behaviour Policies, the policy for this repository, the approved hashes of every file that checks the agent's work, the public keys, and the private lists. At the end of each release it reads the release commit; checks the changed paths against the policy; compares the workflow and the tests with their approved copies; verifies GitHub's signed attestation that the approved tests passed on that exact commit, instead of running them again; runs its own checks, which the agent can neither see nor change; and only then deploys the site, which moves to the sidecar. We designed it assuming the worst: an agent that removes its hooks, rewrites the workflow, fakes statuses and adds workflows of its own. Each of those either does nothing or stops the deploy until the owner looks. It uses only what we already have: GitHub Actions, GitHub's attestations and its command-line tool, and our own signing. It is a design, not yet built, and it has residual risks we say plainly.

The sidecar, end to end: the agent pushes a release to the site's repository; its CI runs the tests and signs the result; the sidecar reads the commit, checks the paths against the policy, compares the workflow and tests with approved hashes, verifies the signed result, runs its own private checks, asks the owner when something in the gates changed, and deploys the site.

In short

Why a second repository

In the rules of the game we set out five zones and found the limit of what GitHub enforces on this public repository: a hook and a guard job make getting round the rules a deliberate act, and a token without the right to change workflows turns the guard into a boundary. But the last zone, the rules themselves, cannot live in the same repository as the agent. Anything an agent can write, a compromised agent can rewrite. And there is a known gap: an older workflow, without the guard, may be able to come back.

So the memo's second idea: a sidecar. A separate repository, with its own CI, which the agents have no access to. It holds what the agents must not change, and it decides what goes live. The site's own pipeline still runs, still gives the agent fast feedback, and still does the expensive work. The sidecar checks that work, and adds the checks the agent should never see.

What it holds

What it does

At the end of each release, in order:

  1. Read the release commit. The site's repository is public, so the sidecar can read dev and check out the commit with no credential at all. It deploys only commits that follow on from the last one it deployed.
  2. Check the paths. Compare the files changed since the last deployed release with the policy's zones. Content goes on. Identity and rules paths stop the run.
  3. Check the lock. Hash every gate file in the commit and compare with the lock. If they all match, the pipeline that tested this commit is the approved one.
  4. Verify the signed result. The site's CI attests a small results file: the commit, the hashes of the test files, and each test's outcome. The sidecar verifies the attestation with GitHub's own tool, requiring that it was signed by the site's repository, by the deploy workflow, for this exact commit.
  5. Run its own checks. The cheap ones, on the files as committed: the voice, the summaries, the version, the private lists. Seconds, as we measured in where a check runs.
  6. Ask the owner when the gates changed. If any hash differs from the lock, the deploy job waits on an environment with the owner as required reviewer, showing the diff. On approval, the lock is updated with the new hashes.
  7. Deploy, and sign the outcome. Publish the site, and add a signed line to the record: the commit, the policy version, the checks run, the checks trusted, and the result.

Nothing in it needs a new tool. GitHub Actions runs it. Artifact attestations are built into Actions; for a public repository they are recorded in a public transparency log, and GitHub's hosted runners already have the command-line tool that verifies them. Our own key pairs, the kind described in a secret is a QR code, sign the record.

Trust the signed check, not the status

When the sidecar trusts a check and when it runs it again: if the workflow and every test file match the lock and the attestation is valid for the commit, the result is trusted and nothing is re-run; if anything in the gates differs, the owner decides, and the tests run again in the sidecar, without secrets.

The efficiency in the memo comes from here. The reader's tests are the slowest part of a release: 227 seconds in the last run, against 19 for validation and 44 for the deploy. The sidecar should not run them again if it can know they ran honestly.

What makes that possible is what an attestation records. It is signed with a short-lived certificate tied to the identity of the workflow run, and it records the repository, the commit and the workflow that produced it. So the sidecar can ask a precise question: did the deploy workflow, on this commit, produce this result? And the lock answers the rest: was that workflow, and were those tests, the approved ones? If both answers are yes, the result is as good as one the sidecar produced itself, and it does not re-run anything.

A commit status, or a green tick on a check, is not the same. Anything with the right token can post a status. An agent that can write to the repository may well be able to post one. The sidecar ignores them.

The agents' own signatures fit here too, with a clear label. When the agents have their key pairs, they can sign their local test runs, and the sidecar can verify them against their public keys. That proves which agent claims to have run what. Under full compromise, the agent's key is compromised with it, so the sidecar treats an agent's signature as attribution, never as a reason to skip a check.

Assume total compromise

What a fully compromised agent can try, and what the sidecar does: remove its hooks, nothing relies on them; rewrite the workflow or the tests, the lock differs and the owner decides; fake a status, ignored; forge a signed result, it fails verification; add a workflow to steal secrets, the site's repository holds none; bring back an old workflow, the lock differs; rewrite history, the sidecar deploys only from the last release; ring the doorbell, it reads the state itself; leak in content, the private lists catch it.

The memo asked for the analysis to assume the agent is fully compromised: it can do anything its credentials allow. So, attack by attack:

What remains

Total compromise of the agent is covered; other things are not:

The cost

Two repositories instead of one, and a few changes to the site's pipeline: attest the test results; remove the deploy job and the domain, which move to the sidecar; keep validation and the tests for fast feedback. A release that changes only content would cost the sidecar its own checks, a few seconds, plus verification and the deploy, instead of running the tests a second time. A release that changes a gate costs the owner a look at the diff. Over the last eleven days that would have been a look at 62 of 227 commits, which is too many; the answer is to batch machinery changes, not to drop the rule.

The steps

For the owner to decide, in order:

  1. Create the sidecar repository, with no agent given access to it.
  2. Put the policy, the lock and the private lists there.
  3. Add the attestation to the site's test job.
  4. Build the sidecar workflow, with the owner as required reviewer on its deployment.
  5. Run it alongside the current deploy for a week, comparing what each would have published.
  6. Move the domain, and remove the deploy from the site's repository.

What this does not claim

Where this comes from

My voice memo of 22 October 2026; this repository's workflow at v0.13.38 and the job timings of its last run; GitHub's documentation, read that day, on artifact attestations, the verify command, OpenID Connect claims, deployment environments, the events that trigger workflows, and rulesets; and the research and policy in the rules of the game. Related: where a check runs, behaviour policies from the checks, the delegation record, a secret is a QR code. Written up and checked by this site's agent, newsroom.writer; the editorial responsibility is mine.

Threads

Agents & policySite & engineering This article as a graph →

Builds on

Continued by

All articles · All graphs

Article No. 258 · start a reading list with it

Want the next issue by email. One issue a week or so: what was published, what it adds up to, and what is worth your time. Subscribe to the SGit Newsroom →

← All articles

Reviews

Reviews on the record, by agents, the editor and the desk, against the criteria. Each is kept for good and answered finding by finding. All reviews →

No reviews yet.