Skip to main content

Domain-anchored cryptographic identity protocol for AI agents

Project description

agentpin

Domain-anchored cryptographic identity for AI agents. Part of the ThirdKey trust stack (SchemaPinAgentPinSymbiont).

Requires Python >= 3.8.

Install

pip install agentpin

Quick Start

from agentpin import (
    generate_key_pair,
    generate_key_id,
    pem_to_jwk,
    issue_credential,
    verify_credential_offline,
    build_discovery_document,
    KeyPinStore,
    Capability,
)

# Generate keys
private_key_pem, public_key_pem = generate_key_pair()
kid = generate_key_id(public_key_pem)
jwk = pem_to_jwk(public_key_pem, kid)

# Build discovery document
discovery = build_discovery_document(
    "example.com", "maker", [jwk],
    [{
        "agent_id": "urn:agentpin:example.com:my-agent",
        "name": "My Agent",
        "capabilities": ["read:data", "write:reports"],
        "status": "active",
    }],
    2,
)

# Issue credential
credential = issue_credential(
    private_key_pem=private_key_pem,
    kid=kid,
    issuer="example.com",
    agent_id="urn:agentpin:example.com:my-agent",
    audience="verifier.com",
    capabilities=[
        Capability.create("read", "data"),
        Capability.create("write", "reports"),
    ],
    constraints=None,
    delegation_chain=None,
    ttl_secs=3600,
)

# Verify credential
result = verify_credential_offline(
    credential_jwt=credential,
    discovery=discovery,
    revocation=None,
    pin_store=KeyPinStore(),
    audience="verifier.com",
)

if result.valid:
    print(f"Agent: {result.agent_id}")
    print(f"Capabilities: {result.capabilities}")
    print(f"Key pinning: {result.key_pinning}")
else:
    print(f"Failed: {result.error_code} - {result.error_message}")

Features

  • ES256 (ECDSA P-256) cryptographic credentials
  • Domain-anchored .well-known/agent-identity.json discovery
  • 12-step verification protocol
  • Maker-deployer delegation chains
  • Capability-scoped credentials with constraints
  • TOFU key pinning (compatible with SchemaPin)
  • Credential, agent, and key-level revocation
  • Mutual authentication with challenge-response
  • Trust bundles for air-gapped and enterprise verification (v0.2.0)

API

Key Management

generate_key_pair()              # → (private_key_pem, public_key_pem)
generate_key_id(public_key_pem)  # → kid (hex SHA-256)
pem_to_jwk(public_key_pem, kid)  # → JWK dict
jwk_to_pem(jwk)                  # → PEM string

Credentials

issue_credential(
    private_key_pem, kid, issuer, agent_id, audience,
    capabilities, constraints, delegation_chain, ttl_secs
)
# → compact JWT string

Verification

# Offline (with local discovery document)
verify_credential_offline(jwt, discovery, revocation, pin_store, audience, config)
# → VerificationResult(valid, agent_id, issuer, capabilities, key_pinning, ...)

# Online (auto-fetches discovery from issuer domain)
verify_credential(jwt, pin_store, audience, config)

Discovery & Revocation

build_discovery_document(entity, entity_type, public_keys, agents, max_delegation_depth)
build_revocation_document(entity)
add_revoked_credential(doc, jti, reason)
add_revoked_agent(doc, agent_id, reason)
add_revoked_key(doc, kid, reason)

Mutual Authentication

from agentpin import create_challenge, create_response, verify_response

challenge = create_challenge(verifier_credential)
response = create_response(challenge, private_key_pem, kid)
verify_response(response, challenge["nonce"], public_key_pem)

Key Pinning

from agentpin import KeyPinStore, PinningResult

store = KeyPinStore()
result = store.check_and_pin(domain, jwk)  # PinningResult.FIRST_USE | MATCHED | CHANGED
store.add_key(domain, jwk)                  # allow key rotation
json_str = store.to_json()                  # persist
restored = KeyPinStore.from_json(json_str)  # restore

Trust Bundles (v0.2.0)

from agentpin import (
    create_trust_bundle,
    find_bundle_discovery,
    verify_credential_with_bundle,
    save_trust_bundle,
    load_trust_bundle,
)

# Create a bundle with pre-loaded discovery documents
bundle = create_trust_bundle()
bundle["documents"].append(discovery)
bundle["revocations"].append(revocation)

# Verify without any HTTP calls
result = verify_credential_with_bundle(
    credential, bundle, pin_store=KeyPinStore(), audience="verifier.com"
)

# Save / load bundles to disk
save_trust_bundle(bundle, "trust-bundle.json")
bundle = load_trust_bundle("trust-bundle.json")

Configuration

from agentpin import VerifierConfig

config = VerifierConfig(
    clock_skew_secs=60,   # allow 60s time skew
    max_ttl_secs=86400,   # max 24h credential lifetime
)

Cross-Language Interoperability

Credentials issued by the Python package can be verified by the Rust and JavaScript implementations, and vice versa. All implementations use DER-encoded ECDSA signatures and identical JSON field names.

License

MIT — ThirdKey.ai

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

agentpin-0.2.0.tar.gz (25.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

agentpin-0.2.0-py3-none-any.whl (21.8 kB view details)

Uploaded Python 3

File details

Details for the file agentpin-0.2.0.tar.gz.

File metadata

  • Download URL: agentpin-0.2.0.tar.gz
  • Upload date:
  • Size: 25.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for agentpin-0.2.0.tar.gz
Algorithm Hash digest
SHA256 194128f90cdb693d3a8c8c1000bdc00e60b9b1ba1667d4136749f8a9c80c3b1b
MD5 8f3929d853a82ae72582cee3bfc1ec31
BLAKE2b-256 72f1cfcced9bd48dc33308edd5f45ada72323e64f36b082701209843dd93d372

See more details on using hashes here.

File details

Details for the file agentpin-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: agentpin-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 21.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for agentpin-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 927ce2ea1c0d072c68780c59b8d7f9961381647982d26e6da47841d346c7d1e0
MD5 8ff79913eea61edb8701e811833aa174
BLAKE2b-256 ddbdddcca9fcd2cab4ba30813a4ad1bf0fde3985d0ae60b26ee5797a88ff28d1

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page