Skip to content

Route Authentication

Fullfinity provides three authentication modes for API routes, allowing fine-grained control over who can access each endpoint.

Users are classified by their group membership:

Group IdentifierNameDescription
core_internalInternalBackend users with full system access
core_portalPortalExternal users with limited access (customers, vendors)
core_publicPublicGuest/anonymous users

Use these FastAPI dependencies to protect your routes:

Restricts access to internal users only. Use for admin panels, settings, and sensitive operations.

from fastapi import Depends
from fullfinity.engine.middleware import requires_internal
@router.post("/api/settings/update", dependencies=[Depends(requires_internal)])
async def update_settings(request: Request):
# Only internal users can access this
pass

Behavior:

  • Returns 401 if no valid token
  • Returns 403 if user is not in core_internal group

Allows any authenticated user (internal or portal). Use for features accessible to all logged-in users.

from fastapi import Depends
from fullfinity.engine.middleware import requires_user
@router.get("/api/my-profile", dependencies=[Depends(requires_user)])
async def get_profile(request: Request):
# Internal and portal users can access this
pass

Behavior:

  • Returns 401 if no valid token
  • Returns 403 if user only has core_public group (guest user)

Allows public access with optional authentication. Tries to authenticate if a token is present, otherwise falls back to guest user.

from fastapi import Depends
from fullfinity.engine.middleware import allows_public
from fullfinity.engine.context import env_ctx
@router.get("/api/products", dependencies=[Depends(allows_public)])
async def list_products(request: Request):
# Anyone can access, but authenticated users get personalized results
env = env_ctx.get()
user = env.user # Either the authenticated user or guest user
pass

Behavior:

  • Never returns 401/403
  • Always succeeds with either authenticated user or guest user context
  • Useful for pages that work for everyone but offer personalization when logged in

For routes that need no authentication at all (no user context):

@router.get("/api/health")
async def health_check():
# No authentication, no user context
return {"status": "ok"}
DependencyInternalPortalPublic/GuestAnonymous
requires_internal❌ 403❌ 403❌ 401
requires_user❌ 403❌ 401
allows_public✅ (as guest)✅ (as guest)
(none)✅ (no user ctx)
# Module installation - internal admins only
@router.post("/api/modules/install", dependencies=[Depends(requires_internal)])
async def install_module(request: Request, module_name: str):
pass
# User management
@router.get("/api/users", dependencies=[Depends(requires_internal)])
async def list_users(request: Request):
pass
# View own orders - any logged-in user
@router.get("/api/orders", dependencies=[Depends(requires_user)])
async def my_orders(request: Request):
env = env_ctx.get()
user = env.user
# Filter by user's company/permissions
pass
# Submit support ticket
@router.post("/api/tickets", dependencies=[Depends(requires_user)])
async def create_ticket(request: Request):
pass
# Product catalog - visible to everyone
@router.get("/api/catalog", dependencies=[Depends(allows_public)])
async def catalog(request: Request):
env = env_ctx.get()
user = env.user
# Show prices based on user type (guest sees retail, portal sees wholesale)
pass
# Website pages
@router.get("/{path:path}", dependencies=[Depends(allows_public)])
async def web_page(request: Request, path: str):
pass

Route authentication works alongside model-level permissions:

  1. Route level: Controls who can call the endpoint (requires_internal, etc.)
  2. Model level: Controls CRUD operations per group (see Model Access)
  3. Record level: Filters visible records per group (see Record Rules)
@router.get("/api/invoices", dependencies=[Depends(requires_user)])
async def list_invoices(request: Request):
# Route allows portal + internal
# But Invoice model access rules determine what each user can read
invoices = await Invoice.filter().all() # Automatically filtered by record rules
return invoices