What is included
- Hardened response headers: Content-Security-Policy, Strict-Transport-Security, X-Content-Type-Options, Referrer-Policy, X-Frame-Options and Permissions-Policy.
- Per-route rate limiting with a guard and an @RateLimit decorator.
- Idempotency-key replay, so a retried POST, PUT, PATCH or DELETE does not run twice.
- Double-submit-cookie CSRF protection.
- Structured PII redaction for logs.
- Application-level column encryption with versioned keys.
Rate limiting a login route
The limiter is keyed on client IP, method and path. X-Forwarded-For is ignored unless you declare how many trusted proxies sit in front of the app, because the header is client-controlled. For several workers, supply a shared store such as Redis.
from austial import Controller, Post, UseGuards
from austial.security import RateLimit, RateLimitGuard
@Controller("/auth")
@UseGuards(RateLimitGuard)
class AuthController:
@Post("/login")
@RateLimit(5, 60) # 5 attempts per minute
async def login(self, body: LoginRequest) -> LoginResponse:
...An audit trail to match
austial.audit adds an append-only audit log persisted through the ORM, an injectable service, and an @Audited interceptor that records who did what on a handler. Retention and legal hold are covered in the docs.
Frequently asked questions
Does Austial follow OWASP guidance?
The docs map each primitive to the OWASP ASVS and OWASP API Security Top 10 items it addresses. Treat that as a starting point for your own review, not a certification.
Is the default rate limiter production-ready for multiple workers?
The default store is in-memory and process-local. For multi-worker deployments the docs say to supply a shared store, such as a Redis-backed one.
What does the idempotency support do?
A retried POST, PUT, PATCH or DELETE that carries the same Idempotency-Key header replays the earlier response instead of executing the mutation twice.