Skip to content

AgentCardVerifier

The AgentCardVerifier class provides methods for verifying signed A2A Agent Cards using Sigstore.

Overview

from sigstore_a2a import AgentCardVerifier

verifier = AgentCardVerifier(
    oidc_issuer="https://token.actions.githubusercontent.com"
)
result = verifier.verify_file("signed-card.json")

if result.valid:
    print("Signature verified!")

API Reference

AgentCardVerifier

AgentCardVerifier(
    identity: str | None = None,
    oidc_issuer: str | None = None,
    staging: bool = False,
    trust_config: Path | None = None,
    instance: str | None = None,
)

Verifies signed A2A Agent Cards using Sigstore.

Initialize the Agent Card verifier.

PARAMETER DESCRIPTION
identity

The expected identity that has signed the model

TYPE: str | None DEFAULT: None

oidc_issuer

The expected OpenID Connect issuer that provided the certificate used for the signature

TYPE: str | None DEFAULT: None

staging

Use Sigstore staging environment

TYPE: bool DEFAULT: False

trust_config

Path to ClientTrustConfig JSON for manual trust configuration

TYPE: Path | None DEFAULT: None

instance

Sigstore instance URL (for TUF-bootstrapped trust)

TYPE: str | None DEFAULT: None

Source code in sigstore_a2a/verifier.py
def __init__(
    self,
    identity: str | None = None,
    oidc_issuer: str | None = None,
    staging: bool = False,
    trust_config: Path | None = None,
    instance: str | None = None,
):
    """Initialize the Agent Card verifier.

    Args:
        identity: The expected identity that has signed the model
        oidc_issuer: The expected OpenID Connect issuer that provided
            the certificate used for the signature
        staging: Use Sigstore staging environment
        trust_config: Path to ClientTrustConfig JSON for manual trust configuration
        instance: Sigstore instance URL (for TUF-bootstrapped trust)
    """
    self.identity = identity
    self.oidc_issuer = oidc_issuer
    self.staging = staging
    self.trust_config = trust_config
    self.instance = instance

    self._verifier: Verifier | None = None

verify_signed_card

verify_signed_card(
    signed_card: (
        SignedAgentCard | dict[str, Any] | str | Path
    ),
    constraints: IdentityConstraints | None = None,
) -> VerificationResult

Verify a signed Agent Card.

PARAMETER DESCRIPTION
signed_card

Signed agent card to verify

TYPE: SignedAgentCard | dict[str, Any] | str | Path

constraints

Optional identity constraints

TYPE: IdentityConstraints | None DEFAULT: None

RETURNS DESCRIPTION
VerificationResult

Verification result

Source code in sigstore_a2a/verifier.py
def verify_signed_card(
    self,
    signed_card: SignedAgentCard | dict[str, Any] | str | Path,
    constraints: IdentityConstraints | None = None,
) -> VerificationResult:
    """Verify a signed Agent Card.

    Args:
        signed_card: Signed agent card to verify
        constraints: Optional identity constraints

    Returns:
        Verification result
    """
    # 1. Parse input
    try:
        parsed_signed_card = self._parse_signed_card(signed_card)
    except Exception as e:
        return VerificationResult(valid=False, errors=[f"Invalid signed card: {e}"])

    sig_bundle = parsed_signed_card.attestations.signature_bundle

    # 2. Build verification policy from constraints (handles None safely)
    policy = self._build_policy(constraints)

    # 3. Sigstore DSSE verification
    verifier = self._get_verifier()
    try:
        _payload_type, payload = verifier.verify_dsse(sig_bundle, policy)
    except Exception as e:
        cert_identity = self._extract_identity(sig_bundle.signing_certificate)
        error_msg = f"Signature verification failed: {e}"
        if cert_identity:
            error_msg += f" (Certificate identity: issuer={cert_identity.get('issuer')}, subject={cert_identity.get('subject')})"
        return VerificationResult(valid=False, errors=[error_msg])

    # 4. Extract the verified agent card from the authenticated DSSE payload.
    #    This is the source of truth, not the outer wrapper, which could
    #    have been modified independently of the Sigstore bundle.
    try:
        verified_card = self._extract_verified_card(payload)
    except Exception as e:
        return VerificationResult(valid=False, errors=[f"Failed to parse agent card from DSSE payload: {e}"])

    # 5. Extract identity from certificate
    identity = self._extract_identity(sig_bundle.signing_certificate)

    return VerificationResult(
        valid=True, agent_card=verified_card, certificate=sig_bundle.signing_certificate, identity=identity
    )

verify_file

verify_file(
    file_path: str | Path,
    constraints: IdentityConstraints | None = None,
) -> VerificationResult

Verify a signed Agent Card file.

PARAMETER DESCRIPTION
file_path

Path to signed Agent Card file

TYPE: str | Path

constraints

Optional identity constraints

TYPE: IdentityConstraints | None DEFAULT: None

RETURNS DESCRIPTION
VerificationResult

Verification result

Source code in sigstore_a2a/verifier.py
def verify_file(self, file_path: str | Path, constraints: IdentityConstraints | None = None) -> VerificationResult:
    """Verify a signed Agent Card file.

    Args:
        file_path: Path to signed Agent Card file
        constraints: Optional identity constraints

    Returns:
        Verification result
    """
    return self.verify_signed_card(file_path, constraints)

IdentityConstraints

IdentityConstraints(
    repository: str | None = None,
    workflow: str | None = None,
    identity: str | None = None,
    identity_provider: str | None = None,
)

Identity constraints for signature verification.

Initialize identity constraints.

PARAMETER DESCRIPTION
repository

Required repository (e.g., "owner/repo")

TYPE: str | None DEFAULT: None

workflow

Required workflow name or path

TYPE: str | None DEFAULT: None

identity

Required identity

TYPE: str | None DEFAULT: None

identity_provider

Required OIDC issuer

TYPE: str | None DEFAULT: None

Source code in sigstore_a2a/verifier.py
def __init__(
    self,
    repository: str | None = None,
    workflow: str | None = None,
    identity: str | None = None,
    identity_provider: str | None = None,
):
    """Initialize identity constraints.

    Args:
        repository: Required repository (e.g., "owner/repo")
        workflow: Required workflow name or path
        identity: Required identity
        identity_provider: Required OIDC issuer
    """
    self.repository = repository
    self.workflow = workflow
    self.identity = identity
    self.identity_provider = identity_provider

VerificationResult

VerificationResult(
    valid: bool,
    agent_card: AgentCard | None = None,
    certificate: Certificate | None = None,
    identity: dict[str, Any] | None = None,
    errors: list[str] | None = None,
)

Result of Agent Card verification.

Initialize verification result.

PARAMETER DESCRIPTION
valid

Whether verification succeeded

TYPE: bool

agent_card

Verified agent card (if valid)

TYPE: AgentCard | None DEFAULT: None

certificate

Signing certificate

TYPE: Certificate | None DEFAULT: None

identity

Extracted identity information

TYPE: dict[str, Any] | None DEFAULT: None

errors

List of verification errors

TYPE: list[str] | None DEFAULT: None

Source code in sigstore_a2a/verifier.py
def __init__(
    self,
    valid: bool,
    agent_card: AgentCard | None = None,
    certificate: x509.Certificate | None = None,
    identity: dict[str, Any] | None = None,
    errors: list[str] | None = None,
):
    """Initialize verification result.

    Args:
        valid: Whether verification succeeded
        agent_card: Verified agent card (if valid)
        certificate: Signing certificate
        identity: Extracted identity information
        errors: List of verification errors
    """
    self.valid = valid
    self.agent_card = agent_card
    self.certificate = certificate
    self.identity = identity or {}
    self.errors = errors or []

__bool__

__bool__() -> bool

Return True if verification was successful.

Source code in sigstore_a2a/verifier.py
def __bool__(self) -> bool:
    """Return True if verification was successful."""
    return self.valid

Usage Examples

Basic Verification

from sigstore_a2a import AgentCardVerifier

verifier = AgentCardVerifier(
    oidc_issuer="https://token.actions.githubusercontent.com"
)

result = verifier.verify_file("signed-card.json")

if result.valid:
    print("✓ Signature verified!")
    print(f"  Agent: {result.agent_card.name}")
    print(f"  Signed by: {result.identity.get('subject')}")
else:
    print("✗ Verification failed:")
    for error in result.errors:
        print(f"  - {error}")

Verification with Constraints

from sigstore_a2a import AgentCardVerifier
from sigstore_a2a.verifier import IdentityConstraints

verifier = AgentCardVerifier(
    oidc_issuer="https://token.actions.githubusercontent.com"
)

# Define constraints
constraints = IdentityConstraints(
    repository="sigstore/sigstore-a2a",
    workflow="Release"
)

result = verifier.verify_file("signed-card.json", constraints)

Verifying with Google Identity

verifier = AgentCardVerifier(
    identity="user@example.com",
    oidc_issuer="https://accounts.google.com"
)

result = verifier.verify_file("signed-card.json")

Using Staging Environment

verifier = AgentCardVerifier(
    oidc_issuer="https://token.actions.githubusercontent.com",
    staging=True
)

Using Custom Trust Configuration

from pathlib import Path

verifier = AgentCardVerifier(
    oidc_issuer="https://my-idp.example.com",
    trust_config=Path("/path/to/trust-config.json")
)

Extracting Identity Information

result = verifier.verify_file("signed-card.json")

if result.valid:
    identity = result.identity

    print(f"Issuer: {identity.get('issuer')}")
    print(f"Subject: {identity.get('subject')}")
    print(f"Repository: {identity.get('github_workflow_repository')}")
    print(f"Workflow: {identity.get('github_workflow_name')}")
    print(f"Commit SHA: {identity.get('github_workflow_sha')}")

Identity Providers

Common OIDC issuers for verification:

Provider Issuer URL
GitHub Actions https://token.actions.githubusercontent.com
Google https://accounts.google.com
Microsoft https://login.microsoftonline.com/{tenant}/v2.0
GitLab https://gitlab.com