Skip to content
Development
Skill

/litestar-security

Auto-activate for litestar_security, SecurityPlugin, SecurityConfig, CurrentUser, Principal, SecurityContext, requires_role, requires_scope, requires_authenticated, requires_tenant, requires_tenant_role, requires_capability, or requires_assurance. Not for raw auth guards alone —

From plugin
litestar
1431 skills1 agent1 hook
Install
$ npx -y skills add litestar-org/litestar-skills --skill litestar-security --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/litestar-security

Context preview

The summary Claude sees to decide when to auto-load this skill.

Auto-activate for litestar_security, SecurityPlugin, SecurityConfig, CurrentUser, Principal, SecurityContext, requires_role, requires_scope, requires_authenticated, requires_tenant, requires_tenant_role, requires_capability, or requires_assurance. Not for raw auth guards alone —

SKILL.md

litestar-security.SKILL.md
name: litestar-security
description: "Auto-activate for litestar_security, SecurityPlugin, SecurityConfig, CurrentUser, Principal, SecurityContext, requires_role, requires_scope, requires_authenticated, requires_tenant, requires_tenant_role, requires_capability, or requires_assurance. Not for raw auth guards alone — use litestar-auth-guards."

Litestar Security

`litestar-security` 0.6.0 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 `auth=`.** Put policy on the route, or on a router/controller/app through `opt={"auth": ...}`. The nearest native owner wins.
  • **Keep authorization in `guards=[...]`.** Litestar's `security=` parameter is reserved for the OpenAPI requirements projected from `auth`.
  • **Inject the user with `CurrentUser[T]`.** Use `NamedDependency[CurrentUser[UserType]]`; it rejects anonymous and userless service principals. `principal` and `security_context` stay typed on public routes too.
  • **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.** Static assets and dashboards carry no `auth` and compile to implicit `required()`, so they answer `401` until listed in `SecurityConfig(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 litestar import Controller, get
from litestar_security import 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 it at whichever layer owns the decision:

@get("/health", auth=public())
async def health() -> dict[str, str]:
    return {"status": "ok"}


class AccountController(Controller):
    opt = {"auth": required("session")}

Custom controller class attributes are not propagated by Litestar — policy must live in `opt`, or use the typed `SecureController` / `PublicController` base classes.

Authorization Guards

from litestar import Controller, get
from litestar_security import requires_any_of, requires_role, requires_scope


class ReportsController(Controller):
    path = "/reports"
    opt = {"auth": 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 Names

The plugin registers these; do not shadow them.

| Key | Type | Use | | --- | --- | --- | | `principal` | `Principal` | Stable envelope identity plus the active user model | | `security_context` | `SecurityContext` | Active session, evidence, snapshot, and restrictions | | `current_user` | `CurrentUser[User]` | Narrowing shortcut; rejects anonymous and service principals | | `websocket_connect_tokens` | `WebSocketConnectTokenService` | WebSocket connect-token manager |

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](references/providers.md).

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.

Read more
Ships withlitestar

Opinionated, first-party agent skills, plugins, subagents, slash commands, and MCP servers for the Litestar framework and its ecosystem — publishable to every major AI agent and IDE from a single repo.

Get the whole plugin

Other skills on litestar.