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.3.0.tar.gz (42.0 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.3.0-py3-none-any.whl (34.3 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for agentpin-0.3.0.tar.gz
Algorithm Hash digest
SHA256 9c6998b46ef855240d3143e0182c7470745bfab59207c50b1f56249e3499a2e6
MD5 4fac10fd8620810bde43b5b429f9a536
BLAKE2b-256 ab505971d1dbf9c3403dba871185eb0f16a454d5bf1ea47eaf7e5f760848bfe5

See more details on using hashes here.

File details

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

File metadata

  • Download URL: agentpin-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 34.3 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.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5ddef1f127de80d86a426f157bf7b8860847fb3bd5ebab47e6025713bb43ce50
MD5 7dd0e7fecac8c254596ab8afde3d5eff
BLAKE2b-256 220ea4bd2190afaf8d04de7b456d6a3b258165d7ff101befe4afc7d2640b3bd5

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