Authentication
Brokoli supports JWT tokens, API keys, and session cookies for authentication.
Brokoli supports JWT tokens, API keys, and session cookies.
Open mode
On first launch with no users created, Brokoli runs in open mode -- all API endpoints are accessible without authentication. Create your first user to enable auth.
User authentication (JWT)
Login
curl -X POST http://localhost:8080/api/auth/login \
-H "Content-Type: application/json" \
-d '{"username": "admin", "password": "your-password"}'Response:
{
"token": "eyJhbGciOiJIUzI1NiIs...",
"user": {
"id": "abc-123",
"username": "admin",
"role": "admin"
}
}Using the token
Pass the JWT in the Authorization header:
curl http://localhost:8080/api/pipelines \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."Session cookies
The login endpoint also sets an httpOnly cookie named brokoli_session. Browsers use this automatically -- no need to manually manage tokens for UI requests.
Cookie properties:
| Property | Value |
|---|---|
| Name | brokoli_session |
| HttpOnly | true |
| SameSite | Lax |
| Secure | true (when HTTPS) |
| MaxAge | 24 hours |
Check current user
curl http://localhost:8080/api/auth/me \
-H "Authorization: Bearer {token}"User roles
| Role | Permissions |
|---|---|
superadmin | Full access, manage organizations |
admin | Full access within workspace |
editor | Create, edit, run pipelines |
viewer | Read-only access |
Create users
Requires admin role:
curl -X POST http://localhost:8080/api/auth/users \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{"username": "analyst", "password": "secure-password", "role": "editor"}'First-time setup check
curl http://localhost:8080/api/auth/setup{"needs_setup": true}Returns true when no users exist. The UI uses this to show the setup wizard.
API key authentication
For programmatic access, use API keys instead of JWT tokens.
Generate a key
broked generate-keyOutput: brk_a1b2c3d4e5f6...
Start with API key auth
broked serve --api-key brk_a1b2c3d4e5f6...Using API keys
Authorization header
curl http://localhost:8080/api/pipelines \
-H "Authorization: Bearer brk_a1b2c3d4e5f6..."X-API-Key header
curl http://localhost:8080/api/pipelines \
-H "X-API-Key: brk_a1b2c3d4e5f6..."Password management
Change your password
curl -X POST http://localhost:8080/api/auth/change-password \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{"current_password": "old-pass", "new_password": "new-pass"}'Admin reset (for locked accounts)
curl -X POST http://localhost:8080/api/auth/admin-reset-password \
-H "Authorization: Bearer {admin-token}" \
-H "Content-Type: application/json" \
-d '{"user_id": "user-abc", "new_password": "new-pass"}'Account lockout
After 5 failed login attempts within 15 minutes, the account is temporarily locked. Wait 15 minutes or have an admin reset the password.
JWT secret
The JWT signing key is stored in .brokoli-jwt-secret (auto-generated on first run). In production, set this as an environment variable for consistency across restarts:
export BROKOLI_JWT_SECRET=your-32-byte-secret-key