Who really built that? Supply-chain provenance for AI agent identity

by , , | Aug 7, 2026 | AI, Trust

When an AI agent introduces itself to another agent, it hands over a digital identity document called an agent card. Our previous post, “Who’s really calling? Securing agent-to-agent communication,” discussed whether that card is authentic at runtime. This post asks, “was the card built by someone you trust in the first place?”

The missing half of agent trust

In our work on Rossoctl, a Kubernetes operator for managing AI agent lifecycles, we built a runtime trust layer using SPIFFE/SPIRE. Every agent workload gets a cryptographic identity. The operator verifies each agent’s identity before trusting its agent card, whether through mTLS-authenticated fetch or JWS signature verification. If a workload cannot prove its identity, its traffic gets restricted. This is strong runtime security, but it has a blind spot.

Consider the journey an agent card takes before it ever reaches the cluster. A developer writes code and defines the card. A CI pipeline builds the container image and produces the card artifact. That artifact gets pushed to a registry or written into a ConfigMap. At some point the operator reads it and presents it to peer agents. At no point in this chain is there a cryptographic binding between the pipeline that produced the card and the card the operator eventually reads. There is no audit log of when it was signed. There is no way to detect if the card was quietly modified somewhere along the way.

An attacker who compromises an artifact store, a container registry, or even an in-cluster ConfigMap can substitute a malicious agent card that redirects traffic, escalates privileges, or injects poisoned tool definitions. The runtime identity system would verify the pod just fine. It simply has no opinion about the card that pod is serving.

Runtime identity is one half of the trust equation. Build-time agent supply-chain provenance is the other. We set out to close that gap.

Enter Sigstore: signing without the key management tax

Traditional code signing requires managing long-lived private keys, and those keys become high-value targets. If a key is stolen, every artifact it signed is suspect. If a key is lost, the pipeline breaks. Key rotation is expensive. Most teams, faced with this burden, simply do not sign their artifacts at all.

Sigstore eliminates this problem with keyless signing. Instead of persistent private keys, it binds signing identity to something the CI system already has: an OIDC token. Here is how the flow works for an agent card:

  1. A GitHub Actions workflow authenticates with its built-in OIDC identity.
  2. Fulcio, Sigstore’s certificate authority, verifies the token and issues a short-lived X.509 certificate, valid for minutes, that binds a signing key to that CI identity.
  3. The workflow signs the agent card using the sigstore-a2a library and embeds SLSA provenance metadata: the source repository, commit SHA, and build workflow that produced the card.
  4. The signature, the certificate, and the provenance are recorded in Rekor, an immutable, append-only transparency log.
  5. The private key is discarded. The certificate expires. What remains is a verifiable record: this agent card was signed by this CI workflow, from this repository, at this time, and the event is permanently logged.

There is nothing to rotate, nothing to store in a vault, nothing to leak. The signing identity is the CI workflow itself.

Two layers, one agent card

The key architectural insight is that a single agent card receives two independent signatures that answer fundamentally different questions:

SignatureWho signsWhenWhat it proves
Sigstore bundleCI/CD pipeline (via Fulcio)Build timeThis card was produced by a trusted pipeline from a known repository
SPIFFE identity verificationRossoctl operator (via SPIRE)RuntimeThis card matches the workload actually serving it

The two layers are complementary. SPIRE stays as the runtime identity foundation. Sigstore adds the agent supply-chain provenance that SPIRE was never designed to provide.

ConcernSPIRE (Runtime)Sigstore (Build time)
Certificate issuerSPIRE CA (cluster-internal)Fulcio CA (public)
Identity sourceSPIFFE ID (Kubernetes workload)OIDC subject (GitHub Actions workflow)
Audit trailNoneRekor transparency log
mTLS between agentsYesNo
CI/CD identity bindingNoYes

Neither layer subsumes the other. When both are present and valid, the trust picture is complete: you know the card was built right and that the workload serving it is legitimate.

How it works in practice

On the CI side, we wrote a GitHub Actions workflow that signs agent cards as part of the standard build process. The workflow requests an OIDC token from GitHub, passes it to the sigstore-a2a library, and produces a single signed document that bundles the original agent card together with its cryptographic attestations and SLSA provenance. This signed document is stored in a ConfigMap, which the operator reads during reconciliation. For developers, this adds a single step to their existing pipeline.

On the operator side, the verification happens during the standard AgentCard reconciliation loop. When the controller fetches an agent card, it checks whether the document is a SignedAgentCard with an attestations.signatureBundle field. If one exists, the operator:

  1. Parses the bundle and loads Sigstore’s trusted root material.
  2. Verifies the cryptographic signature against the Fulcio certificate.
  3. Checks that the signer identity matches the expected repository and workflow (configurable via operator flags or per-card overrides).
  4. Confirms the signing event is enrolled in the Rekor transparency log.
  5. Extracts SLSA provenance: the source repository and commit SHA that produced the card.

All of this is implemented using the sigstore-go library directly in the operator, avoiding the overhead of shelling out to CLI tools on every reconcile cycle. The raw agent card bytes are canonicalized using JCS (RFC 8785) before digest verification, ensuring that semantically equivalent JSON representations produce identical hashes.

The verification result is recorded on the AgentCard CR status:

Platform teams can see at a glance which cards have provenance and which do not. The status includes the Fulcio signer identity and the Rekor log index, so auditors can cross-reference against the transparency log directly.

Graceful adoption: audit before you enforce

Rolling out agent supply-chain verification in a running cluster requires a safety valve. Not every team will have Sigstore-signed cards on day one, and blocking unsigned cards without warning would break deployments.

We followed the same pattern that has proven effective for SPIRE signature verification: audit mode. When Sigstore verification is enabled with --sigstore-audit-mode=true, the operator evaluates every bundle but never blocks a card from becoming active. Verification failures are logged, recorded as Kubernetes events, and reflected in the AgentCard status. This gives teams full visibility into what would fail under enforcement without any operational impact.

When a team is confident that their pipelines are signing correctly, they flip audit mode off. From that point, any agent card whose Sigstore bundle is present but fails verification is marked Ready=False and never becomes active. The enforcement is reconciler-based rather than admission-webhook-based: unverified cards simply never reach a ready state. This avoids the webhook becoming a single point of failure and is consistent with the existing operator patterns. The architecture supports adding admission-time rejection as a follow-on if needed.

Cards without any Sigstore bundle at all (plain agent cards that predate the signing workflow) are not blocked, even in enforcement mode. A missing bundle means the card hasn’t been onboarded to signing yet, which is different from a card that was signed and failed verification. This means organizations can migrate incrementally: new pipelines start signing immediately, while legacy cards continue to function until they are updated.

What comes next

The Sigstore integration described here is one step in a broader plan. Looking ahead, SPIRE’s Kubernetes workload attestor already has built-in Sigstore support (currently experimental) that can verify container image signatures as part of workload attestation. When enabled, SPIRE refuses to issue an identity certificate to any workload running an unsigned image. This means an agent with a tampered image cannot even obtain a SPIFFE identity, let alone participate in the mesh.

Further out, the SPIRE community is exploring attestor composition: a model where attestors chain together, each consuming the verified output of the previous one. The Kubernetes attestor would verify the pod and image signature. A Rossoctl agent attestor would consume those selectors, read the agent card, verify it against the operator’s trust policy, and emit capability-level selectors. A single SPIRE registration entry could then require all conditions to pass: the right namespace, a signed image, and a validated agent card.

There is also a third dimension we have not covered here: capability validation. Provenance proves the card came from a trusted pipeline. Runtime identity proves the workload is legitimate. But neither proves that the skills an agent claims are actually true. That is the domain of a separate effort within Rossoctl that we will discuss in a future post.

Get involved

All of this work is open source. The Rossoctl operator and the broader Rossoctl platform are developed in the open, and we welcome contributions, issues, and feedback. If you are building agent systems on Kubernetes and thinking about agent supply-chain trust, we would particularly like to hear about:

  • How identity constraints should work across multitenant clusters.
  • Private Sigstore instance support for air-gapped deployments.
  • What provenance signals are most useful for your compliance requirements.

The gap between “who built this” and “who is running this” is closing. And with it, the foundation for trustworthy multiagent AI is taking shape.

Note: Red Hat’s Emerging Technologies blog includes posts that discuss technologies that are under active development in upstream open source communities and at Red Hat. We believe in sharing early and often the things we’re working on, but we want to note that unless otherwise stated the technologies and how-tos shared here aren’t part of supported products, nor promised to be in the future.