Skip to main content

Agentic Profile Authentication Library

Project description

Agentic Profile Authentication

A Python library for handling authentication and verification of AI agent profiles using Decentralized Identifiers (DIDs).

Features

  • DID resolution for web, HTTP, and HTTPS methods
  • NEW: Built-in web DID resolver that follows the did:web specification
  • Challenge-response authentication flow
  • JWT-based attestation with EdDSA signatures
  • Configurable caching of resolved profiles
  • Async/await support for all operations
  • Type hints and Pydantic models for data validation

Installation

pip install agentic-profile-auth

Quick Start

Basic Usage

from agentic_profile_auth import HttpDidResolver, InMemoryAgenticProfileStore

# Create a resolver with caching
store = InMemoryAgenticProfileStore()
resolver = HttpDidResolver(store=store)

# Resolve a DID
async def resolve_did():
    profile, metadata = await resolver.resolve("did:web:example.com")
    print(f"Resolved profile: {profile}")
    print(f"Resolution metadata: {metadata}")

# Handle authentication
from agentic_profile_auth import handle_authorization

async def authenticate_request(auth_header: str):
    try:
        session = await handle_authorization(auth_header, store, resolver)
        print(f"Authenticated session: {session}")
    except ValueError as e:
        print(f"Authentication failed: {e}")

Web DID Resolution

The library now includes a built-in web DID resolver that follows the did:web specification:

import aiohttp
from agentic_profile_auth import (
    HttpDidResolver, 
    get_web_resolver, 
    InMemoryAgenticProfileStore
)

async def resolve_web_did():
    # Create a session for HTTP requests
    async with aiohttp.ClientSession() as session:
        
        # Create a web DID resolver
        web_resolver = get_web_resolver(session)
        
        # Create a store for caching
        store = InMemoryAgenticProfileStore()
        
        # Create the main DID resolver with web support
        resolver = HttpDidResolver(
            session=session,
            store=store,
            registry=web_resolver
        )
        
        # Resolve web DIDs
        dids = [
            "did:web:example.com",                    # https://example.com/.well-known/did.json
            "did:web:example.com:user",               # https://example.com/user/did.json
            "did:web:localhost:8080",                 # http://localhost:8080/.well-known/did.json
            "did:web:example.com:user:profile"        # https://example.com/user/profile/did.json
        ]
        
        for did in dids:
            profile, metadata = await resolver.resolve(did)
            if profile:
                print(f"✅ Resolved {did}")
            else:
                print(f"❌ Failed to resolve {did}: {metadata.get('error')}")

Web DID URL Conversion

You can also convert web DIDs to their corresponding URLs:

from agentic_profile_auth import web_did_to_url

# Convert web DIDs to URLs
urls = [
    web_did_to_url("did:web:example.com"),           # https://example.com/.well-known/did.json
    web_did_to_url("did:web:example.com:user"),      # https://example.com/user/did.json
    web_did_to_url("did:web:localhost:8080"),        # http://localhost:8080/.well-known/did.json
]

for url in urls:
    print(url)

Authentication Flow

  1. Challenge Creation

    • Server creates a challenge with a unique ID and secret
    • Challenge is stored in the session store
    • Challenge is sent to the client
  2. Client Authentication

    • Client resolves the server's DID
    • Client creates a JWT with:
      • Challenge ID and secret
      • Client's DID and verification method
      • EdDSA signature using the client's private key
  3. Server Verification

    • Server validates the JWT signature
    • Server verifies the challenge
    • Server resolves the client's DID
    • Server verifies the client's verification method

API Reference

DID Resolution

class HttpDidResolver:
    def __init__(self, store: Optional[AgenticProfileStore] = None, registry: Optional[Dict[str, ResolverRegistry]] = None):
        """Create a new HTTP DID resolver with optional caching and method-specific resolvers."""
        pass

    async def resolve(self, did: str) -> Tuple[Dict[str, Any], Dict[str, Any]]:
        """Resolve a DID to its profile document."""
        pass

class WebDidResolver:
    """Web DID resolver that fetches DID documents from .well-known/did.json endpoints"""
    
    def __init__(self, session: Optional[aiohttp.ClientSession] = None):
        """Initialize the web DID resolver."""
        pass

    async def resolve(self, did: str, parsed: ParsedDID, options: Dict[str, Any]) -> DIDResolutionResult:
        """Resolve a web DID to its DID document."""
        pass

Web DID Functions

def get_web_resolver(session: Optional[aiohttp.ClientSession] = None) -> Dict[str, WebDidResolver]:
    """Get a web DID resolver for use with HttpDidResolver."""
    pass

def web_did_to_url(did: str, parsed: Optional[ParsedDID] = None) -> str:
    """Convert a web DID to its corresponding URL."""
    pass

def select_protocol(path: str) -> str:
    """Select the appropriate protocol (HTTP for localhost, HTTPS for others)."""
    pass

Authentication

async def create_challenge(store: ClientAgentSessionStore) -> AgenticChallenge:
    """Create a new authentication challenge."""
    pass

async def handle_authorization(
    auth_header: str,
    store: ClientAgentSessionStore,
    resolver: DidResolver
) -> ClientAgentSession:
    """Handle an authorization header and return the authenticated session."""
    pass

Models

  • AgenticProfile: Represents a DID profile document
  • AgentService: Represents an agent service in a profile
  • VerificationMethod: Represents a verification method in a profile
  • ClientAgentSession: Represents an authenticated session
  • AgenticChallenge: Represents an authentication challenge
  • AgenticJwsHeader: JWT header for agentic authentication
  • AgenticJwsPayload: JWT payload for agentic authentication

Web DID Specification Support

The web DID resolver implements the did:web specification and supports:

  • Basic web DIDs: did:web:example.comhttps://example.com/.well-known/did.json
  • Subdomain DIDs: did:web:example.com:userhttps://example.com/user/did.json
  • Multi-level DIDs: did:web:example.com:user:profilehttps://example.com/user/profile/did.json
  • Localhost support: did:web:localhost:8080http://localhost:8080/.well-known/did.json
  • Query parameters: did:web:example.com?version=1https://example.com/.well-known/did.json?version=1

The resolver automatically:

  • Selects HTTP for localhost and HTTPS for other domains
  • Handles HTTP errors and network failures gracefully
  • Determines content type based on @context presence
  • Supports both application/did+json and application/did+ld+json formats

Development

Setup

# Clone the repository
git clone https://github.com/yourusername/agentic-profile-auth.git
cd agentic-profile-auth

# Create a virtual environment
python -m venv venv
source venv/bin/activate  # or `venv\Scripts\activate` on Windows

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

Running Tests

pytest

Code Style

The project uses:

  • Black for code formatting
  • MyPy for type checking
  • Ruff for linting

License

MIT License - see LICENSE file for details

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

agentic_profile_auth-0.1.3.tar.gz (24.8 kB view details)

Uploaded Source

Built Distribution

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

agentic_profile_auth-0.1.3-py3-none-any.whl (20.4 kB view details)

Uploaded Python 3

File details

Details for the file agentic_profile_auth-0.1.3.tar.gz.

File metadata

  • Download URL: agentic_profile_auth-0.1.3.tar.gz
  • Upload date:
  • Size: 24.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.10.4

File hashes

Hashes for agentic_profile_auth-0.1.3.tar.gz
Algorithm Hash digest
SHA256 9451fef5cf8e70532dd5d7f4755910aa0d7e92d3408daabe14b36ca6cda9f660
MD5 fb22c6602fa88083f0245fcb2e17c7eb
BLAKE2b-256 59cc5cecc8e056f0a4de8494f7bd1f470e1743f726214f1453de0878192305c2

See more details on using hashes here.

File details

Details for the file agentic_profile_auth-0.1.3-py3-none-any.whl.

File metadata

File hashes

Hashes for agentic_profile_auth-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 d8bb8d7a19156fa47c80896c4b6cad224b824526a8409e74ee88a7806ab93c04
MD5 be08791ab385f888ce46ffdb8eab6340
BLAKE2b-256 2782dab1256d2bfcdecd71229deece65ac5e110cce19f8585cfb3687b5aa46d6

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