Skip to content
Development
Skill

/litestar-security

Use when working with litestar_security, SecurityPlugin, SecurityConfig, SecureController, CurrentUser, Principal, SecurityContext, or requires_role/scope/tenant/capability/assurance. Not for basic Litestar Guards.

From plugin
litestar
1720 skills1 agent2 hooks

Claude Code

$ npx -y skills add litestar-org/litestar-skills --skill litestar-security --agent claude-code

SKILL.md

litestar-security.SKILL.md
name: litestar-security
description: "Use when working with litestar_security, SecurityPlugin, SecurityConfig, SecureController, CurrentUser, Principal, SecurityContext, or requires_role/scope/tenant/capability/assurance. Not for basic Litestar Guards."

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=` (or `opt={"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(...)`) or `PublicController` for controllers, pass `auth=` on individual routes, and use `opt={"auth": ...}` on routers or third-party controllers. The nearest native owner wins. When a public controller needs native Litestar CSRF on cookie-session `POST` routes, subclass `SecureController` with `auth: ClassVar[AuthenticationPolicy] = exclude()` and set `opt={"exclude_from_csrf": False}` on the `POST` handlers (or set `opt={"csrf_required": True}` on individual handlers) because `public()` sets `exclude_from_csrf=True` and rejects `opt={"exclude_from_csrf": False}`.
  • **Keep authorization in `guards=[...]`.** Litestar's `security=` parameter is reserved for the OpenAPI requirements projected from `auth`.
  • **Supply `scheme_name` and `security_scheme` on custom mechanisms.** Every `AuthenticationMechanism` in `SecurityConfig(mechanisms=(...,))` must set both `scheme_name` and `security_scheme=SecurityScheme(...)` when OpenAPI is enabled, or startup fails with `ImproperlyConfiguredException`.
  • **Inject the user with `CurrentUser[T]`.** Annotate `current_user: CurrentUser[UserType]` (already a `NamedDependency[UserType]` alias); it rejects anonymous and userless service principals. `principal` and `security_context` stay typed on public routes too via `NamedDependency`.
  • **Authorize from the snapshot.** Guards read the `AuthorizationSnapshot` produced by the configured `authorization_resolver`. Never query the database inside a guard.
  • **Compose predicates with `requires_*`.** Use `requires_any_of`, `requires_all_of`, `requires_at_least`, `requires_one_of` for predicate composition.
  • **Exclude other plugins' routes by path, never OpenAPI or `.well-known`.** Static assets and dashboards carry no `auth` and compile to implicit `required()`, so they answer `401` until listed in `SecurityConfig(exclude=[...])`. Litestar's OpenAPI routes (`/schema`, `/docs`) and `ProtectedResourceConfig` / `LocalJWKSConfig` routes are already `public()` — do not add them to `exclude`. Inspect routes with `litestar security routes`.
  • **Secure WebSockets with connect tokens.** Browsers cannot set handshake headers; mint a short-lived token over authenticated HTTP via `WebSocketConnectTokenService` or `WebSocketConnectTokenIssuer`.
  • **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

from litestar import Litestar, get
from litestar.di import NamedDependency

from litestar_security import (
    SecurityConfig,
    SecurityContext,
    SecurityPlugin,
    public,
)


@get("/", auth=public(), sync_to_thread=False)
def index(security_context: NamedDependency[SecurityContext]) -> dict[str, bool]:
    return {"authenticated": bool(security_context.evidence)}


app = Litestar(
    route_handlers=[index],
    plugins=[SecurityPlugin(SecurityConfig())],
)

With mechanisms configured and no inherited policy, routes default to implicit `required()`. With no mechanisms at all they are public.

Authentication Policy

from typing import ClassVar

from litestar import get
from litestar_security import (
    AuthenticationPolicy,
    PublicController,
    SecureController,
    all_of,
    any_of,
    at_least,
    public,
    required,
)

policy_default = required()
policy_session = required("session")
policy_either = any_of("session", "api-key")
policy_both = all_of("api-key", "service-jwt")
policy_threshold = at_least(2, "session", "api-key", "service-jwt")
policy_public = public()

Apply policy on controllers via `SecureController` / `PublicController` and on routes via `auth=`:

class HealthController(PublicController):
    path = "/health"

    @get("/")
    async def check(self) -> dict[str, str]:
        return {"status": "ok"}


class AccountController(SecureController):
    path = "/accounts"
    auth: ClassVar[AuthenticationPolicy] = required("session")

Use `opt={"auth": ...}` only on `Router`, `Litestar`, or third-party controllers that cannot subclass `SecureController`.

Authorization Guards

from typing import ClassVar

from litestar import get
from litestar_security import (
    AuthenticationPolicy,
    SecureController,
    required,
    requires_any_of,
    requires_role,
    requires_scope,
)


class ReportsController(SecureController):
    path = "/reports"
    auth: ClassVar[AuthenticationPolicy] = required("session")
    guards = [requires_role("analyst")]

    @get("/", guards=[requires_any_of(requires_scope("read:all"), requires_scope("read:reports"))])
    async def list_reports(self) -> list[dict[str, str]]:
        return []

Reserved Dependency

Read more
@litestar-org
Ships withlitestar

Opinionated, first-party agent skills, plugins, subagents, hooks, and rules for the Litestar framework and its ecosystem — published from a single-root repository across Google Antigravity, Claude Code, Codex CLI, Cursor, OpenCode, and VS Code / Copilot.

1720 skills1 agent
Get the whole plugin

Stars on GitHub

Momentum

stars in total
17
Star history of litestar-org/litestar-skills on GitHub, a chart by star-history.com

Other skills on litestar.

advanced-alchemy

advanced-alchemy

Use when working with advanced_alchemy, alembic/, SQLAlchemyAsyncRepositoryService, SQLAlchemyAsyncConfig, repository_type,…

litestar-autowire

litestar-autowire

Use when working with litestar_autowire, AutowirePlugin, AutowireConfig, domain_packages, AutowireIntegration, AutowireLoader, or…

litestar-build

litestar-build

Use when working with uv build, hatch build, PyApp, PYAPP_*, wheel assets, GitHub release matrices, cargo-zigbuild, or…

litestar-docs

litestar-docs

Use when working with zensical.toml, docs/conf.py, sphinx, shibuya, litestar-sphinx-theme, mkdocstrings, Griffe, objects.inv, or…

litestar-email

litestar-email

Use when working with litestar_email, EmailPlugin, EmailConfig, EmailService, EmailMessage, SMTPConfig, ResendConfig,…

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills10d309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc12d293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react1d252k
@facebook@facebookInstall Skill

Questions about litestar-security.

Which coding agents can use litestar-security?
litestar-security installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.