Skip to content

Feat: Implementing Sigstore-A2A verification for A2A Agent Cards#355

Open
DeanKelly751 wants to merge 7 commits into
kagenti:mainfrom
DeanKelly751:feature/sigstore-a2a-signed-card-verification
Open

Feat: Implementing Sigstore-A2A verification for A2A Agent Cards#355
DeanKelly751 wants to merge 7 commits into
kagenti:mainfrom
DeanKelly751:feature/sigstore-a2a-signed-card-verification

Conversation

@DeanKelly751
Copy link
Copy Markdown

@DeanKelly751 DeanKelly751 commented May 12, 2026

What This PR Delivers

Phase 2b: Sigstore-based Agent Card Verification

  1. Keyless Signing in CI/CD

    • GitHub Actions workflow signs agent cards using GitHub's OIDC identity
    • No long-lived secrets or keys required
    • Uses sigstore-a2a CLI for signing
  2. Cryptographic Verification

    • AgentCard controller verifies Fulcio certificates
    • Validates Rekor transparency log entries
    • Configurable certificate identity allowlist
  3. Supply Chain Provenance

    • SLSA metadata embedded in signed cards
    • Links deployed agents to exact source commits and builds
    • Includes workflow, repository, and commit SHA
  4. Audit Trail

    • Every signature recorded in Sigstore's Rekor transparency log
    • Public, tamper-proof verification
    • Permanent record of what was signed when
  5. Graceful Adoption Mode

    • Unsigned cards allowed but clearly flagged (sigstoreBundleVerified: false)
    • Organizations can migrate incrementally
    • Policy enforcement ready via status.sigstoreBundleVerified field

Implementation Details

Core Changes:

  • AgentCard controller: Added Sigstore bundle verification logic
  • AgentCard status: New fields for verification state (sigstoreBundleVerified, sigstoreIdentity, rekorLogIndex, SLSA provenance)
  • Operator flags: --enable-sigstore-verification, --sigstore-certificate-identity, --sigstore-certificate-oidc-issuer, --sigstore-audit-mode
  • GitHub Actions: .github/workflows/sign-agent-card.yml - OIDC-based signing workflow

Verification Flow:

  1. AgentCard controller fetches agent card from ConfigMap (key: signed-agent-card.json)
  2. If card contains attestations.signatureBundle, verification is attempted
  3. Fulcio certificate validated against configured identity + OIDC issuer
  4. Rekor transparency log entry verified
  5. Status updated with verification result + provenance metadata

Configuration Example:

--enable-sigstore-verification=true
--sigstore-certificate-identity=[https://github.com/ORG/REPO/.github/workflows/WORKFLOW.yml@refs/heads/BRANCH](https://github.com/ORG/REPO/.github/workflows/WORKFLOW.yml@refs/heads/BRANCH)
--sigstore-certificate-oidc-issuer=[https://token.actions.githubusercontent.com](https://token.actions.githubusercontent.com)
--sigstore-audit-mode=false  # true = log failures but don't block

dekelly and others added 2 commits May 11, 2026 13:04
Implement Sigstore (sigstore-a2a) bundle verification for agent cards
using the sigstore-go library with production TUF root, certificate
identity validation, and Rekor transparency log verification.

**Core Verification**
- Verify SignedAgentCard bundles using sigstore-go verify.NewVerifier
- Validate Fulcio certificate identity against expected GitHub workflow
- Confirm Rekor transparency log inclusion
- Extract SLSA provenance (repository, commit SHA) from bundles
- Support both current (attestations) and legacy (verificationMaterial) formats
- Use JCS (RFC 8785) canonicalization for artifact bytes

**Configuration**
- CLI flags: --enable-sigstore-verification, --sigstore-audit-mode,
  --sigstore-certificate-identity, --sigstore-certificate-oidc-issuer
- Per-AgentCard identity override via spec.sigstoreVerification
- Support custom TUF trust roots via ConfigMap
- Staging TUF support for testing (--sigstore-staging)

**Status & Observability**
- Status fields: sigstoreBundleVerified, sigstoreIdentity, rekorLogIndex,
  slsaRepository, slsaCommitSHA
- SigstoreVerified condition with reasons: SigstoreVerified,
  SigstoreVerificationFailed, SigstoreVerificationFailedAudit,
  SigstoreBundleNotFound
- Kubernetes Events: SigstoreVerified (Normal), SigstoreVerificationFailed
  (Warning), SigstoreBundleNotFound (Warning)
- Prometheus metrics: kagenti_sigstore_verification_total{result},
  kagenti_sigstore_verification_duration_seconds,
  kagenti_sigstore_trusted_root_age_seconds

**Enforcement**
- Audit mode: log failures without blocking reconciliation
- Enforcement mode: reject cards with invalid/missing bundles
- NetworkPolicy integration: verified label requires both JWS and Sigstore
- Graceful adoption: absent bundles (plain agent cards) marked as Absent

**CI Integration**
- GitHub Actions workflow: .github/workflows/sign-agent-card.yml
- Uses sigstore-a2a Python library to sign example agent card
- OIDC token from GitHub Actions for keyless signing
- Publishes signed card as workflow artifact

**Helm Chart**
- New values: sigstore.enabled, sigstore.auditMode,
  sigstore.certificateIdentity, sigstore.certificateOIDCIssuer,
  sigstore.staging, sigstore.trustedRoot
- Manager deployment updated to pass Sigstore flags

**Testing**
- 6 integration test cases: valid bundle, absent bundle, audit mode,
  enforcement mode, SLSA extraction, per-card identity override
- Unit tests for parseProvenance, parseSignedAgentCardStructure
- Example signed agent card in examples/ci-agent-card.json

**Documentation**
- Manual E2E test guide for Sigstore verification
- Inline code comments for Sigstore initialization and verification flow
- Webhook configuration comment for local testing without certificates

**Code Review Fixes**
- Add kustomize patch for webhook namespace/object selectors (W-1 HIGH)
- Include Sigstore in NetworkPolicy label propagation (P-2 MEDIUM)
- Emit Kubernetes Events for all Sigstore paths (P-3 MEDIUM)
- Handle infrastructure errors in enforcement mode (M-3 MEDIUM)
- Clear Sigstore status when verification disabled (P-6 LOW)
- Remove unused RekorURL CRD field (CRD-1 LOW)
- Allow validation webhooks to be disabled via ENABLE_WEBHOOKS=false

Signed-off-by: dekelly <dekelly@redhat.com>
Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com>
dekelly added 3 commits May 12, 2026 14:26
- Split long error messages in cmd/main.go to stay under 120 char limit
- Add nolint:gocyclo directive for updateAgentCardStatus (TODO: refactor)

Signed-off-by: dekelly <dekelly@redhat.com>
Signed-off-by: dekelly <dekelly@redhat.com>
…ification

Signed-off-by: dekelly <dekelly@redhat.com>
@DeanKelly751 DeanKelly751 force-pushed the feature/sigstore-a2a-signed-card-verification branch from a6b1300 to ec5f236 Compare May 12, 2026 13:26
Copy link
Copy Markdown
Contributor

@kevincogan kevincogan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work on the Sigstore integration. The architecture is solid with clean use of sigstore-go, proper JCS canonicalization, good separation between the fetcher and verifier, and the audit/enforcement mode split is well thought out. Integration tests cover the key paths nicely.

Two items to address, both are quick fixes. See inline comments.

Comment thread .github/workflows/sign-agent-card.yml Outdated
- name: Install sigstore-a2a with pinned a2a-sdk
run: |
uv pip install --system --prerelease=allow "a2a-sdk==0.2.16"
uv pip install --system --prerelease=allow "git+https://github.com/sigstore/sigstore-a2a.git@main"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This installs sigstore-a2a from an unpinned @main branch. For a PR that adds supply-chain verification, the signing toolchain itself should be pinned to a specific commit SHA or tagged release. A compromised or broken main push would silently affect every CI run.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed from:

uv pip install --system --prerelease=allow "git+https://github.com/sigstore/sigstore-a2a.git@main"

To:

uv pip install --system --prerelease=allow
"git+https://github.com/sigstore/sigstore-a2a.git@293f9bd"

Also I added a comment in the workflow to update periodically by checking the commit history.

Comment on lines +115 to +118
rekorURL:
description: RekorURL is reserved for custom transparency log
base URL; the operator primarily uses the trusted root material.
type: string
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This rekorURL field exists in the Helm chart CRD but not in the Go type (SigstoreVerification in agentcard_types.go) or the generated CRD at config/crd/bases/. That means a user can set spec.sigstoreVerification.rekorURL on their AgentCard and the API server will accept it, but the operator will silently ignore it.

Either remove rekorURL from this file to match the generated CRD, or add the corresponding field to the Go type and regenerate. Since the description says "reserved," removing it until it's wired up is the safer option.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Followed your recommendation to remove it as the safer option since it was only "reserved" and not actually wired up.

@DeanKelly751 DeanKelly751 force-pushed the feature/sigstore-a2a-signed-card-verification branch from 2e51891 to 63b495f Compare May 14, 2026 08:58
  - Pin sigstore-a2a to commit SHA 293f9bd instead of @main for reproducibility
  - Remove non-functional rekorURL field from Helm chart CRD to match Go types

Signed-off-by: dekelly <dekelly@redhat.com>
@DeanKelly751 DeanKelly751 force-pushed the feature/sigstore-a2a-signed-card-verification branch from 63b495f to bca169f Compare May 14, 2026 09:11
@DeanKelly751 DeanKelly751 marked this pull request as ready for review May 14, 2026 09:18
@DeanKelly751 DeanKelly751 requested review from a team as code owners May 14, 2026 09:18
@DeanKelly751 DeanKelly751 requested a review from kevincogan May 14, 2026 15:04
Copy link
Copy Markdown
Contributor

@kevincogan kevincogan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

3 participants