Authentication & Authorization
FastPluggy ships a minimal auth layer built on Starlette's AuthenticationMiddleware.
Auth backends are provided by plugins (e.g. auth_user) and auto-wired at startup.
How it works
- No auth plugin installed → all routes are open,
request.state.current_userisFPAnonymousUser - Auth plugin installed (e.g.
auth_user) → the plugin callsfast_pluggy.set_auth_manager(backend)duringon_load_complete, which addsAuthenticationMiddlewareand enables auth checks on all core routes
You can also pass an auth manager explicitly:
If set explicitly, plugins will not override it.
set_auth_manager(backend)
Sets the auth backend at runtime. Called automatically by auth plugins, but can also be used programmatically:
This:
- Sets self.auth_manager
- Adds Starlette's AuthenticationMiddleware
- Updates the auth_enable template global
Dependencies
require_authentication
Rejects unauthenticated requests (401) or redirects to login if the auth backend
defines on_authenticate_error. When no auth manager is set, this is a no-op —
all requests pass through.
# Protect an entire router
app.include_router(my_router, dependencies=[Depends(require_authentication)])
# Or a single route
@router.get("/secret", dependencies=[Depends(require_authentication)])
async def secret(request: Request): ...
require_role(role: str)
Requires the user to have a specific role (checked against request.auth.scopes).
FastPluggy uses "fp_admin" to protect its own admin routes. No-op when auth manager
is not set.
Current user
Set by CurrentUserMiddleware on every request:
user = request.state.current_user # FPAnonymousUser if not authenticated
if user.is_authenticated:
...
if user.is_admin:
...
Available in templates as {{ request.state.current_user }}.
FPAnonymousUser extends Starlette's UnauthenticatedUser and is used as the
fallback when no user is authenticated. It guarantees request.state.current_user
is never None.
The user object shape depends on the auth backend. FastPluggy core expects:
| Attribute | Type | Description |
|---|---|---|
is_authenticated |
bool |
False for anonymous, True for logged-in users |
display_name |
str |
Shown in the topbar user menu |
is_admin |
bool |
Controls visibility of the admin sidebar section |
profile_picture |
str\|None |
Optional; used for avatar display |
Writing a custom auth backend
Implement AuthInterface (extends Starlette's AuthenticationBackend):
from fastpluggy.core.auth.auth_interface import AuthInterface
class MyAuthManager(AuthInterface):
@property
def user_model(self):
return MyUserModel
async def authenticate(self, conn):
# Return (AuthCredentials, user) or None
...
async def on_authenticate_error(self, request):
# Return a Response (e.g. redirect) or raise HTTPException
...
Then either pass it to FastPluggy(app, auth_manager=MyAuthManager()) or call
fast_pluggy.set_auth_manager(MyAuthManager()) from a plugin's on_load_complete.