Innsegl
Verifiable identity and attribution for AI agents.
Innsegl issues a single-purpose cryptographic identity to each agent run, attributes every action and every commit to that identity, and records the attribution somewhere a third party can check it without trusting the system that produced it — including without trusting whoever operates that system.
Innsegl is Norwegian, from Old Norse innsigli: the seal pressed on a document to prove who issued it.
Status: pre-1.0, and several things below are not built
This is an in-progress open-source project, not a product. The honest inventory, as of this page:
-
Nothing is released. There is no tagged version,
so
@latestresolves to a pseudo-version of the default branch. Every interface that is not named as protected below can still change without notice. -
Nothing is hosted.
innsegl.devserves this page and the Go module path. The public verification page and the operator dashboard are written but are not deployed at any address, and there is no instance of the server you can point an agent at. -
There is no public Go API. Every package except
cmd/innseglis underinternal/, so the module is a program rather than a library. Do not plan to import it. -
innsegl sealis listed in the CLI's help and exits non-zero. Segment sealing and Rekor anchoring exist as code; the subcommand an operator would schedule does not yet. - The end-to-end claim is not yet demonstrable by you. The signing and anchoring paths are exercised against real SPIRE and a real Fulcio and Rekor in this project's own test containers. That is not the same as a deployment you can run and check, and it should not be read as one.
If something on this page is not a command you can run yourself, read it as a design intention rather than a shipped feature.
What it is
Agent work is unattributed. Nobody can prove which agent did what, and nothing stops an operator from disputing the attribution afterwards. Innsegl is one identity service and one append-only ledger, arranged so that issuance is centralized and verification is not.
-
One identity per run. SPIRE attests the workload
and issues a short-lived SVID for the SPIFFE ID
spiffe://{trust-domain}/agent/{agent-type}/{task-id}/{run-id}. One registration entry per run, created at registration and deleted at retirement: identity, run and purpose are the same thing. -
An MCP server with five tools —
register_agent,get_credential,record_event,sign_commit,retire_agent. Agents talk only to it, and never see SPIRE's admin API. It never holds, caches or proxies an agent's private key. -
Commits signed, not asserted. A JWT-SVID bound to
Sigstore's audience buys a short-lived Fulcio certificate; the
commit is signed with it and its entry lands in the Rekor
transparency log. The commit carries
Agent-Identity,Agent-RunandAgent-Tasktrailers. The trailer is the claim; the signature is the proof; verification requires that they agree. - A ledger with no delete or update path. Events are hash-chained, sealed into content-addressed segments, and each segment's Merkle root is anchored in Rekor. Corrections are new events that supersede old ones. Nothing is ever rewritten.
What it proves, and what it does not
Verification is three checks, against public infrastructure only:
- the signing certificate chains to Fulcio;
- the commit's entry is provably included in Rekor;
- the identity claimed in the commit trailer is the identity in that certificate.
All three run against git, Fulcio and Rekor. None of them reads this system's database — the verifier has no flag with which to point it at one, deliberately. A verification you can only perform by asking the operator's server is not a verification.
Limits worth knowing before you adopt it
- It answers who did it, not whether it was allowed. There is no policy engine and no authorization model beyond protecting the server's own admin surface.
- Attestation proves what a workload is, not that it behaved. Innsegl is not a sandbox.
-
GitHub's interface does not render gitsign signatures with its
Verified badge, and this project does not chase that.
innsegl verify,gitsign verifyand a Rekor inclusion proof are the verification. - The ledger stores digests and references — commit SHA, tree hash, payload digest — never diffs, code or tool-call bodies.
- Commits made before adoption stay unattributed. Nothing is backfilled or inferred.
Install
go install innsegl.dev/innsegl/cmd/innsegl@latest
innsegl.dev/innsegl is the module path; the code is at
github.com/Raymalian/innsegl.
With no tag published yet, @latest gives you a
pseudo-version of the default branch — pin a commit if you need the
same bytes twice.
Verify a commit, with no Innsegl deployment at all
innsegl verify <commit> -repo .
The exit status is the verdict, so it composes into a script without
parsing anything: 0 verified, 3 failed,
4 verification unavailable, 5 the commit
makes no attribution claim, 6 unusable — no such commit,
or a configuration that cannot verify. 4 is never
collapsed into 3: we could not check is a
different answer from it does not hold.
Run the reference stack
The repository carries a Docker Compose stack — SPIRE, Postgres,
object storage, a self-hosted Sigstore, and the server itself — under
deploy/compose/. Read its README there; it is the part of
this project that changes fastest.
Two names that look alike and are not
innsegl.dev/innsegl-
The Go module path. It is a real URL and it resolves: this domain
serves the
go-importmeta tag that sends the toolchain to the repository. See the tag. spiffe://innsegl.dev-
The reference trust domain — and it is
not an endpoint. It has no DNS record, nothing
listens on it, and nothing ever connects to it. A SPIFFE trust
domain is a name: it identifies which root a
spiffe://innsegl.dev/agent/…identity belongs to. Owning the matching DNS name is worth doing only because it guarantees no one else can create ambiguity about that root.
What is frozen already
Some surfaces are protected from the first release onward, because changing them retroactively would invalidate proofs that were already made: the event schema field names and enum values, the canonical serialization of an event, the commit trailer keys, the SPIFFE ID grammar, and the MCP tool names and error classes. Those change only in a major release, with a migration attestation. Everything else on this page is pre-1.0 and may move.