Middleware & Auth

Middleware Overview

New to acton-service?

Start with the homepage to understand what acton-service is, then explore Core Concepts for foundational explanations. See the Glossary for technical term definitions.


acton-service provides a middleware library for backend services. All middleware works with both HTTP and gRPC protocols.

Quick Example

Note: Middleware in acton-service is automatically applied by ServiceBuilder based on your configuration file. Individual middleware layers are not manually composed via .with_middleware() - the framework handles this for you based on enabled features and config settings.

Available Middleware

Authentication & Authorization

Token Authentication (PASETO/JWT)

  • PASETO V4 tokens (default) - secure by design with no algorithm confusion
  • JWT support via feature flag for legacy systems (RS256, ES256, HS256/384/512)
  • Claims structure with roles, permissions, user/client identification
  • Redis-backed token revocation for immediate invalidation
  • Learn more: Token Authentication

Cedar Policy-Based Authorization

  • AWS Cedar integration for fine-grained access control
  • Declarative policy files for resource-based permissions
  • Role-based and attribute-based access control (RBAC/ABAC)
  • Manual policy reload endpoint (automatic hot-reload in progress)
  • Optional Redis caching for sub-5ms policy decisions
  • HTTP and gRPC support with customizable path normalization
  • Learn more: Cedar Authorization

Resilience & Reliability

Circuit Breaker

  • Configurable failure rate monitoring with automatic recovery
  • Prevents cascading failures in distributed systems
  • Configurable open/half-open/closed state transitions

Retry Logic

  • Exponential backoff with configurable maximum attempts
  • Intelligent retry for transient failures
  • Respects idempotency requirements

Bulkhead

  • Concurrency limiting with wait timeouts
  • Prevents resource exhaustion and overload
  • Isolates request pools for different operations

Learn more: Resilience Patterns

Rate Limiting

Redis-backed Rate Limiting

  • Distributed rate limiting for multi-instance deployments
  • Consistent limits across service replicas
  • Production-ready for horizontal scaling

Governor Rate Limiting

  • Local in-memory limiting with per-second/minute/hour presets
  • Lower latency for single-instance deployments
  • No external dependencies required

Advanced Features

  • Per-user and per-client limits via token claims
  • Customizable limit buckets and windows
  • Graceful handling of rate limit exceeded scenarios

Learn more: Rate Limiting

Observability

Request Tracking

  • TypeID-based request ID generation (req_ prefix with UUIDv7) for human-readable, time-sortable identifiers
  • Automatic correlation across service boundaries
  • Essential for debugging distributed transactions

Distributed Tracing Headers

  • Standards-compliant header propagation
  • Supports x-request-id, x-trace-id, x-span-id, x-correlation-id
  • Integrates with OpenTelemetry and Jaeger

OpenTelemetry Metrics

  • HTTP request count and duration histograms
  • Active request gauges for load monitoring
  • Request and response size tracking
  • Custom metric instrumentation support

Sensitive Header Masking

  • Automatic masking in logs for security
  • Protects authorization tokens, cookies, API keys
  • Configurable sensitive header patterns

Learn more: Observability

Standard HTTP Middleware

Compression

  • Multiple encoding support: gzip, br (Brotli), deflate, zstd
  • Automatic content negotiation based on Accept-Encoding
  • Reduces bandwidth and improves response times

CORS

  • Configurable cross-origin resource sharing policies
  • Supports preflight requests and credentials
  • Fine-grained control over allowed origins, methods, headers

Timeouts

  • Configurable per-request timeouts
  • Prevents resource leaks from hanging requests
  • Graceful timeout error responses

Body Size Limits

  • Prevents oversized payload attacks
  • Configurable limits per endpoint
  • Returns clear error messages for violations

Panic Recovery

  • Graceful handling of unexpected panics
  • Detailed error logging for debugging
  • Prevents service crashes from request handlers

Middleware Types

The middleware that ServiceBuilder wires up lives in acton_service::middleware:

TypePurposeFeature
PasetoAuthPASETO V4 token validation (default)always available
JwtAuthJWT token validationjwt
RedisTokenRevocationRedis-backed token revocationcache
CedarAuthzCedar policy authorizationcedar-authz
GovernorRateLimitLocal in-memory rate limitinggovernor
RateLimitRedis-backed distributed rate limitingcache
ResilienceConfigCircuit breaker and bulkhead layersresilience
RequestContextPer-request client IP, request ID, and user agent, resolved oncealways available

Execution Order

ServiceBuilder::build() applies the middleware it manages in a fixed order. You do not choose this order — it is determined by the framework so that each stage sees the state the previous one produced:

Request → framework middleware (request ID, tracing, CORS, compression, timeouts)
        → Request context                    — resolves client IP, request ID, user agent
        → Token auth (PasetoAuth / JwtAuth)  — populates Claims
        → Audit logging                      — sees Claims
        → Cedar authorization                — sees Claims
        → Governor rate limiting             — sees Claims for per-user limits
        → Handler

The request-context stage runs after the request ID has been generated and before anything that consumes it. It resolves the client IP once — from X-Forwarded-For or X-Real-IP when present, falling back to the TCP peer address — and stores it, together with the request ID and user agent, in a RequestContext request extension. Every downstream consumer (auth failure audit events, the audit logger, custom handlers) reads that extension instead of re-parsing headers, so audit events carry a real IP and request ID even when an upstream proxy strips forwarding headers.

Token authentication runs next so that Claims are available downstream: audit records the authenticated principal, Cedar evaluates policies against it, and the rate limiter applies per_user_rpm / per_client_rpm buckets keyed by the caller. Anonymous requests fall back to per-IP limits.

If you assemble a Router by hand instead of using ServiceBuilder, preserve this ordering yourself: apply request_context_middleware outside (before) the auth and audit layers, and inside (after) request_id_layer(). Consumers fall back to raw header extraction when the extension is missing, but that fallback cannot see the peer address or a generated request ID.

Each stage is skipped when its configuration or feature flag is absent — for example, the governor layer is only attached when the governor feature is enabled and rate_limit.auto_apply is true.

HTTP and gRPC Compatibility

All middleware works identically for HTTP and gRPC services. The same configuration applies to both protocols automatically. Middleware is automatically applied by ServiceBuilder during initialization based on your configuration file - no manual composition is required.

Next Steps

Previous
Request IDs