Signed by the Agent
aeon shipped skill-execution attestation via Sigstore. Every eligible run now produces a signed statement binding the output bytes to the workflow identity that produced them - verifiable without trusting the operator.
The last article in the kickoff series argued that aeon’s observability is a substrate rather than a feature. The runner is the audit trail: every prompt, every output, every failure lives in the GitHub Actions tab, and you can scroll back through it whenever you want.
That was the “trust the log” story. This one is the “verify the signature” story.
In early July, aeon shipped skill-execution attestation via Sigstore. Every eligible run now produces a cryptographically signed statement binding the output bytes to the exact workflow identity that produced them. You don’t have to trust the repo owner, and you don’t have to trust the log renderer. You verify the signature against a transparency log the operator doesn’t control, and it either checks out or it doesn’t.
§ 01What Sigstore actually gives you
Sigstore is the OpenSSF project that makes signing runtime artifacts as cheap as a container tag. Under the hood: short-lived signing certificates tied to an OIDC identity, plus Rekor, a public transparency log that stores every signature. The identity used for aeon is the GitHub Actions OIDC token, which encodes repository, workflow file path, run ID, commit SHA, trigger, and timestamp.
The GitHub Artifact Attestations feature wraps this in a first-class Actions primitive. actions/attest-build-provenance@v4 takes a subject file - the bytes you want to attest to - and produces a Sigstore-signed statement that says: this file was produced by this workflow, in this run, at this commit, at this time. The statement goes to Rekor. Anyone can pull the attestation later and verify it against the public log.
For aeon, the subject is an immutable, run-scoped snapshot of the output the skill just produced - output/.attest/<skill>-<run_id>.md - rather than the shared chain file that later runs overwrite. Alongside it goes a small manifest, output/.attest/<skill>-<run_id>.json, carrying the aeon-side facts a bare provenance statement doesn’t know: skill, model, mode, trigger, commit, run_id, and the snapshot’s SHA-256. Both are signed in the same attestation, so the framework context costs nothing extra.
Zero changes to the skill itself. The attestation happens in the trusted workflow layer, on bytes the runner already had, behind two permissions:
permissions: id-token: write # mint the OIDC token that signs the attestation attestations: write # write the attestation to the repo's store
§ 02Why the operator cares
An unsigned skill output is a claim. “Here’s what my agent produced this morning.” The claim is worth exactly as much as your reputation.
A signed skill output is a proof. “Here’s what my agent produced this morning, signed by the workflow at commit abc1234, run ID 1234567890, on branch main, triggered by cron at 06:00 UTC, logged in Rekor.” The reader runs gh attestation verify and gets back a cert chain and a Rekor inclusion proof.
The difference matters most when the output leaves the repo. A daily brief posted to Telegram, a weekly digest linked from a website, a market signal handed to a downstream system - each of those can be re-derived from the log, but only if the log is honest. Attestation removes the operator from the trust boundary. The runner, the OIDC token, the Sigstore CA, and the Rekor log all sit outside the operator’s control.
For a framework whose thesis is “the fork IS the deployment,” that matters. Someone else’s aeon fork is not something you should trust by default. But you can verify its outputs.
§ 03Off by default, tiered when on
Attestation isn’t free. Each attested run is a Sigstore signing plus a permanent, public Rekor entry - a few seconds of workflow time, a real cost, and a record that never goes away. On a fork that runs 20 skills a day, that adds up.
So the gate is tiered:
- Global kill switch.
ATTEST_ENABLED=false(the default) means nothing gets attested. Flip it totrueand the framework starts making decisions. - Per-skill override in `aeon.yml`. A skill entry can declare
attest: trueorattest: falseand win over the default policy. - Per-skill override in `SKILL.md` frontmatter. Same field, closer to the code - useful for authors who ship a skill upstream with a strong opinion about whether its output should carry provenance.
- Default policy when nothing else is set. Attest feed-published runs only: the ones whose output goes somewhere with an audience. Internal-only runs stay unattested to keep the ledger tight.
Explicit attest: false always wins. If an operator decides a skill’s output should never carry provenance - a research skill that pulls draft material, say - nothing overrides that decision.
One deployment caveat: public repos get attestations on every GitHub plan. Private repos need a plan that includes Artifact Attestations (Team or Enterprise); without it, the attest step fails rather than silently skipping.
§ 04What the reader gets
The mechanics on the reader side are one command:
gh attestation verify output/.attest/<skill>-<run_id>.md \ --repo aeonfun/aeon
That returns:
- The identity that signed it -
sourceRepositoryURI,buildSignerURI(the workflow file),sourceRepositoryDigest(the commit), andrunInvocationURI(the run). - The Rekor entry that logged the signature.
- A cert chain rooted in the Sigstore CA.
If the file was modified after signing, the verify fails. If the workflow identity doesn’t match what the operator claims, the verify fails. If Rekor has no record of the signature, the verify fails. None of these depend on the operator being cooperative.
For someone building a distribution layer on top of aeon - a public briefing service, a paid signal feed, a community-facing digest - attestation is the missing primitive. “Here’s the output” becomes “here’s the output, and here’s the signature.” One is a screenshot. The other is evidence.
Worth stating plainly: this proves provenance of bytes, not correctness of behaviour. A signed output is not a true output. It’s an output nobody can quietly swap, backdate, or attribute to a workflow that never ran.
§ 05Why now
Signed provenance for build outputs isn’t new. The npm ecosystem started shipping Sigstore attestations for published packages in 2023. Container registries added it around the same time. The novel piece is applying it to agent outputs - to the artifact of a skill run.
The framing that made this fit aeon: the skill output is the deliverable. The runner already captures it. The workflow identity is already meaningful - repo, commit, cron trigger, all bound to a Sigstore-signable OIDC token. Every piece was already in place. What shipped was two workflow steps and a permissions bump that wired them together.
§ 06The trust boundary shift
The first batch of articles argued that aeon’s observability was a substrate. This one argues that trust in that substrate is now cryptographic, not social.
You no longer have to know the operator to trust the output. You verify the signature, check the workflow identity, and decide whether that identity is one you want to believe. The framework moved the trust from a person to a proof.
Silence is still a feature. Public logs are still the audit trail. But now, if the operator wants to hand you an output and be believed by strangers, the tooling is there. gh attestation verify is the whole protocol.
Background on the mechanics: Receipts, Not Just Vibes for the log substrate, 60 Days of aeon for everything else that shipped alongside this, and docs/attestation.md for the implementation.
