AgentMarqueVerifier

The AgentMarqueVerifier validates SD-JWT presentations from agent credentials. It resolves issuer DIDs, checks signatures and holder binding, enforces trust policies, and optionally verifies revocation status.

from agentmarque import AgentMarqueVerifier
CLASSAgentMarqueVerifier(trusted_issuers, cache_ttl)

Constructor

Create a verifier instance with a set of trusted issuer DIDs. Only credentials signed by these issuers will pass the issuer_trusted check.

Required attributes

  • Name
    trusted_issuers
    Type
    list[str]
    Description

    List of issuer DIDs to trust (e.g., ["did:key:z6Mk...", "did:web:registry.agentmarque.com"]). Presentations from issuers not in this list will fail the issuer_trusted check.

Optional attributes

  • Name
    cache_ttl
    Type
    int
    Description

    Time-to-live in seconds for cached DID documents and status list responses. Defaults to 300.

Example

verifier = AgentMarqueVerifier(
    trusted_issuers=[
        "did:key:z6MkRegistry...",
        "did:web:registry.agentmarque.com",
    ],
    cache_ttl=600,
)

METHODverifier.verify(presentation, expected_nonce, expected_audience, min_tier, min_reputation, required_capabilities, check_revocation)

verify

Verify an SD-JWT presentation synchronously. Runs all checks (signature, holder binding, dates, issuer trust, nonce, audience, revocation, policy) and returns a VerificationResult.

Returns a VerificationResult. Check result.valid for the overall outcome, result.checks for individual check results, and result.errors for failure details.

Required attributes

  • Name
    expected_nonce
    Type
    str
    Description

    The nonce your service sent to the holder. Checked against the key-binding JWT's nonce claim.

  • Name
    expected_audience
    Type
    str
    Description

    Your service's identifier (DID or URL). Checked against the key-binding JWT's aud claim.

Optional attributes

  • Name
    min_tier
    Type
    int
    Description

    Minimum required verification tier. Defaults to 0.

  • Name
    min_reputation
    Type
    float
    Description

    Minimum required reputation score (0.0 to 1.0). Defaults to 0.0.

  • Name
    required_capabilities
    Type
    list[str] | None
    Description

    Capabilities the agent must possess. If provided, all listed capabilities must be present in the disclosed claims. Defaults to None.

  • Name
    check_revocation
    Type
    bool
    Description

    Whether to check the credential status list for revocation. Defaults to True.

Example

result = verifier.verify(
    presentation=jwt_string,
    expected_nonce="abc123",
    expected_audience="did:web:api.example.com",
    min_tier=1,
    min_reputation=0.5,
    required_capabilities=["data-query"],
)

if result.valid:
    print(result.claims["agentName"])
    print(result.claims["capabilities"])
else:
    for err in result.errors:
        print(f"Failed: {err}")

Check individual results

result = verifier.verify(
    jwt_string, "nonce", "did:web:my-service.com",
)

print(result.checks.signature)      # True
print(result.checks.cnf_match)      # True
print(result.checks.holder_bound)   # True
print(result.checks.dates)          # True
print(result.checks.issuer_trusted) # True
print(result.checks.status)         # True
print(result.checks.nonce)          # True
print(result.checks.audience)       # True
print(result.checks.policy)         # True

METHODverifier.verify_vc(credential, min_tier, min_reputation, required_capabilities, check_revocation) -> VerificationResult

verify_vc

Verify a raw VC dictionary (issuer signature only). This checks the Data Integrity proof, dates, revocation, and policy — but does not prove the presenter is the credential subject.

Use verify() with a holder-bound SD-JWT presentation for full verification. Use verify_vc() only for inspecting credential authenticity without a presentation context.

Returns a VerificationResult. The holder_bound, cnf_match, nonce, and audience fields will be None.

  • Name
    credential
    Type
    dict
    Description

    The full W3C VC as a dictionary (with proof field).

  • Name
    min_tier
    Type
    int
    Description

    Minimum verification tier. Defaults to 0.

  • Name
    min_reputation
    Type
    float
    Description

    Minimum reputation score. Defaults to 0.0.

  • Name
    required_capabilities
    Type
    list[str] | None
    Description

    Required capabilities. Defaults to None.

  • Name
    check_revocation
    Type
    bool
    Description

    Whether to check revocation. Defaults to True.

Example

result = verifier.verify_vc(
    credential=cred.vc,
    check_revocation=False,
)

if result.valid:
    print("Credential is authentic")
    print(result.checks.holder_bound)  # None

Verification Order

The verifier runs checks in a fixed order. Each step must pass before the next is attempted. If a step fails, subsequent steps are skipped and the result reflects the failure.

  1. Issuer signature -- Verify the SD-JWT issuer signature using the resolved public key.
  2. Holder binding -- Verify the key-binding JWT signature, confirming the presenter holds the private key.
  3. cnf match -- Confirm the key-binding JWT's signing key matches the credential's cnf claim.
  4. Nonce -- If expected_nonce is provided, check the key-binding JWT's nonce claim.
  5. Audience -- If expected_audience is provided, check the key-binding JWT's aud claim.
  6. Dates -- Validate iat, exp, and nbf claims against the current time.
  7. Revocation -- If check_revocation is enabled and the credential includes a status list, fetch and check revocation status. Fails closed: if the status list cannot be fetched (network error, timeout), the check fails rather than passing by default.
  8. Policy -- Evaluate min_tier, min_reputation, and required_capabilities against disclosed claims.

The issuer_trusted check runs independently and does not block other checks.

VerificationCheck fields

# All fields on VerificationCheck
result.checks.signature      # bool — issuer signature valid
result.checks.cnf_match      # bool | None — cnf claim present and parseable
result.checks.holder_bound   # bool | None — KB-JWT signature matches cnf key
result.checks.status         # bool | None — not revoked
result.checks.dates          # bool — within nbf/exp window
result.checks.issuer_trusted # bool — issuer DID in trusted list
result.checks.nonce          # bool | None — KB-JWT nonce matches
result.checks.audience       # bool | None — KB-JWT audience matches
result.checks.policy         # bool — min tier/rep/capabilities

DID Resolution

The verifier resolves issuer DIDs to retrieve public keys for signature verification. Two DID methods are supported:

  • did:key -- Resolved locally. The public key is decoded directly from the DID string using z-base58 multibase encoding. No network request required.
  • did:web -- Resolved via HTTP. The verifier fetches the DID document from https://<domain>/.well-known/did.json (or the appropriate path for DIDs with additional path components). Responses are cached according to cache_ttl.

Resolution failures (network errors, malformed documents) cause the signature check to fail with a descriptive error in result.errors.

Trusted issuer examples

verifier = AgentMarqueVerifier(
    trusted_issuers=[
        # Local resolution (no network)
        "did:key:z6MkRegistry...",
        # HTTP resolution (cached)
        "did:web:registry.agentmarque.com",
    ],
)

Policy Enforcement

Policy enforcement runs after signature, holder binding, and date validation. The policy field on VerificationCheck is True only when all policy constraints are satisfied:

  • min_tier -- The disclosed verificationTier claim must be greater than or equal to the specified minimum.
  • min_reputation -- The disclosed reputationScore claim must be greater than or equal to the specified minimum.
  • required_capabilities -- Every capability in the list must appear in the disclosed capabilities claim.

If a required claim is not disclosed (due to selective disclosure), the policy check fails and an error message indicates which claim was missing.

Example

# Strict policy: tier 2+, high reputation,
# specific capabilities
result = verifier.verify(
    presentation=jwt_string,
    expected_audience="did:web:api.example.com",
    min_tier=2,
    min_reputation=0.8,
    required_capabilities=[
        "invoice-processing",
        "payments",
    ],
)

if not result.checks.policy:
    print("Policy check failed:")
    for err in result.errors:
        print(f"  - {err}")

Was this page helpful?