Security

Agentend takes a defense-in-depth approach to security. The PALADIN system provides 5 layers of injection defense, while the auth module handles identity verification and the guardrails module validates inputs and outputs.

PALADIN — 5-layer injection defense

PALADIN (Proactive Agent-Layer Anti-injection Defense INfrastructure) is a multi-layer system that detects and neutralizes injection attacks before they reach the LLM. Layer 1 — the InputSanitizer — runs on every incoming request.

Layer 1: Input sanitization

The InputSanitizer strips control characters, removes known injection patterns, and validates input length. It detects and blocks:

  • Script injection<script>, <iframe>, <object> tags
  • Protocol abusejavascript: and data:text/html URIs
  • Event handler injection — inline on*= attributes
  • Template injection${...} and {{...}} patterns
  • Code executionexec(), eval(), __import__
  • SQL injection — UNION, SELECT, INSERT, UPDATE, DELETE, DROP, CREATE, ALTER keywords
  • Shell injection — command chaining (; rm), pipe to shell, backtick substitution, $() expansion
from agentend.security.sanitizer import InputSanitizer

sanitizer = InputSanitizer(
    max_length=100000,
    allow_html=False,
    allow_sql=False,
    allow_shell=False,
)

# Sanitize user input
clean = sanitizer.sanitize(user_input)

# Check for injection patterns
patterns = sanitizer.has_injection_patterns(user_input)
if patterns:
    log.warning(f"Detected injection patterns: {patterns}")

Layer 2: Prompt armoring

System prompts are wrapped with injection-resistant delimiters and instructions that tell the LLM to ignore overrides embedded in user input.

Layer 3: Output validation

Agent responses are scanned for leaked system prompts, PII, and hallucinated tool calls before being sent to the client.

Layer 4: Tool call validation

Tool calls are validated against a whitelist of allowed tools and argument schemas before execution. This prevents the LLM from invoking tools it should not have access to or passing malicious arguments.

Layer 5: Behavioral monitoring

Runtime monitoring detects anomalous patterns like repeated tool calls, unusual output lengths, or attempts to exfiltrate data through side channels.

Authentication

Agentend supports three authentication methods, configured in fleet.yaml:

MethodDescription
JWTJSON Web Tokens with configurable secret and algorithm (default: HS256)
OAuth2External OAuth2 provider with client ID/secret
API KeyHeader-based API key validation (default header: X-API-Key)
# fleet.yaml
auth:
  enabled: true
  provider: jwt
  jwt:
    secret: ${JWT_SECRET}
    algorithm: HS256

Per-capability RBAC

Role-Based Access Control restricts which capabilities a user can invoke. Roles are extracted from the JWT claims and matched against capability requirements at dispatch time.

Guardrails

The guardrails module provides configurable input and output validation:

GuardrailDirectionDescription
max_lengthInputMaximum input length (default: 10,000 chars)
sanitize_htmlInputStrip HTML tags from input
check_piiOutputDetect personally identifiable information in responses
check_toxicityOutputCheck for toxic or harmful content
redact_sensitiveOutputRedact sensitive data (keys, passwords, etc.)

Multi-tenant RLS

Agentend uses PostgreSQL Row-Level Security (RLS) to enforce data isolation between tenants. Every database query is automatically scoped to the authenticated tenant. This is enforced at the persistence layer via SQLAlchemy 2.0 async models, so there is no way to accidentally query another tenant's data.