475 lines
13 KiB
Markdown
475 lines
13 KiB
Markdown
# Authentik Setup Guide for Kaboot
|
|
|
|
This guide walks through configuring Authentik as the OAuth2/OIDC identity provider for Kaboot.
|
|
|
|
## Quick Start (Automated Setup)
|
|
|
|
The recommended approach uses Authentik Blueprints for automatic configuration:
|
|
|
|
```bash
|
|
# 1. Run setup script (generates all secrets including admin password)
|
|
./scripts/setup.sh
|
|
|
|
# 2. Start the stack
|
|
docker compose up -d
|
|
|
|
# 3. Wait for Authentik to initialize (~30 seconds)
|
|
docker compose logs -f authentik-server | grep -i blueprint
|
|
|
|
# 4. Set password for test user
|
|
docker compose exec authentik-server ak set_password kaboottest
|
|
# Enter: kaboottest (or your preferred password)
|
|
|
|
# 5. (Optional) Create app password for service account via UI
|
|
# See "Step 7: Create a Service Account" below
|
|
```
|
|
|
|
The blueprint automatically creates:
|
|
- Kaboot OAuth2/OIDC Provider (public client, client_id: `kaboot-spa`)
|
|
- Kaboot Application with proper redirect URIs
|
|
- `kaboot-users` Group
|
|
- Enrollment flow with sign-up capability
|
|
- Password complexity policy
|
|
- Test user (`kaboottest`)
|
|
- Service account (`kaboot-test-service`)
|
|
|
|
Your admin credentials are printed by `setup.sh` - save them!
|
|
|
|
---
|
|
|
|
## Manual Setup (Alternative)
|
|
|
|
If you prefer manual configuration or need to customize the setup, follow the steps below.
|
|
|
|
## Prerequisites
|
|
|
|
- Docker and Docker Compose installed
|
|
- Kaboot stack running (`docker compose up -d`)
|
|
- Access to `http://localhost:9000`
|
|
|
|
## Step 1: Initial Authentik Setup
|
|
|
|
1. Navigate to `http://localhost:9000/if/flow/initial-setup/`
|
|
- **Important**: Include the trailing slash `/`
|
|
|
|
2. Create the admin account:
|
|
- Email: Your email address
|
|
- Password: Choose a strong password
|
|
|
|
3. Log in with the credentials you just created
|
|
|
|
## Step 2: Create the Kaboot Application
|
|
|
|
1. In the Authentik admin interface, go to **Applications** > **Applications**
|
|
|
|
2. Click **Create with provider**
|
|
|
|
3. **Application Settings**:
|
|
| Field | Value |
|
|
|-------|-------|
|
|
| Name | `Kaboot` |
|
|
| Slug | `kaboot` |
|
|
| Launch URL | `http://localhost:5173` |
|
|
|
|
4. Click **Next**
|
|
|
|
## Step 3: Configure OAuth2/OIDC Provider
|
|
|
|
1. Select **OAuth2/OIDC** as the Provider Type
|
|
|
|
2. Click **Next**
|
|
|
|
3. **Provider Configuration**:
|
|
| Field | Value |
|
|
|-------|-------|
|
|
| Name | `Kaboot OAuth2` |
|
|
| Authorization flow | `default-provider-authorization-implicit-consent` |
|
|
| Client type | `Public` |
|
|
| Client ID | `kaboot-spa` |
|
|
|
|
4. **Redirect URIs** (one per line):
|
|
```
|
|
http://localhost:5173/callback
|
|
http://localhost:5173/silent-renew.html
|
|
http://localhost:5173
|
|
```
|
|
|
|
5. **Advanced Settings**:
|
|
| Field | Value |
|
|
|-------|-------|
|
|
| Subject mode | `Based on the User's hashed ID` |
|
|
| Include claims in id_token | `Yes` |
|
|
| Issuer mode | `Each provider has a different issuer` |
|
|
|
|
6. **Scopes** - Ensure these are selected:
|
|
- `openid`
|
|
- `profile`
|
|
- `email`
|
|
- `offline_access` (for refresh tokens)
|
|
|
|
7. Click **Submit**
|
|
|
|
## Step 4: Enable User Registration (Sign Up)
|
|
|
|
By default, Authentik only shows a login form. To allow users to sign up, you need to create an enrollment flow and link it.
|
|
|
|
### Step 4.1: Create the Enrollment Prompt Stage
|
|
|
|
1. Go to **Flows and Stages** > **Stages**
|
|
|
|
2. Click **Create**
|
|
|
|
3. Select **Prompt Stage** and click **Next**
|
|
|
|
4. Configure:
|
|
| Field | Value |
|
|
|-------|-------|
|
|
| Name | `enrollment-prompt` |
|
|
|
|
5. In the **Fields** section, move these to the **Selected** side:
|
|
- `default-source-enrollment-field-username` (username)
|
|
- `default-user-settings-field-email` (email)
|
|
- `default-password-change-field-password` (password)
|
|
- `default-password-change-field-password-repeat` (password_repeat)
|
|
|
|
6. (Optional) In **Validation policies**, select `password-complexity` if you created it in Step 4.2
|
|
|
|
7. Click **Finish**
|
|
|
|
### Step 4.2: (Optional) Create Password Complexity Policy
|
|
|
|
1. Go to **Customisation** > **Policies**
|
|
|
|
2. Click **Create** and select **Password Policy**
|
|
|
|
3. Configure:
|
|
| Field | Value |
|
|
|-------|-------|
|
|
| Name | `password-complexity` |
|
|
| Password field | `password` |
|
|
| Minimum length | `8` |
|
|
| Amount of uppercase characters | `1` |
|
|
| Amount of lowercase characters | `1` |
|
|
| Amount of digits | `1` |
|
|
|
|
4. Click **Finish**
|
|
|
|
You'll add this to the enrollment prompt stage later.
|
|
|
|
### Step 4.3: Create a Group for Kaboot Users
|
|
|
|
1. Go to **Directory** > **Groups**
|
|
|
|
2. Click **Create**
|
|
|
|
3. Configure:
|
|
| Field | Value |
|
|
|-------|-------|
|
|
| Name | `kaboot-users` |
|
|
|
|
4. Click **Create**
|
|
|
|
### Step 4.4: Create the User Write Stage
|
|
|
|
1. Go to **Flows and Stages** > **Stages**
|
|
|
|
2. Click **Create**
|
|
|
|
3. Select **User Write Stage** and click **Next**
|
|
|
|
4. Configure:
|
|
| Field | Value |
|
|
|-------|-------|
|
|
| Name | `enrollment-user-write` |
|
|
| User creation mode | `Create users when required` |
|
|
| Create users as inactive | Unchecked |
|
|
| Group | `kaboot-users` |
|
|
|
|
5. Click **Finish**
|
|
|
|
### Step 4.5: Create the User Login Stage
|
|
|
|
1. Go to **Flows and Stages** > **Stages**
|
|
|
|
2. Click **Create**
|
|
|
|
3. Select **User Login Stage** and click **Next**
|
|
|
|
4. Configure:
|
|
| Field | Value |
|
|
|-------|-------|
|
|
| Name | `enrollment-user-login` |
|
|
| Session duration | `hours=24` |
|
|
| Stay signed in offset | `days=30` |
|
|
| Network binding | `No binding` |
|
|
| GeoIP binding | `No binding` |
|
|
|
|
5. Click **Finish**
|
|
|
|
### Step 4.6: Create the Enrollment Flow
|
|
|
|
1. Go to **Flows and Stages** > **Flows**
|
|
|
|
2. Click **Create**
|
|
|
|
3. Configure:
|
|
| Field | Value |
|
|
|-------|-------|
|
|
| Name | `Enrollment Flow` |
|
|
| Title | `Sign Up` |
|
|
| Slug | `enrollment-flow` |
|
|
| Designation | `Enrollment` |
|
|
| Authentication | `No requirement` |
|
|
|
|
4. Click **Create**
|
|
|
|
5. Click on the newly created `enrollment-flow`
|
|
|
|
6. Go to the **Stage Bindings** tab
|
|
|
|
7. Click **Bind existing stage** and add stages in this order:
|
|
| Stage | Order |
|
|
|-------|-------|
|
|
| `enrollment-prompt` | 10 |
|
|
| `enrollment-user-write` | 20 |
|
|
| `enrollment-user-login` | 30 |
|
|
|
|
### Step 4.7: Bind the Group to the Kaboot Application
|
|
|
|
1. Go to **Applications** > **Applications** > **Kaboot**
|
|
|
|
2. Go to the **Policy / Group / User Bindings** tab
|
|
|
|
3. Click **Bind existing group**
|
|
|
|
4. Select `kaboot-users`
|
|
|
|
5. Click **Bind**
|
|
|
|
Now users in the `kaboot-users` group (which includes all users who sign up) will have access to Kaboot.
|
|
|
|
### Step 4.8: Link Enrollment Flow to Login
|
|
|
|
1. Go to **Flows and Stages** > **Stages**
|
|
|
|
2. Find and click on `default-authentication-identification`
|
|
|
|
3. Scroll down to **Flow settings**
|
|
|
|
4. In the **Enrollment flow** dropdown, select `enrollment-flow`
|
|
|
|
5. Click **Update**
|
|
|
|
Now when users visit the login page, they'll see a "Need an account? Sign up." link.
|
|
|
|
### Optional: Add Password Recovery
|
|
|
|
1. In **Flows and Stages** > **Stages** > `default-authentication-identification`
|
|
|
|
2. Set **Recovery flow** to `default-recovery-flow` (if it exists)
|
|
|
|
3. Click **Update**
|
|
|
|
## Step 5: Verify OIDC Endpoints
|
|
|
|
After creation, go to **Applications** > **Providers** > **Kaboot OAuth2**
|
|
|
|
Note these endpoints (you'll need them for frontend configuration):
|
|
|
|
| Endpoint | URL |
|
|
|----------|-----|
|
|
| Issuer | `http://localhost:9000/application/o/kaboot/` |
|
|
| Authorization | `http://localhost:9000/application/o/authorize/` |
|
|
| Token | `http://localhost:9000/application/o/token/` |
|
|
| UserInfo | `http://localhost:9000/application/o/userinfo/` |
|
|
| JWKS | `http://localhost:9000/application/o/kaboot/jwks/` |
|
|
|
|
## Step 5: Test the Configuration
|
|
|
|
1. Open the OpenID Configuration URL in your browser:
|
|
```
|
|
http://localhost:9000/application/o/kaboot/.well-known/openid-configuration
|
|
```
|
|
|
|
2. You should see a JSON response with all OIDC endpoints
|
|
|
|
## Step 6: Create a Test User
|
|
|
|
Create a regular user for manual browser testing.
|
|
|
|
1. Go to **Directory** > **Users**
|
|
|
|
2. Click **Create**
|
|
|
|
3. Fill in user details:
|
|
| Field | Value |
|
|
|-------|-------|
|
|
| Username | `kaboottest` |
|
|
| Name | `Kaboot Test` |
|
|
| Email | `kaboottest@test.com` |
|
|
|
|
4. After creation, click on the user and go to the **Credentials** tab
|
|
|
|
5. Click **Set password** and set it to `kaboottest`
|
|
|
|
6. **Bind the user to the Kaboot application**:
|
|
- Go to **Applications** > **Applications** > **Kaboot**
|
|
- Click the **Policy / Group / User Bindings** tab
|
|
- Click **Bind existing user**
|
|
- Select `kaboottest` and click **Bind**
|
|
|
|
## Step 7: Create a Service Account for API Testing
|
|
|
|
Create a service account that can obtain tokens programmatically for automated tests.
|
|
|
|
1. Go to **Directory** > **Users**
|
|
|
|
2. Click **Create Service Account**
|
|
|
|
3. Fill in details:
|
|
| Field | Value |
|
|
|-------|-------|
|
|
| Username | `kaboot-test-service` |
|
|
| Create group | Unchecked |
|
|
|
|
4. Click **Create**
|
|
|
|
5. **Create an App Password** for the service account:
|
|
- Click on the newly created `kaboot-test-service` user
|
|
- Go to the **App passwords** tab
|
|
- Click **Create App Password**
|
|
- Name it `api-tests`
|
|
- Copy the generated password (you won't see it again!)
|
|
|
|
6. **Bind the service account to the Kaboot application**:
|
|
- Go to **Applications** > **Applications** > **Kaboot**
|
|
- Click the **Policy / Group / User Bindings** tab
|
|
- Click **Bind existing user**
|
|
- Select `kaboot-test-service` and click **Bind**
|
|
|
|
7. **Save credentials to `server/.env.test`**:
|
|
```bash
|
|
TEST_USERNAME=kaboot-test-service
|
|
TEST_PASSWORD=<paste-app-password-here>
|
|
```
|
|
|
|
8. **Verify token generation works**:
|
|
```bash
|
|
cd server
|
|
npm run test:get-token
|
|
```
|
|
|
|
You should see "Token obtained successfully" and the access token printed.
|
|
|
|
## Environment Variables
|
|
|
|
### Development (localhost only)
|
|
|
|
For local development on a single machine:
|
|
|
|
```bash
|
|
KABOOT_HOST=localhost
|
|
```
|
|
|
|
### Development (network/mobile access)
|
|
|
|
To access from other devices (phones, tablets), set `KABOOT_HOST` to your machine's IP:
|
|
|
|
```bash
|
|
KABOOT_HOST=192.168.1.100
|
|
```
|
|
|
|
The setup script (`./scripts/setup.sh`) auto-detects your IP and configures:
|
|
- `.env` - Backend CORS and docker-compose variables
|
|
- `.env.local` - Frontend Vite environment variables
|
|
|
|
**Important**: You must also update redirect URIs in Authentik to include:
|
|
- `http://<your-ip>:5173/callback`
|
|
- `http://<your-ip>:5173/silent-renew.html`
|
|
- `http://<your-ip>:5173`
|
|
|
|
Then run the dev server with `npm run dev -- --host` to bind to all interfaces.
|
|
|
|
## Troubleshooting
|
|
|
|
### "Invalid redirect URI" error
|
|
- Ensure all redirect URIs are added exactly as configured in the provider
|
|
- Check for trailing slashes - they must match exactly
|
|
|
|
### "Client not found" error
|
|
- Verify the Client ID matches `kaboot-spa`
|
|
- Ensure the application is enabled (not archived)
|
|
|
|
### CORS errors
|
|
- Authentik handles CORS automatically for configured redirect URIs
|
|
- Ensure your frontend origin (`http://localhost:5173`) is in the redirect URIs
|
|
|
|
### Token validation fails on backend
|
|
- Verify `OIDC_ISSUER` and `OIDC_JWKS_URI` are correct
|
|
- The backend must be able to reach Authentik at `http://authentik-server:9000` (Docker network)
|
|
|
|
## Required OIDC Claims
|
|
|
|
The Kaboot backend validates the following JWT claims:
|
|
|
|
| Claim | Required | Description |
|
|
|-------|----------|-------------|
|
|
| `sub` | Yes | User identifier (subject) |
|
|
| `iss` | Yes | Must match `OIDC_ISSUER` env var |
|
|
| `aud` | Recommended | Must match `OIDC_AUDIENCE` env var if set |
|
|
| `preferred_username` | No | Display name, falls back to `sub` |
|
|
| `email` | No | User's email address |
|
|
| `groups` | No | Array of group names for access control |
|
|
|
|
### Audience Claim Configuration
|
|
|
|
The `aud` (audience) claim prevents tokens issued for other applications from being accepted. The blueprint configures this automatically via the `kaboot` scope.
|
|
|
|
**Backend Configuration:**
|
|
```bash
|
|
# Set to your OIDC client ID
|
|
OIDC_AUDIENCE=kaboot-spa
|
|
```
|
|
|
|
**Frontend Configuration:**
|
|
The frontend must request the `kaboot` scope to include the audience claim:
|
|
```typescript
|
|
// src/config/oidc.ts
|
|
scope: 'openid profile email offline_access groups kaboot'
|
|
```
|
|
|
|
**Manual Authentik Setup (if not using blueprints):**
|
|
|
|
1. Go to **Customisation** > **Property Mappings**
|
|
2. Click **Create** > **Scope Mapping**
|
|
3. Configure:
|
|
| Field | Value |
|
|
|-------|-------|
|
|
| Name | `Kaboot Audience Scope` |
|
|
| Scope name | `kaboot` |
|
|
| Expression | `return {"aud": "kaboot-spa"}` |
|
|
|
|
4. Go to **Applications** > **Providers** > **Kaboot OAuth2**
|
|
5. Edit and add the new scope mapping to **Scopes**
|
|
|
|
### Groups Claim for Access Control
|
|
|
|
The `groups` claim controls access to premium features:
|
|
|
|
| Group | Access Level |
|
|
|-------|--------------|
|
|
| `kaboot-users` | Basic access (required to use app) |
|
|
| `kaboot-ai-access` | Unlimited AI generations, OCR access |
|
|
| `kaboot-admin` | Admin features |
|
|
|
|
The groups scope mapping is configured in the blueprint. For manual setup:
|
|
|
|
1. Create a scope mapping with expression:
|
|
```python
|
|
return {"groups": [group.name for group in request.user.ak_groups.all()]}
|
|
```
|
|
2. Add it to the provider's scopes
|
|
|
|
## Production Notes
|
|
|
|
For production deployment, see [PRODUCTION.md](./PRODUCTION.md) for full instructions.
|