Configuration Module

Configuration Module

The configuration module (agentweave.config) provides a comprehensive Pydantic-based configuration system with strict validation to ensure agents cannot start with insecure settings.

Overview

The configuration system enforces:

  • Default deny in production - Explicit policies required
  • No peer verification bypass - mTLS verification cannot be disabled
  • TLS >= 1.2 mandatory - Modern TLS versions only
  • Valid SPIFFE trust domain - Proper identity domain configuration

Configuration can be loaded from:

  • YAML files (recommended for deployment)
  • Environment variables (for container overrides)
  • Direct instantiation (for testing)

Enumerations

Environment

1
2
3
4
5
6
class Environment(str, Enum):
    """Deployment environment."""

    DEVELOPMENT = "development"
    STAGING = "staging"
    PRODUCTION = "production"

Values:

Value Description
DEVELOPMENT Development environment (relaxed security rules)
STAGING Staging environment
PRODUCTION Production environment (strict security enforced)

Example:

1
2
agent:
  environment: production

IdentityProvider

1
2
3
4
5
class IdentityProvider(str, Enum):
    """Identity provider type."""

    SPIFFE = "spiffe"
    MTLS_STATIC = "mtls-static"  # For testing/development only

Values:

Value Description
SPIFFE SPIFFE/SPIRE identity provider (recommended)
MTLS_STATIC Static mTLS certificates (development/testing only)

Example:

1
2
identity:
  provider: spiffe

AuthorizationProvider

1
2
3
4
5
class AuthorizationProvider(str, Enum):
    """Authorization provider type."""

    OPA = "opa"
    ALLOW_ALL = "allow-all"  # Development only - rejected in production

Values:

Value Description
OPA Open Policy Agent for policy-based authorization
ALLOW_ALL Allow all requests (development only, rejected in production)

Example:

1
2
authorization:
  provider: opa

DefaultAction

1
2
3
4
5
class DefaultAction(str, Enum):
    """Default authorization action."""

    DENY = "deny"
    LOG_ONLY = "log-only"  # Development only - rejected in production

Values:

Value Description
DENY Deny requests by default (required in production)
LOG_ONLY Log authorization decisions but allow all (development only)

Example:

1
2
authorization:
  default_action: deny

PeerVerification

1
2
3
4
5
class PeerVerification(str, Enum):
    """Peer verification mode."""

    STRICT = "strict"
    LOG_ONLY = "log-only"  # Development only

Values:

Value Description
STRICT Strict peer verification (required in production)
LOG_ONLY Log verification failures but allow connection (development only)

Example:

1
2
transport:
  peer_verification: strict

ProtocolType

1
2
3
4
5
class ProtocolType(str, Enum):
    """Communication protocol type."""

    A2A = "a2a"
    GRPC = "grpc"

Values:

Value Description
A2A Agent-to-Agent JSON-RPC protocol
GRPC gRPC protocol (future support)

Example:

1
2
server:
  protocol: a2a

Configuration Models

Capability

1
2
3
4
5
6
7
class Capability(BaseModel):
    """Agent capability definition."""

    name: str
    description: str
    input_modes: list[str] = ["application/json"]
    output_modes: list[str] = ["application/json"]

Fields:

Field Type Default Description
name str required Capability name (lowercase, underscores allowed)
description str required Human-readable description
input_modes list[str] ["application/json"] Accepted input content types
output_modes list[str] ["application/json"] Produced output content types

Validation Rules:

  • name must match pattern ^[a-z][a-z0-9_]*$
  • Must start with lowercase letter
  • Can contain lowercase letters, numbers, and underscores

Example:

1
2
3
4
5
6
7
8
agent:
  capabilities:
    - name: search_users
      description: Search for users in the directory
      input_modes:
        - application/json
      output_modes:
        - application/json

Python:

1
2
3
4
5
6
from agentweave.config import Capability

cap = Capability(
    name="search_users",
    description="Search for users in the directory"
)

AgentSettings

1
2
3
4
5
6
7
8
class AgentSettings(BaseModel):
    """Core agent settings."""

    name: str
    trust_domain: str
    description: str = ""
    environment: Environment = Environment.PRODUCTION
    capabilities: list[Capability] = []

Fields:

Field Type Default Description
name str required Unique agent name
trust_domain str required SPIFFE trust domain
description str "" Agent description
environment Environment PRODUCTION Deployment environment
capabilities list[Capability] [] Agent capabilities

Validation Rules:

  • name must match pattern ^[a-z][a-z0-9-]*$ (lowercase, hyphens allowed)
  • trust_domain must be valid DNS name (e.g., agentweave.io)

Example:

1
2
3
4
5
6
7
8
agent:
  name: data-search-agent
  trust_domain: agentweave.io
  description: Agent for searching data across systems
  environment: production
  capabilities:
    - name: search
      description: Search the database

Python:

1
2
3
4
5
6
7
8
9
10
from agentweave.config import AgentSettings, Environment, Capability

settings = AgentSettings(
    name="data-search-agent",
    trust_domain="agentweave.io",
    environment=Environment.PRODUCTION,
    capabilities=[
        Capability(name="search", description="Search the database")
    ]
)

IdentityConfig

1
2
3
4
5
6
class IdentityConfig(BaseModel):
    """Identity provider configuration."""

    provider: IdentityProvider = IdentityProvider.SPIFFE
    spiffe_endpoint: str = "unix:///run/spire/sockets/agent.sock"
    allowed_trust_domains: list[str] = []

Fields:

Field Type Default Description
provider IdentityProvider SPIFFE Identity provider type
spiffe_endpoint str unix:///run/spire/sockets/agent.sock SPIFFE Workload API endpoint
allowed_trust_domains list[str] [] Allowed trust domains for federation

Validation Rules:

  • spiffe_endpoint must start with unix:// or tcp://

Example:

1
2
3
4
5
6
identity:
  provider: spiffe
  spiffe_endpoint: unix:///run/spire/sockets/agent.sock
  allowed_trust_domains:
    - partner.io
    - trusted-domain.com

Python:

1
2
3
4
5
6
7
from agentweave.config import IdentityConfig, IdentityProvider

identity = IdentityConfig(
    provider=IdentityProvider.SPIFFE,
    spiffe_endpoint="unix:///run/spire/sockets/agent.sock",
    allowed_trust_domains=["partner.io"]
)

AuditConfig

1
2
3
4
5
class AuditConfig(BaseModel):
    """Audit logging configuration."""

    enabled: bool = True
    destination: str = "file:///var/log/agentweave/audit.log"

Fields:

Field Type Default Description
enabled bool True Enable audit logging
destination str file:///var/log/agentweave/audit.log Audit log destination

Example:

1
2
3
4
authorization:
  audit:
    enabled: true
    destination: file:///var/log/agentweave/audit.log

AuthorizationConfig

1
2
3
4
5
6
7
8
class AuthorizationConfig(BaseModel):
    """Authorization provider configuration."""

    provider: AuthorizationProvider = AuthorizationProvider.OPA
    opa_endpoint: str = "http://localhost:8181"
    policy_path: str = "agentweave/authz"
    default_action: DefaultAction = DefaultAction.DENY
    audit: AuditConfig = AuditConfig()

Fields:

Field Type Default Description
provider AuthorizationProvider OPA Authorization provider
opa_endpoint str http://localhost:8181 OPA server endpoint
policy_path str agentweave/authz OPA policy path
default_action DefaultAction DENY Default authorization action
audit AuditConfig AuditConfig() Audit configuration

Validation Rules:

  • opa_endpoint must be valid HTTP(S) URL

Example:

1
2
3
4
5
6
7
8
authorization:
  provider: opa
  opa_endpoint: http://localhost:8181
  policy_path: agentweave/authz
  default_action: deny
  audit:
    enabled: true
    destination: file:///var/log/agentweave/audit.log

Python:

1
2
3
4
5
6
7
from agentweave.config import AuthorizationConfig, AuthorizationProvider, DefaultAction

authz = AuthorizationConfig(
    provider=AuthorizationProvider.OPA,
    opa_endpoint="http://localhost:8181",
    default_action=DefaultAction.DENY
)

ConnectionPoolConfig

1
2
3
4
5
class ConnectionPoolConfig(BaseModel):
    """Connection pool configuration."""

    max_connections: int = Field(default=100, ge=1, le=10000)
    idle_timeout_seconds: int = Field(default=60, ge=1)

Fields:

Field Type Default Constraints Description
max_connections int 100 1-10000 Maximum connections in pool
idle_timeout_seconds int 60 >= 1 Idle connection timeout

Example:

1
2
3
4
transport:
  connection_pool:
    max_connections: 200
    idle_timeout_seconds: 120

CircuitBreakerConfig

1
2
3
4
5
class CircuitBreakerConfig(BaseModel):
    """Circuit breaker configuration."""

    failure_threshold: int = Field(default=5, ge=1)
    recovery_timeout_seconds: int = Field(default=30, ge=1)

Fields:

Field Type Default Constraints Description
failure_threshold int 5 >= 1 Failures before opening circuit
recovery_timeout_seconds int 30 >= 1 Time before attempting recovery

Example:

1
2
3
4
transport:
  circuit_breaker:
    failure_threshold: 10
    recovery_timeout_seconds: 60

RetryConfig

1
2
3
4
5
6
class RetryConfig(BaseModel):
    """Retry policy configuration."""

    max_attempts: int = Field(default=3, ge=1, le=10)
    backoff_base_seconds: float = Field(default=1.0, ge=0.1)
    backoff_max_seconds: float = Field(default=30.0, ge=1.0)

Fields:

Field Type Default Constraints Description
max_attempts int 3 1-10 Maximum retry attempts
backoff_base_seconds float 1.0 >= 0.1 Base backoff duration
backoff_max_seconds float 30.0 >= 1.0 Maximum backoff duration

Example:

1
2
3
4
5
transport:
  retry:
    max_attempts: 5
    backoff_base_seconds: 2.0
    backoff_max_seconds: 60.0

TransportConfig

1
2
3
4
5
6
7
8
class TransportConfig(BaseModel):
    """Transport layer configuration."""

    tls_min_version: Literal["1.2", "1.3"] = "1.3"
    peer_verification: PeerVerification = PeerVerification.STRICT
    connection_pool: ConnectionPoolConfig = ConnectionPoolConfig()
    circuit_breaker: CircuitBreakerConfig = CircuitBreakerConfig()
    retry: RetryConfig = RetryConfig()

Fields:

Field Type Default Description
tls_min_version "1.2" or "1.3" "1.3" Minimum TLS version
peer_verification PeerVerification STRICT Peer verification mode
connection_pool ConnectionPoolConfig default Connection pool settings
circuit_breaker CircuitBreakerConfig default Circuit breaker settings
retry RetryConfig default Retry policy

Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
transport:
  tls_min_version: "1.3"
  peer_verification: strict
  connection_pool:
    max_connections: 200
    idle_timeout_seconds: 120
  circuit_breaker:
    failure_threshold: 10
    recovery_timeout_seconds: 60
  retry:
    max_attempts: 5
    backoff_base_seconds: 2.0
    backoff_max_seconds: 60.0

ServerConfig

1
2
3
4
5
6
class ServerConfig(BaseModel):
    """Server configuration."""

    host: str = "0.0.0.0"
    port: int = Field(default=8443, ge=1, le=65535)
    protocol: ProtocolType = ProtocolType.A2A

Fields:

Field Type Default Constraints Description
host str "0.0.0.0" - Server bind host
port int 8443 1-65535 Server port
protocol ProtocolType A2A - Communication protocol

Example:

1
2
3
4
server:
  host: 0.0.0.0
  port: 8443
  protocol: a2a

MetricsConfig

1
2
3
4
5
class MetricsConfig(BaseModel):
    """Metrics configuration."""

    enabled: bool = True
    port: int = Field(default=9090, ge=1, le=65535)

Fields:

Field Type Default Constraints Description
enabled bool True - Enable metrics collection
port int 9090 1-65535 Metrics server port

Example:

1
2
3
4
observability:
  metrics:
    enabled: true
    port: 9090

TracingConfig

1
2
3
4
5
6
class TracingConfig(BaseModel):
    """Distributed tracing configuration."""

    enabled: bool = True
    exporter: Literal["otlp", "jaeger", "zipkin"] = "otlp"
    endpoint: str = "http://localhost:4317"

Fields:

Field Type Default Description
enabled bool True Enable distributed tracing
exporter "otlp", "jaeger", or "zipkin" "otlp" Trace exporter type
endpoint str http://localhost:4317 Trace collector endpoint

Example:

1
2
3
4
5
observability:
  tracing:
    enabled: true
    exporter: otlp
    endpoint: http://localhost:4317

LoggingConfig

1
2
3
4
5
class LoggingConfig(BaseModel):
    """Logging configuration."""

    level: Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"] = "INFO"
    format: Literal["json", "text"] = "json"

Fields:

Field Type Default Description
level Log level "INFO" Log level
format "json" or "text" "json" Log format

Example:

1
2
3
4
observability:
  logging:
    level: INFO
    format: json

ObservabilityConfig

1
2
3
4
5
6
class ObservabilityConfig(BaseModel):
    """Observability configuration."""

    metrics: MetricsConfig = MetricsConfig()
    tracing: TracingConfig = TracingConfig()
    logging: LoggingConfig = LoggingConfig()

Fields:

Field Type Default Description
metrics MetricsConfig default Metrics settings
tracing TracingConfig default Tracing settings
logging LoggingConfig default Logging settings

Example:

1
2
3
4
5
6
7
8
9
10
11
observability:
  metrics:
    enabled: true
    port: 9090
  tracing:
    enabled: true
    exporter: otlp
    endpoint: http://localhost:4317
  logging:
    level: INFO
    format: json

AgentConfig (Main Configuration)

1
2
3
4
5
6
7
8
9
class AgentConfig(BaseModel):
    """Complete agent configuration with strict security validation."""

    agent: AgentSettings
    identity: IdentityConfig = IdentityConfig()
    authorization: AuthorizationConfig = AuthorizationConfig()
    transport: TransportConfig = TransportConfig()
    server: ServerConfig = ServerConfig()
    observability: ObservabilityConfig = ObservabilityConfig()

Fields

Field Type Default Description
agent AgentSettings required Agent settings
identity IdentityConfig default Identity configuration
authorization AuthorizationConfig default Authorization configuration
transport TransportConfig default Transport configuration
server ServerConfig default Server configuration
observability ObservabilityConfig default Observability configuration

Methods

is_production

1
def is_production(self) -> bool

Check if running in production environment.

Returns: bool - True if environment is production

Example:

1
2
3
config = AgentConfig.from_file("config.yaml")
if config.is_production():
    print("Running in production mode")

from_file

1
2
@classmethod
def from_file(cls, path: str | Path) -> AgentConfig

Load configuration from YAML file.

Parameters:

Parameter Type Description
path str or Path Path to YAML configuration file

Returns: AgentConfig - Validated configuration instance

Raises:

Exception Description
ConfigurationError If file not found, invalid YAML, or validation fails

Example:

1
2
3
from agentweave.config import AgentConfig

config = AgentConfig.from_file("config.yaml")

from_env

1
2
@classmethod
def from_env(cls, prefix: str = "AGENTWEAVE_") -> AgentConfig

Load configuration from environment variables.

Parameters:

Parameter Type Default Description
prefix str "AGENTWEAVE_" Environment variable prefix

Returns: AgentConfig - Validated configuration instance

Raises:

Exception Description
ConfigurationError If required variables missing or validation fails

Environment Variable Format:

1
{prefix}{SECTION}_{KEY}

Examples:

1
2
3
4
5
export AGENTWEAVE_AGENT_NAME=my-agent
export AGENTWEAVE_AGENT_TRUST_DOMAIN=agentweave.io
export AGENTWEAVE_IDENTITY_SPIFFE_ENDPOINT=unix:///run/spire/sockets/agent.sock
export AGENTWEAVE_TRANSPORT_TLS_MIN_VERSION=1.3
export AGENTWEAVE_SERVER_PORT=8443

Python:

1
2
3
4
5
6
7
from agentweave.config import AgentConfig

# Load from environment
config = AgentConfig.from_env()

# Custom prefix
config = AgentConfig.from_env(prefix="MYAPP_")

Security Validation Rules

The AgentConfig enforces strict security rules during validation:

Rule 1: Default Deny in Production

1
2
3
4
if self.is_production() and self.authorization.default_action != DefaultAction.DENY:
    raise ConfigurationError(
        "authorization.default_action must be 'deny' in production environment"
    )

Rule 2: No Allow-All in Production

1
2
3
4
if self.is_production() and self.authorization.provider == AuthorizationProvider.ALLOW_ALL:
    raise ConfigurationError(
        "authorization.provider cannot be 'allow-all' in production environment"
    )

Rule 3: Strict Peer Verification in Production

1
2
3
4
if self.is_production() and self.transport.peer_verification != PeerVerification.STRICT:
    raise ConfigurationError(
        "transport.peer_verification must be 'strict' in production environment"
    )

Rule 4: TLS 1.2 Minimum

1
2
3
4
if self.transport.tls_min_version not in ("1.2", "1.3"):
    raise ConfigurationError(
        "transport.tls_min_version must be '1.2' or '1.3'"
    )

Rule 5: Audit Enabled in Production

1
2
3
4
if self.is_production() and not self.authorization.audit.enabled:
    raise ConfigurationError(
        "authorization.audit.enabled must be true in production environment"
    )

Complete Configuration Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# config.yaml
agent:
  name: data-search-agent
  trust_domain: agentweave.io
  description: Agent for searching data across systems
  environment: production
  capabilities:
    - name: search
      description: Search the database
      input_modes:
        - application/json
      output_modes:
        - application/json

identity:
  provider: spiffe
  spiffe_endpoint: unix:///run/spire/sockets/agent.sock
  allowed_trust_domains:
    - partner.io

authorization:
  provider: opa
  opa_endpoint: http://localhost:8181
  policy_path: agentweave/authz
  default_action: deny
  audit:
    enabled: true
    destination: file:///var/log/agentweave/audit.log

transport:
  tls_min_version: "1.3"
  peer_verification: strict
  connection_pool:
    max_connections: 200
    idle_timeout_seconds: 120
  circuit_breaker:
    failure_threshold: 10
    recovery_timeout_seconds: 60
  retry:
    max_attempts: 5
    backoff_base_seconds: 2.0
    backoff_max_seconds: 60.0

server:
  host: 0.0.0.0
  port: 8443
  protocol: a2a

observability:
  metrics:
    enabled: true
    port: 9090
  tracing:
    enabled: true
    exporter: otlp
    endpoint: http://localhost:4317
  logging:
    level: INFO
    format: json

Load in Python:

1
2
3
4
5
6
7
8
9
10
11
from agentweave.config import AgentConfig
from agentweave import SecureAgent

# Load configuration
config = AgentConfig.from_file("config.yaml")

# Use with agent
class MyAgent(SecureAgent):
    pass

agent = MyAgent(config=config.agent)  # Pass AgentSettings

See Also