Skip to main content

Official Python SDK for Tether.name - AI agent identity verification

Project description

Tether.name Python SDK

PyPI Python versions License: MIT

Official Python SDK for Tether.name โ€” cryptographic identity verification for AI agents.

Tether lets AI agents prove their identity using RSA-2048 digital signatures, providing a secure, verifiable way to establish trust in AI-to-AI and AI-to-human interactions.

๐Ÿš€ Quick Start

Installation

pip install tether-name

Basic Usage

from tether_name import TetherClient

# Initialize with your credentials
client = TetherClient(
    credential_id="your-credential-id",
    private_key_path="/path/to/your/private-key.der"
)

# Verify your agent's identity
result = client.verify()

if result.verified:
    print(f"โœ… Verified as: {result.agent_name}")
    print(f"๐Ÿ“ง Email: {result.email}")
    print(f"๐Ÿ”— Verification URL: {result.verify_url}")
else:
    print(f"โŒ Verification failed: {result.error}")

Agent Management

One line to start managing agents programmatically:

from tether_name import TetherClient

client = TetherClient(api_key="sk-tether-name-...")

# Create, list, and delete agents
agent = client.create_agent("my-bot")
agents = client.list_agents()
client.delete_agent(agent.id)

๐Ÿ“– How Tether Works

Tether.name provides cryptographic identity verification for AI agents through a simple 3-step process:

  1. Register: Create an agent identity at tether.name and get your credential ID and RSA-2048 private key
  2. Sign: Your agent signs a cryptographic challenge using its private key
  3. Verify: The signature proves your agent's identity to others

This creates unforgeable digital identity that anyone can verify.

๐Ÿ”ง Configuration

Authentication

The SDK supports two authentication modes:

API Key โ€” for agent management (create, list, delete):

client = TetherClient(api_key="sk-tether-name-...")

Private Key โ€” for identity verification (sign, verify):

client = TetherClient(
    credential_id="your-credential-id",
    private_key_path="/path/to/key.der"
)

Both โ€” for full access:

client = TetherClient(
    api_key="sk-tether-name-...",
    credential_id="your-credential-id",
    private_key_path="/path/to/key.der"
)

Environment Variables

Set these environment variables to avoid hardcoding credentials:

export TETHER_API_KEY="sk-tether-name-..."
export TETHER_CREDENTIAL_ID="your-credential-id"
export TETHER_PRIVATE_KEY_PATH="/path/to/your/key.der"

Then initialize without parameters:

client = TetherClient()  # Uses environment variables

Key Formats

The SDK supports multiple private key formats:

# From file path (PEM or DER)
client = TetherClient(
    credential_id="...",
    private_key_path="/path/to/key.der"
)

# From PEM string
client = TetherClient(
    credential_id="...",
    private_key_pem="-----BEGIN PRIVATE KEY-----\n..."
)

# From DER bytes  
with open("key.der", "rb") as f:
    key_bytes = f.read()

client = TetherClient(
    credential_id="...",
    private_key_der=key_bytes
)

๐Ÿ“š API Reference

TetherClient

Main client for Tether.name API interactions.

Constructor

TetherClient(
    credential_id: Optional[str] = None,
    private_key_path: Optional[Union[str, Path]] = None,
    private_key_pem: Optional[Union[str, bytes]] = None,
    private_key_der: Optional[bytes] = None,
    timeout: float = 30.0,
    api_key: Optional[str] = None
)
Parameter Env var Description
api_key TETHER_API_KEY API key for agent management operations
credential_id TETHER_CREDENTIAL_ID Credential ID for identity verification
private_key_path TETHER_PRIVATE_KEY_PATH Path to RSA-2048 private key (PEM or DER)
private_key_pem โ€” PEM-encoded private key string
private_key_der โ€” DER-encoded private key bytes

When api_key is set, credential_id and private key parameters become optional (only needed for verify/sign operations).

Methods

verify() -> VerificationResult

Perform complete identity verification in one call.

result = client.verify()
print(result.verified)      # bool: True if verified
print(result.agent_name)    # str: Your agent's display name
print(result.verify_url)    # str: Public verification URL
print(result.email)         # str: Registered email address
request_challenge() -> str

Request a cryptographic challenge from Tether.

challenge = client.request_challenge()
print(challenge)  # "550e8400-e29b-41d4-a716-446655440000"
sign(challenge: str) -> str

Sign a challenge with your private key.

challenge = client.request_challenge()
signature = client.sign(challenge)
print(signature)  # URL-safe base64 signature (no padding)
submit_proof(challenge: str, proof: str) -> VerificationResult

Submit signed challenge for verification.

challenge = client.request_challenge()
signature = client.sign(challenge)
result = client.submit_proof(challenge, signature)
create_agent(agent_name: str, description: str = "") -> Agent

Create a new agent. Requires API key authentication.

agent = client.create_agent("my-bot", description="My automated agent")
print(agent.id)                # Agent ID
print(agent.agent_name)        # "my-bot"
print(agent.registration_token) # Token for agent registration
list_agents() -> list[Agent]

List all agents. Requires API key authentication.

agents = client.list_agents()
for agent in agents:
    print(f"{agent.agent_name} (created {agent.created_at})")
delete_agent(agent_id: str) -> bool

Delete an agent. Requires API key authentication.

client.delete_agent("agent-id-here")

Agent

Agent object returned by management operations.

@dataclass
class Agent:
    id: str                        # Unique agent ID
    agent_name: str                # Agent display name
    description: str               # Agent description
    created_at: int                # Creation time (epoch ms)
    registration_token: str = ""   # Token for agent registration
    last_verified_at: int = 0      # Last verification time (epoch ms)

VerificationResult

Result object returned by verification operations.

@dataclass
class VerificationResult:
    verified: bool                           # True if verification succeeded
    agent_name: Optional[str] = None         # Agent's display name
    verify_url: Optional[str] = None         # Public verification URL
    email: Optional[str] = None              # Registered email
    registered_since: Optional[datetime] = None  # Registration date
    error: Optional[str] = None              # Error message if failed
    challenge: Optional[str] = None          # Original challenge

๐Ÿ” Step-by-Step Example

For more control, you can break down the verification process:

from tether_name import TetherClient, TetherAPIError, TetherVerificationError

try:
    client = TetherClient(
        credential_id="your-credential-id",
        private_key_path="/path/to/key.der"
    )
    
    # Step 1: Request a challenge
    print("๐Ÿ“ก Requesting challenge...")
    challenge = client.request_challenge()
    print(f"๐Ÿ”ข Challenge: {challenge}")
    
    # Step 2: Sign the challenge  
    print("โœ๏ธ  Signing challenge...")
    signature = client.sign(challenge)
    print(f"๐Ÿ“ Signature: {signature[:32]}...")
    
    # Step 3: Submit proof
    print("๐Ÿ“ค Submitting proof...")
    result = client.submit_proof(challenge, signature)
    
    if result.verified:
        print(f"โœ… Successfully verified as {result.agent_name}")
        print(f"๐Ÿ”— Share this verification: {result.verify_url}")
    else:
        print(f"โŒ Verification failed: {result.error}")
        
except TetherAPIError as e:
    print(f"๐ŸŒ API Error: {e.message}")
    if e.status_code:
        print(f"๐Ÿ“Š Status: {e.status_code}")
        
except TetherVerificationError as e:
    print(f"๐Ÿ”’ Verification Error: {e.message}")
    
finally:
    client.close()  # Clean up HTTP connections

๐Ÿงช Testing

The SDK includes comprehensive unit tests that don't hit the live API:

# Install development dependencies
pip install -e ".[dev]"

# Run tests
pytest

# Run with coverage
pytest --cov=tether_name

๐Ÿ”— Context Manager Support

Use TetherClient as a context manager for automatic cleanup:

with TetherClient(credential_id="...", private_key_path="...") as client:
    result = client.verify()
    print(f"Verified: {result.verified}")
# HTTP client automatically closed

๐Ÿ›ก๏ธ Security Notes

  • Private Key Security: Never commit private keys to version control or share them publicly
  • API Key Security: API keys are hashed before storage. The sk-tether-name- prefix enables leak detection. Revoke compromised keys immediately
  • Key Format: Tether requires RSA-2048 keys. Other key sizes will be rejected
  • Challenge Uniqueness: Each verification uses a unique challenge to prevent replay attacks
  • Signature Algorithm: Uses SHA256withRSA (PKCS#1 v1.5 padding) as specified by Tether

๐Ÿ› Error Handling

The SDK provides specific exception types for different error conditions:

from tether_name import (
    TetherError,           # Base exception
    TetherAPIError,        # API request failures  
    TetherVerificationError,  # Verification failures
    TetherKeyError,        # Private key issues
)

try:
    result = client.verify()
except TetherAPIError as e:
    # Handle API connectivity or server errors
    print(f"API Error {e.status_code}: {e.message}")
except TetherVerificationError as e:
    # Handle verification failures (invalid signature, etc.)
    print(f"Verification failed: {e.message}")
except TetherKeyError as e:
    # Handle private key loading or format errors
    print(f"Key error: {e.message}")
except TetherError as e:
    # Handle any other Tether-related errors
    print(f"Tether error: {e.message}")

๐Ÿ“‹ Requirements

  • Python: 3.8+
  • Dependencies: httpx>=0.20.0, cryptography>=3.4.0
  • Key Format: RSA-2048 private key (PEM or DER)

๐Ÿ“ฆ Publishing

Published to PyPI automatically via GitHub Actions when a release is created (uses trusted publishing).

Version checklist

Update the version in:

  1. pyproject.toml โ†’ version
  2. src/tether_name/__init__.py โ†’ __version__

Steps

  1. Update version numbers above (they must match)
  2. Commit and push to main
  3. Create a GitHub release with a matching tag (e.g. v1.0.0)
  4. CI builds and publishes to PyPI automatically

Manual publish (if needed)

pip install build twine
python -m build
twine upload dist/*

๐Ÿ“„ License

MIT License - see LICENSE file for details.

๐Ÿค Contributing

Contributions welcome! Please see the GitHub repository for details.

๐Ÿ”— Links


Ready to get started? Register your AI agent at tether.name and start building with cryptographic identity verification! ๐Ÿš€

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

tether_name-1.0.5.tar.gz (13.3 kB view details)

Uploaded Source

Built Distribution

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

tether_name-1.0.5-py3-none-any.whl (12.7 kB view details)

Uploaded Python 3

File details

Details for the file tether_name-1.0.5.tar.gz.

File metadata

  • Download URL: tether_name-1.0.5.tar.gz
  • Upload date:
  • Size: 13.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for tether_name-1.0.5.tar.gz
Algorithm Hash digest
SHA256 1f813c337a1a47853f2c7cdc9757ce42288d7c1f276095aab7a072e7b8f41a4d
MD5 3ea55bcd201390210a205951307f310d
BLAKE2b-256 2fb0cf8413d13b4897b38f4e2011da38149614b80459f2e2f31685d6d136059d

See more details on using hashes here.

Provenance

The following attestation bundles were made for tether_name-1.0.5.tar.gz:

Publisher: publish.yml on tether-name/tether-name-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file tether_name-1.0.5-py3-none-any.whl.

File metadata

  • Download URL: tether_name-1.0.5-py3-none-any.whl
  • Upload date:
  • Size: 12.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for tether_name-1.0.5-py3-none-any.whl
Algorithm Hash digest
SHA256 f0573ef1ff4647993a8de605852e17e39c225e31bb72c85c1177ed5232375ca0
MD5 f65c08d62fe1068670924ede3579fa08
BLAKE2b-256 f42a35741849763864f0fe28aa2621ccdfca0e631c4c4e70cb6f13d36ae8ab9b

See more details on using hashes here.

Provenance

The following attestation bundles were made for tether_name-1.0.5-py3-none-any.whl:

Publisher: publish.yml on tether-name/tether-name-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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