Quick Start

Add authentication to your app in 5 minutes.

1. Create an Account

Sign up at manage.authfi.app. You’ll get a tenant with a slug like acme.

2. Create an Application

In the console, go to Applications → Create Application:

  • Name: My App
  • Type: Web / SPA / Native / M2M
  • Redirect URIs: http://localhost:3000/callback

You’ll get a client_id and client_secret.

3. Install the SDK

# Node.js
npm install authfi

# Go
go get github.com/queflyhq/authfi/sdk/go

# Python
pip install authfi

4. Protect Your Routes

Node.js (Express)

const authfi = require('authfi')({
  tenant: 'acme',
  apiKey: 'sk_live_...',
  applicationId: 'your-client-id',
  autoSync: true
});

// Protect a route with a permission
app.get('/api/users', authfi.require('read:users'), (req, res) => {
  // req.user contains: id, email, roles, permissions, tenant_id
  res.json({ user: req.user });
});

// Require a specific role
app.post('/api/admin', authfi.requireRole('admin'), handler);

// Just verify the token (no permission check)
app.get('/api/profile', authfi.authenticate(), handler);

// Start the SDK (syncs permissions to AuthFI)
authfi.start();

Go (Chi)

auth := authfi.New(authfi.Config{
    Tenant:        "acme",
    APIKey:        "sk_live_...",
    ApplicationID: "your-client-id",
    AutoSync:      true,
})

r.With(auth.Require("read:users")).Get("/api/users", handler)
r.With(auth.RequireRole("admin")).Post("/api/admin", handler)

auth.RegisterPermission("read:users", "List all users")
go auth.Sync()

Python (Flask)

from authfi import AuthFI

auth = AuthFI(
    tenant='acme',
    api_key='sk_live_...',
    application_id='your-client-id',
    auto_sync=True,
)

@app.route('/api/users')
@auth.require('read:users')
def get_users():
    user = auth.current_user()
    return jsonify(user)

auth.sync()

5. Set Up Login

Point your login button to AuthFI’s hosted login page:

https://acme.authfi.app/authorize
  ?client_id=your-client-id
  &redirect_uri=http://localhost:3000/callback
  &response_type=code
  &scope=openid profile email
  &state=random-state
  &code_challenge=...
  &code_challenge_method=S256

After login, exchange the authorization code for tokens:

const response = await fetch('https://acme.authfi.app/token', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    grant_type: 'authorization_code',
    code: authCode,
    redirect_uri: 'http://localhost:3000/callback',
    client_id: 'your-client-id',
    code_verifier: pkceVerifier
  })
});
// Returns: { access_token, refresh_token, expires_in, id_token }

6. Verify It Works

curl -H "Authorization: Bearer <access_token>" 
  http://localhost:3000/api/users

What’s in the JWT?

{
  "sub": "user-uuid",
  "email": "alice@acme.com",
  "email_verified": true,
  "tenant_id": "tenant-uuid",
  "roles": ["admin"],
  "permissions": ["read:users", "write:users"],
  "groups": ["engineering"],
  "azp": "your-client-id",
  "iss": "https://acme.authfi.app",
  "exp": 1711234567
}

Next Steps