litestar-org/litestar-skills/litestar-security
Claude Code and agent skill by litestar-org/litestar-skills
- community
Checking that the SKILL.md file is still in the repository.
Auto-activate for litestar_security, SecurityPlugin, SecurityConfig, SecureController, CurrentUser, Principal, SecurityContext, or requires_role/scope/tenant/capability/assurance. Not for basic Litestar Guards.
Install
npx vskill@latest install litestar-org/litestar-skills/litestar-securitySKILL.md
Litestar Security
litestar-security is a declarative authentication and authorization framework for Litestar. It provides credential slots and mechanisms, unified session management, local accounts, MFA, WebAuthn passkeys, OAuth/OIDC, API keys, workload JWTs, and browser hardening.
Two separate axes, wired through two separate Litestar keywords:
- Authentication — who is calling — is a policy on
auth=(oropt={"auth": ...}). - Authorization — what they may do — is a predicate in Litestar's native
guards=[...].
Do not conflate them: the policy helpers (public, required, any_of, all_of, at_least, optional, exclude, mechanism) take mechanism names, while the guard combinators (requires_any_of, requires_all_of, requires_at_least, requires_one_of) take predicates.
Code Style Rules
- Declare authentication with `SecureController`, `PublicController`, or `auth=`. Subclass
SecureController(auth: ClassVar[AuthenticationPolicy] = required(...)) orPublicControllerfor controllers, passauth=on individual routes, and useopt={"auth": ...}on routers or third-party controllers. The nearest native owner wins. When a public controller needs native Litestar CSRF on cookie-sessionPOSTroutes, subclassSecureControllerwithauth: ClassVar[AuthenticationPolicy] = exclude()and setopt={"exclude_from_csrf": False}on thePOSThandlers (or setopt={"csrf_required": True}on individual handlers) becausepublic()setsexclude_from_csrf=Trueand rejectsopt={"exclude_from_csrf": False}. - Keep authorization in `guards=[...]`. Litestar's
security=parameter is reserved for the OpenAPI requirements projected fromauth. - Supply `scheme_name` and `security_scheme` on custom mechanisms. Every
AuthenticationMechanisminSecurityConfig(mechanisms=(...,))must set bothscheme_nameandsecurity_scheme=SecurityScheme(...)when OpenAPI is enabled, or startup fails withImproperlyConfiguredException. - Inject the user with `CurrentUser[T]`. Annotate
current_user: CurrentUser[UserType](already aNamedDependency[UserType]alias); it rejects anonymous and userless service principals.principalandsecurity_contextstay typed on public routes too viaNamedDependency. - Authorize from the snapshot. Guards read the
AuthorizationSnapshotproduced by the configuredauthorization_resolver. Never query the database inside a guard. - Compose predicates with `requires_*`. Use
requires_any_of,requires_all_of,requires_at_least,requires_one_offor predicate composition. - Exclude other plugins' routes by path, never OpenAPI or `.well-known`. Static assets and dashboards carry no
authand compile to implicitrequired(), so they answer401until listed inSecurityConfig(exclude=[...]). Litestar's OpenAPI routes (/schema,/docs) andProtectedResourceConfig/LocalJWKSConfigroutes are alreadypublic()— do not add them toexclude. Inspect routes withlitestar security routes. - Secure WebSockets with connect tokens. Browsers cannot set handshake headers; mint a short-lived token over authenticated HTTP via
WebSocketConnectTokenServiceorWebSocketConnectTokenIssuer. - Load protector keys from a secret store. MFA and OAuth protectors need application-owned 32-byte AES-256-GCM keys, never source literals.
Quick Reference
Plugin Registration
With mechanisms configured and no inherited policy, routes default to implicit required(). With no mechanisms at all they are public.
Authentication Policy
Apply policy on controllers via SecureController / PublicController and on routes via auth=:
Use opt={"auth": ...} only on Router, Litestar, or third-party controllers that cannot subclass SecureController.
Authorization Guards
Reserved Dependency Names
The plugin registers these; do not shadow them.
| Key | Type | Use | |
|---|---|---|---|
principal | NamedDependency[Principal[User]] | Stable envelope identity plus the active user model | |
security_context | NamedDependency[SecurityContext] | Active session, evidence, snapshot, and restrictions | |
current_user | CurrentUser[User] | Narrowing shortcut (NamedDependency[User]); rejects anonymous and service principals | |
csp_nonce | csp_nonce (NamedDependency[str]) | Per-request CSP nonce when ContentSecurityPolicy.nonce_directives is non-empty | |
websocket_connect_tokens | NamedDependency[WebSocketConnectTokenIssuer] | Route-aware WebSocket connect-token issuer |
Status Code Contract
| Outcome | Status | |
|---|---|---|
| Authentication failure | 401 | |
| Guard denial | 403 | |
| Verification unavailable (fails closed) | 503 |
<workflow>
Workflow
Step 1: Install the capabilities in use
Core install covers JWT/JWKS validation, API keys, IAP, and OIDC token verification. Use [argon2,mfa] for LocalAuth; add [passkeys] or [oauth] only when needed, or use [all].
Step 2: Choose providers
Pick where identity is established — local accounts, OAuth/OIDC, Google IAP, API keys, or workload JWTs. Adding a provider makes its mechanism available; route policy decides where it is accepted. See Providers.
Step 3: Implement the authorization resolver
Implement an async resolve(principal) method that returns an AuthorizationSnapshot of granted roles, scopes, capabilities, tenant roles, and tenant IDs. Return InvalidCredentials or VerificationUnavailable for expected denial or dependency failure. It runs once per request, so guards must not perform I/O.
Step 4: Register the plugin and set default policy
Scope an application-wide opt={"auth": ...} default to the router that owns the application's own routes, so policy-less third-party routes keep the implicit default rather than counting as declared.
Step 5: Exclude routes the application did not write
Add SecurityConfig(exclude=[...]) patterns for static files, queue dashboards, and schema browsers. See Composition.
Step 6: Harden the deployment
Apply SecurityHeadersConfig.hardened(), supply every CSP directive explicitly, and move protector keys and peppers into secret management. See Hardening.
</workflow>
<guardrails>
Guardrails
- Do not pass predicates to `any_of` / `all_of` / `at_least`. Those compose authentication mechanisms. Use
requires_any_of,requires_all_of,requires_at_least, orrequires_one_offor predicates. - Do not shadow reserved dependencies. Avoid naming providers
principal,security_context,current_user,csp_nonce, orwebsocket_connect_tokens. - Do not perform I/O in predicates. Guards evaluate synchronously against the snapshot; put database checks in the
authorization_resolver. - Do not use `guards=` for authentication or `auth=` for authorization. They compile to different things — runtime admission plus OpenAPI projection versus permission checks.
- Do not set `opt={"exclude_from_csrf": False}` on `PublicController` (`auth = public()`) routes.
public()setsexclude_from_csrf=TrueandRouteCompiler._validate_csrf_metadataraisesImproperlyConfiguredException: Native CSRF exclusions must be exactly True. For a public controller whose cookie-sessionPOSTroutes require native Litestar CSRF, setauth: ClassVar[AuthenticationPolicy] = exclude()on aSecureControllersubclass andopt={"exclude_from_csrf": False}on thePOSThandlers (or setopt={"csrf_required": True}on individual HTTP handlers). - Do not omit `scheme_name` and `security_scheme` on custom `AuthenticationMechanism` instances. When OpenAPI is enabled,
OpenAPISchemeSet.from_registry()raisesImproperlyConfiguredException: Authentication mechanism <name> has no native OpenAPI security scheme. - Do not put a layer-level policy above excluded routes, or add `/docs`, `/schema`, or `/.well-known` to `SecurityConfig.exclude`. A route that both declares
authand matches an exclusion pattern is rejected at startup, and OpenAPI routes are already auto-detected aspublic(). - Do not put bearer credentials in WebSocket query strings. Use a connect token or an HttpOnly cookie.
- Do not enable `MFAConfig(require_at_login=True)` before enrolling factors. Unenrolled accounts lock themselves out; use
require_at_login="enrolled"to enforce login MFA only for accounts that have enrolled a factor. - Do not hard-code protector keys. Load exact 32-byte material from a KMS or secret store, and retain the previous key through rotation.
</guardrails>
<validation>
Validation Checkpoint
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 100 of 100Pattern checks on the skill's files.
- Model reviewNot runA model review is scheduled for the next rescan.
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/litestar-security/SKILL.md
Popularity
- Repository stars
- 15
- 7-day trend score
- 14
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/litestar-org/litestar-skills/litestar-security)