Skip to main content

Enable SSO, Authentication & Authorization for Your App

Add login, enterprise SSO, and fine-grained access control to your application. This guide registers your app, wires a login button in React, Node.js, or Python, optionally enables SAML/OIDC SSO, and adds permission checks to protect routes.

Prerequisites

Step 1: Register Your Application​

In the Organization Portal, go to Applications → New application.

FieldValue
ProtocolOpenID Connect
Application nameYour app name
What the application isWeb application (for server-side) or Single-page or mobile app (for React/Vue/Angular)
Redirect URIhttps://myapp.com/auth/callback

The Create application form with Web application selected and a redirect URI entered

Click Create application and copy your Client ID (and Client Secret for web apps). The client secret is shown once, on the page you land on; afterwards it can only be regenerated. For a single-page app, also add its origin under Browser CORS origins on the application's Configuration tab.


Step 2: Add a Login Button​

React / SPA​

npm install @lumoauth/react
import { LumoAuthProvider, SignIn, SignedIn, SignedOut, UserButton } from '@lumoauth/react';

// Wrap your app root
function App() {
return (
<LumoAuthProvider
domain="https://app.lumoauth.dev"
orgId="YOUR_ORG_ID"
clientId="YOUR_CLIENT_ID"
>
<SignedIn>
<UserButton showName />
<Dashboard />
</SignedIn>
<SignedOut>
<SignIn afterSignInUrl="/dashboard" />
</SignedOut>
</LumoAuthProvider>
);
}

Node.js / Express​

The Express integration ships as the @lumoauth/express package. It mounts the PKCE login flow (/auth/login, /auth/callback, /auth/logout) and exposes requireAuth() — you don't hand-roll the code exchange.

npm install @lumoauth/express express express-session
import "dotenv/config";
import express from "express";
import session from "express-session";
import { lumoAuthMiddleware, requireAuth } from "@lumoauth/express";

const app = express();

// Session middleware MUST be mounted before lumoAuthMiddleware.
app.use(session({
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
}));

app.use(lumoAuthMiddleware({
baseUrl: "https://app.lumoauth.dev",
organization: "YOUR_ORG_ID",
clientId: "YOUR_CLIENT_ID",
clientSecret: "YOUR_CLIENT_SECRET", // omit for public clients
postLoginRedirect: "/dashboard",
}));

// req.user is populated after sign-in; requireAuth() gates a handler.
app.get("/dashboard", requireAuth(), (req, res) => res.json(req.user));

See the SDKs reference for the full middleware and requireAuth() options.

Python (FastAPI)​

pip install 'lumoauth[fastapi]' itsdangerous

The lumoauth.fastapi router mounts /login, /callback, and /logout for you; get_current_user is the dependency you use everywhere else. SessionMiddleware must be mounted before the router.

import os
from fastapi import FastAPI, Depends
from fastapi.responses import RedirectResponse, HTMLResponse
from starlette.middleware.sessions import SessionMiddleware
from lumoauth.fastapi import lumo_auth_router, get_current_user, User

app = FastAPI()
app.add_middleware(SessionMiddleware, secret_key=os.environ["SESSION_SECRET"])

app.include_router(
lumo_auth_router(
base_url="https://app.lumoauth.dev",
organization="YOUR_ORG_ID",
client_id="YOUR_CLIENT_ID",
client_secret="YOUR_CLIENT_SECRET", # omit for public/SPA clients
callback_path="/auth/callback",
),
prefix="/auth",
)

@app.get("/dashboard", response_class=HTMLResponse)
def dashboard(user: User | None = Depends(get_current_user)):
if user is None:
return RedirectResponse("/auth/login")
return f"<h1>Hi {user.email}</h1>"

See the full FastAPI quickstart for required-auth and scope-checked dependencies.


Step 3: Enable Enterprise SSO (Optional)​

Enable SAML or OIDC SSO (single sign-on through your customer's own identity provider) so users can log in with their corporate identity.

In the portal: Settings → Integrations → Enterprise SSO (SAML) → Add SAML IdP, or Enterprise SSO (OIDC) → Add OIDC IdP

The Integrations page with its section tabs, showing Enterprise SSO (SAML)

  • SAML 2.0: Paste your IdP metadata URL or XML
  • OIDC: Enter your IdP's issuer URL, client ID, and secret (the endpoints are discovered from the issuer)

Your login page automatically shows the SSO option — no code changes required.


Step 4: Protect Routes with Permissions​

Define roles and permissions in the portal under Access control → Roles & permissions.

The Roles page with the Create role button

Then check permissions in your app. The authorization endpoints are global (/api/v1/authz/..., no /orgs/{orgId} prefix); the organization comes from the token:

curl -X POST https://app.lumoauth.dev/api/v1/authz/check \
-H "Authorization: Bearer USER_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"permission": "billing.manage"}'
{ "allowed": true }

In React, use the Protect component:

import { Protect } from '@lumoauth/react';

<Protect permission="billing.manage" fallback={<p>Access denied</p>}>
<BillingDashboard />
</Protect>

What's Next​

TopicDescription
OAuth 2.0 & OIDCDeep-dive into token flows
Access ControlRBAC, ABAC, Zanzibar ReBAC
Enterprise SSOSAML and OIDC federation
Multi-TenancyIsolate customers in your SaaS
React QuickstartFull React integration guide
Node.js QuickstartFull Node.js integration guide