Contents
mafia docs
GitHub authentication
GitHub OAuth is optional and disabled by default for loopback-only development.
When enabled, every user must match an immutable GitHub user ID allowlist or active membership in one configured organization. There is no unrestricted GitHub-account mode because users operate the deployment’s GitHub and Copilot identities.
Create an OAuth App
Create a separate GitHub OAuth App for each deployment:
- Homepage URL: the public HTTPS origin, such as
https://mafia.example.com - Authorization callback URL: the same origin followed by
/auth/callback
The callback URL must exactly match MAFIA_GITHUB_OAUTH_CALLBACK_URL.
Configure credentials
Generate independent secrets:
openssl rand -hex 32
openssl rand -hex 32
MAFIA_AUTH_MODE=github
MAFIA_GITHUB_OAUTH_CLIENT_ID=...
MAFIA_GITHUB_OAUTH_CLIENT_SECRET=...
MAFIA_GITHUB_OAUTH_CALLBACK_URL=https://mafia.example.com/auth/callback
MAFIA_GITHUB_SESSION_SECRET=<first-generated-secret>
MAFIA_INTERNAL_SECRET=<second-generated-secret>
Then configure at least one authorization policy:
MAFIA_GITHUB_ALLOWED_USER_IDS=[37492]
MAFIA_GITHUB_ALLOWED_ORG=frostyard
Find your immutable numeric user ID with:
gh api user --jq .id
When both policies are present, a user is allowed if their ID is listed or their organization membership is active. Organization mode requests read:org; user-ID-only mode requests no GitHub OAuth scopes.
Session boundary
OAuth uses authorization code flow with PKCE and a signed, short-lived state cookie. After fetching /user and any required organization membership, mafia discards the access token.
The browser receives only a signed, HttpOnly, Secure, SameSite=Lax session cookie containing the immutable user ID, login, avatar URL, and expiration.
Next.js and FastAPI both validate the signed browser session at their respective boundaries. Keep both listeners bound to loopback. MAFIA_INTERNAL_SECRET authenticates only server-to-server traffic from Next.js to FastAPI.
Publish through Caddy
Expose only Caddy. The repository’s contrib/Caddyfile terminates TLS and applies forward_auth before routing pages and CopilotKit to Next.js or REST, AG-UI, and readiness traffic to FastAPI.
Set MAFIA_DOMAIN in Caddy’s service environment, then validate and reload the configuration:
sudo MAFIA_DOMAIN=mafia.example.com caddy validate \
--config /etc/caddy/Caddyfile
sudo systemctl reload caddy
Never add MAFIA_INTERNAL_SECRET to Caddy or expose it to browsers.