A2A Security

Secure A2A endpoints with authentication, authorization, and access control

A2A security enables authentication and authorization for agent-to-agent communication, protecting endpoints while maintaining protocol compliance.

python
from praisonaiagents import Agent, A2A

agent = Agent(name="secure-agent", instructions="Serve A2A requests only to authenticated clients.")

agent.start("Process this authenticated A2A message.")

The user exposes an A2A endpoint; only clients with valid credentials can discover the agent and send JSON-RPC requests.

Diagram

A2A Security Flow

Valid

Invalid

🧠 Agent Client

🔒 Auth Check

📡 A2A Endpoint

❌ 401 Denied

✅ Response

🔍 Discovery

📋 Agent Card


Quick Start

  1. Basic Bearer Token

    Protect your A2A endpoint with a simple bearer token:

    python
    from praisonaiagents import Agent, A2A
    
    agent = Agent(
        name="Secure Agent", 
        role="Helper", 
        goal="Help users securely"
    )
    
    a2a = A2A(
        agent=agent,
        auth_token="sk-my-secret-key"
    )
    
    a2a.serve(port=8000)
  2. Client Authentication

    Connect to protected endpoints using authorization headers:

    python
    import requests
    
    # Authenticated request
    response = requests.post(
        "http://localhost:8000/a2a",
        headers={
            "Authorization": "Bearer sk-my-secret-key",
            "Content-Type": "application/json"
        },
        json={
            "jsonrpc": "2.0",
            "method": "message/send",
            "id": "1",
            "params": {
                "message": {
                    "role": "user",
                    "parts": [{"text": "Hello"}]
                }
            }
        }
    )

How It Works

Diagram
PraisonAI AgentA2A ServerAgent ClientPraisonAI AgentA2A ServerAgent ClientDiscovery (Always Public)Authenticated Interactionalt[Valid Token][Invalid Token]GET /.well-known/agent.jsonAgent Card (no auth required)POST /a2a + Bearer TokenVerify TokenProcess RequestResponseSuccess Response401 Unauthorized
ComponentSecurity LevelPurpose
Discovery EndpointPublicAgent card per A2A spec
A2A EndpointProtectedAuthenticated communication
Status EndpointPublicHealth checks

Security Configurations

Bearer Token Authentication

The simplest authentication method using a shared secret:

python
from praisonaiagents import Agent, A2A

# Basic bearer token setup
a2a = A2A(
    agent=agent,
    auth_token="sk-prod-your-secure-token-here"
)

Client Example

bash
# Valid request with token
curl -X POST http://localhost:8000/a2a \
  -H "Authorization: Bearer sk-prod-your-secure-token-here" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "message/send",
    "id": "1",
    "params": {
      "message": {
        "role": "user",
        "parts": [{"text": "Hello"}]
      }
    }
  }'

# Invalid token returns 401
curl -X POST http://localhost:8000/a2a \
  -H "Authorization: Bearer invalid-token" \
  -H "Content-Type: application/json" \
  -d '{...}'
# Returns: {"error": {"code": 401, "message": "Invalid token"}}

Extended Agent Card

When authentication is enabled, the agent card can indicate security requirements:

python
# Agent card includes security metadata
agent_card = a2a.get_agent_card()
# Discovery endpoint remains public per A2A specification

Common Patterns

Environment-Based Tokens

python
import os
from praisonaiagents import Agent, A2A

agent = Agent(name="Production Agent", role="Assistant", goal="Help users")

a2a = A2A(
    agent=agent,
    auth_token=os.getenv("A2A_AUTH_TOKEN"),  # From environment
    url="https://api.example.com/a2a"
)

FastAPI Integration

python
from fastapi import FastAPI
from praisonaiagents import Agent, A2A

app = FastAPI()
agent = Agent(name="API Agent", role="Helper", goal="Serve requests")

a2a = A2A(
    agent=agent,
    auth_token="sk-api-secure-token",
    prefix="/api/v1"  # Mount at /api/v1/a2a
)

app.include_router(a2a.get_router())

# Discovery: GET /api/v1/.well-known/agent.json (public)
# A2A: POST /api/v1/a2a (protected)

Multi-Environment Setup

python
from praisonaiagents import Agent, A2A

def create_secured_agent(env: str):
    """Create agent with environment-specific security."""

    tokens = {
        "development": "sk-dev-token",
        "staging": "sk-staging-secure-token", 
        "production": "sk-prod-highly-secure-token"
    }

    agent = Agent(
        name=f"{env.title()} Agent",
        role="Environment Helper",
        goal=f"Handle {env} requests securely"
    )

    return A2A(
        agent=agent,
        auth_token=tokens.get(env),
        url=f"https://{env}.example.com/a2a"
    )

# Usage
prod_a2a = create_secured_agent("production")
prod_a2a.serve(port=8000)

Best Practices

Token Security
  • Use cryptographically secure random tokens (32+ characters)
  • Store tokens in environment variables, never in code
  • Rotate tokens regularly in production environments
  • Use different tokens for different environments
  • Consider using prefixes like sk-prod-, sk-dev- for identification
Discovery Compliance
  • Keep /.well-known/agent.json public per A2A specification
  • Only protect the /a2a endpoint with authentication
  • Ensure agent cards don’t expose sensitive information
  • Status endpoints can remain public for health checks
Error Handling
  • Return standard HTTP 401 for invalid/missing tokens
  • Use consistent error message format
  • Log authentication attempts for monitoring
  • Implement rate limiting for failed authentication attempts
Production Deployment
  • Use HTTPS in production environments
  • Implement proper logging and monitoring
  • Consider API gateways for additional security layers
  • Set up proper CORS policies for web clients
  • Monitor token usage patterns for anomalies

Related