Implements SaaSKit login in Django, FastAPI, or Flask so an agent can add login, callback, session cookies, and logout. Use when the user wants SaaSKit Django, FastAPI, or Flask auth. It does not write Node or Next.js login (that's `implement-saaskit` or `implement-saaskit-nextjs`).
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
A direct command skips the review prompt. Inspect the source before running it.
Implements SaaSKit login in Django, FastAPI, or Flask so an agent can add login, callback, session cookies, and logout. Use when the user wants SaaSKit Django, FastAPI, or Flask auth. It does not write Node or Next.js login (that's `implement-saaskit` or `implement-saaskit-nextjs`).
Implement SaaSKit Python
Add login, callback, an encrypted sk_session cookie, logout, and refresh in FastAPI. Then stop.
Guardrails
MUST keep SCALEKIT_REDIRECT_URI, the dashboard Redirect URI, and the process host:port the same string.
MUST call auth.install(app). app.include_router(auth.router) alone skips the 302 handler.
MUST set cookie_secure=False on local HTTP. MUST set it True in production.
MUST treat returnTo as a relative path only (/..., not //…). The adapter already sanitizes it.
Gotchas
setup-saaskit already wrote env and registered the redirect. Start there.
Read SCALEKIT_ENVIRONMENT_URL, SCALEKIT_CLIENT_ID, SCALEKIT_CLIENT_SECRET, and SCALEKIT_REDIRECT_URI. Never SCALEKIT_ENV_URL. Do not prepend https://.
Also need COOKIE_ENCRYPTION_SECRET (openssl rand -base64 32). Keep it identical on every server.
Default path is FastAPI ScalekitAuth. Do not hand-roll ScalekitClient routes. Do not copy Express cookies from .
manage-saaskit-sessions
Adapter defaults: GET /login, /callback, /logout. Cookie is sk_session (HttpOnly, SameSite=lax). CSRF cookie is sk_oauth_state.
If SCALEKIT_REDIRECT_URI already ends in /auth/callback, pass callback_path="/auth/callback" or change both the env and the dashboard to /callback. Keep that URI's host and port. Run the app on that port. Do not keep port 3000 in env and run FastAPI on 5001.
user from requires_auth is access-token claims. sub is always present.
requires_auth refreshes. Do not add /auth/refresh. Do not return a Response from a protected endpoint — that drops the refreshed cookie.
Register the Initiate Login URL and the Post Logout Redirect URI too.
Next.js App Router → name implement-saaskit-nextjs. Stop.
If env is missing, collect the four Scalekit values from app.scalekit.com → Developers → Settings → API Credentials. Register SCALEKIT_REDIRECT_URI under Authentication → Redirect URLs → Allowed callback URLs. Use one origin for that URI, the dashboard, and the process. Do not mix setup's localhost:3000 with adapter samples on localhost:5001. Also register that origin's /login as Initiate Login URL and / as Post Logout Redirect URI. Generate COOKIE_ENCRYPTION_SECRET. Do not invent credential values.
Done when: this skill is the right path, the four Scalekit env names exist, and COOKIE_ENCRYPTION_SECRET exists.
Step 2 — Install and init
Install "scalekit-sdk-python[fastapi]" only when the repo has no Scalekit FastAPI extra yet. Do not add Django or Flask packages.
# app.pyimport os
from fastapi import Depends, FastAPI
from scalekit.frameworks.fastapi import ScalekitAuth
app = FastAPI()
auth = ScalekitAuth(
env_url=os.environ["SCALEKIT_ENVIRONMENT_URL"],
client_id=os.environ["SCALEKIT_CLIENT_ID"],
client_secret=os.environ["SCALEKIT_CLIENT_SECRET"],
redirect_uri=os.environ["SCALEKIT_REDIRECT_URI"],
cookie_encryption_secret=os.environ["COOKIE_ENCRYPTION_SECRET"],
cookie_secure=False, # set True behind HTTPS
)
auth.install(app)
cookie_secure defaults to True in the SDK. Browsers drop a Secure cookie on plain http://localhost.
Done when: the extra is installed, ScalekitAuth reads those env vars, and auth.install(app) has run.
Step 3 — Login, callback, session
auth.install registers GET /login, GET /callback, and GET /logout. Do not write those routes by hand.
/login sets sk_oauth_state, requests openid profile email offline_access, and redirects to Scalekit.
/callback compares sk_oauth_state to state before authenticate_with_code. Mismatch → 302 /login. Success writes encrypted sk_session and deletes the state cookie.
returnTo is a relative path only.
Link to /login. Do not send the browser to Scalekit yourself.
Done when:/login redirects to Scalekit, /callback writes sk_session, and the browser leaves /callback.
Step 4 — Logout
GET /logout. Link to /logout. full_logout defaults to True: get_logout_url with id_token_hint and post_logout_redirect_uri, then delete sk_session.
Register that same origin as a Post Logout Redirect URI.
Done when:sk_session is gone and the browser hits the logout URL.
Step 5 — Protect routes
requires_auth is the caller for refresh. It checks sk_session, refreshes when expires_at is near, and 302s to /login?returnTo=… when the session is missing. Never a JSON 401.