FusionAuth Cheat Sheet
Overview
FusionAuth is a full-featured identity and access management (IAM) platform that can be self-hosted or used as a managed cloud service. It provides authentication, authorization, user management, SSO, multi-factor authentication, and consent management. FusionAuth supports OAuth 2.0, OpenID Connect, SAML v2, and passwordless login flows.
FusionAuth distinguishes itself with multi-tenant support, advanced theming for login pages, webhook events, lambda functions for token customization, and a comprehensive REST API. It handles millions of users efficiently and offers features like breached password detection, account linking, family management, and advanced registration forms.
Installation
# Docker (quickest start)
docker pull fusionauth/fusionauth-app
docker run -d \
--name fusionauth \
-p 9011:9011 \
-e DATABASE_URL=jdbc:postgresql://host:5432/fusionauth \
-e DATABASE_USERNAME=fusionauth \
-e DATABASE_PASSWORD=password \
-e FUSIONAUTH_APP_MEMORY=512M \
-e SEARCH_TYPE=database \
fusionauth/fusionauth-app
# Docker Compose (recommended)
curl -o docker-compose.yml https://raw.githubusercontent.com/FusionAuth/fusionauth-containers/main/docker/fusionauth/docker-compose.yml
docker compose up -d
# Debian/Ubuntu
sudo apt-get install fusionauth-app fusionauth-search
# macOS Homebrew
brew install fusionauth-app
# Access at http://localhost:9011
FusionAuth CLI (Kickstart)
{
"variables": {
"apiKey": "#{ENV.FUSIONAUTH_API_KEY}",
"applicationId": "#{UUID()}"
},
"apiKeys": [
{
"key": "#{apiKey}",
"description": "Admin API Key"
}
],
"requests": [
{
"method": "POST",
"url": "/api/application/#{applicationId}",
"body": {
"application": {
"name": "My App",
"oauthConfiguration": {
"authorizedRedirectURLs": ["http://localhost:3000/callback"],
"logoutURL": "http://localhost:3000",
"clientSecret": "super-secret",
"enabledGrants": ["authorization_code", "refresh_token"]
}
}
}
}
]
}
REST API
| Endpoint | Description |
|---|---|
POST /api/user/registration | Register a user to an application |
POST /api/login | Authenticate a user |
GET /api/user/{userId} | Retrieve a user |
PUT /api/user/{userId} | Update a user |
DELETE /api/user/{userId} | Delete a user |
POST /api/user/search | Search users |
GET /api/application | List applications |
POST /api/application | Create an application |
GET /api/tenant | List tenants |
POST /api/group | Create a group |
# Create a user
curl -X POST http://localhost:9011/api/user/registration \
-H "Authorization: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"user": {
"email": "user@example.com",
"password": "SecureP@ss123!"
},
"registration": {
"applicationId": "YOUR_APP_ID",
"roles": ["user"]
}
}'
# Login
curl -X POST http://localhost:9011/api/login \
-H "Content-Type: application/json" \
-d '{
"loginId": "user@example.com",
"password": "SecureP@ss123!",
"applicationId": "YOUR_APP_ID"
}'
# Search users
curl -X POST http://localhost:9011/api/user/search \
-H "Authorization: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"search": {
"queryString": "email:*@example.com",
"numberOfResults": 25,
"startRow": 0
}
}'
OAuth 2.0 Integration
// Node.js with passport
const passport = require("passport");
const OAuth2Strategy = require("passport-oauth2");
passport.use(new OAuth2Strategy({
authorizationURL: "http://localhost:9011/oauth2/authorize",
tokenURL: "http://localhost:9011/oauth2/token",
clientID: process.env.FUSIONAUTH_CLIENT_ID,
clientSecret: process.env.FUSIONAUTH_CLIENT_SECRET,
callbackURL: "http://localhost:3000/callback",
}, (accessToken, refreshToken, profile, done) => {
return done(null, profile);
}));
// Direct OAuth2 flow
const authUrl = new URL("http://localhost:9011/oauth2/authorize");
authUrl.searchParams.set("client_id", CLIENT_ID);
authUrl.searchParams.set("response_type", "code");
authUrl.searchParams.set("redirect_uri", "http://localhost:3000/callback");
authUrl.searchParams.set("scope", "openid email profile");
Lambdas (Token Customization)
// JWT Populate Lambda
function populate(jwt, user, registration) {
// Add custom claims
jwt.roles = registration.roles;
jwt.email = user.email;
jwt.plan = user.data.plan || "free";
// Add group memberships
if (user.memberships) {
jwt.groups = user.memberships.map(m => m.groupId);
}
// Conditional claims
if (registration.roles.includes("admin")) {
jwt.permissions = ["read:all", "write:all", "delete:all"];
}
}
Multi-Tenant Configuration
# Create a tenant
curl -X POST http://localhost:9011/api/tenant \
-H "Authorization: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"tenant": {
"name": "Acme Corp",
"issuer": "acme.example.com",
"emailConfiguration": {
"host": "smtp.example.com",
"port": 587,
"username": "noreply@acme.com"
},
"jwtConfiguration": {
"accessTokenKeyId": "KEY_ID",
"timeToLiveInSeconds": 3600,
"refreshTokenTimeToLiveInMinutes": 43200
}
}
}'
Webhooks
# Register a webhook
curl -X POST http://localhost:9011/api/webhook \
-H "Authorization: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"webhook": {
"url": "https://api.example.com/webhooks/fusionauth",
"eventsEnabled": {
"user.create": true,
"user.update": true,
"user.delete": true,
"user.login.success": true,
"user.login.failed": true,
"user.registration.create": true,
"jwt.refresh-token.revoke": true
}
}
}'
Advanced Usage
Breached Password Detection
curl -X PATCH http://localhost:9011/api/tenant/TENANT_ID \
-H "Authorization: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"tenant": {
"passwordValidationRules": {
"breachDetection": {
"enabled": true,
"matchMode": "High",
"onLogin": "RecordOnly"
}
}
}
}'
SAML v2 Identity Provider
curl -X POST http://localhost:9011/api/identity-provider \
-H "Authorization: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"identityProvider": {
"type": "SAMLv2",
"name": "Corporate SSO",
"idpEndpoint": "https://idp.example.com/saml/sso",
"issuer": "https://idp.example.com",
"keyId": "SIGNING_KEY_ID",
"emailClaim": "email",
"enabled": true,
"applicationConfiguration": {
"APP_ID": {
"enabled": true,
"createRegistration": true
}
}
}
}'
Theme Customization
curl -X POST http://localhost:9011/api/theme \
-H "Authorization: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"theme": {
"name": "Custom Theme",
"stylesheet": "body { font-family: Inter, sans-serif; }",
"templates": {
"oauth2Authorize": "<!-- Custom FreeMarker template -->"
}
}
}'
Configuration
# Environment variables
FUSIONAUTH_APP_URL=http://localhost:9011
FUSIONAUTH_API_KEY=your-api-key
FUSIONAUTH_CLIENT_ID=your-client-id
FUSIONAUTH_CLIENT_SECRET=your-client-secret
FUSIONAUTH_TENANT_ID=your-tenant-id
# fusionauth.properties (self-hosted)
database.url=jdbc:postgresql://localhost:5432/fusionauth
database.username=fusionauth
database.password=password
fusionauth-app.memory=512M
search.type=database
fusionauth-app.url=http://localhost:9011
Troubleshooting
| Issue | Solution |
|---|---|
| Cannot connect to database | Verify PostgreSQL is running; check JDBC connection string |
| Login page not loading | Check FusionAuth is running on port 9011; verify application config |
| OAuth redirect mismatch | Ensure authorizedRedirectURLs matches exactly in application settings |
| JWT claims missing | Check Lambda is assigned to the application; verify Lambda logic |
| Webhook not firing | Verify webhook URL is accessible; check event types are enabled |
| Email not sending | Configure SMTP settings in tenant; check spam filters |
| Search not working | Switch SEARCH_TYPE to elasticsearch for advanced search |
| Memory issues | Increase FUSIONAUTH_APP_MEMORY; allocate at least 512M |