API Authentication¶
This page covers the practical details of authenticating with the Tech Strategy Tool API, including login flow, session management, and CSRF requirements.
Overview¶
The API uses cookie-based session authentication. After logging in, a session cookie is set on the browser and automatically included in subsequent requests.
Login Flow¶
1. Authenticate¶
curl -X POST https://localhost:5001/api/auth/login \
-H "Content-Type: application/json" \
-d '{"username": "editor", "password": "editor"}' \
-c cookies.txt
On success, the server sets the techstrat_session cookie:
2. Make authenticated requests¶
Include the cookie on subsequent requests:
3. Make mutating requests¶
All POST, PUT, PATCH, and DELETE requests require the CSRF header:
curl -X POST https://localhost:5001/api/events \
-H "Content-Type: application/json" \
-H "X-CSRF-Token: 1" \
-b cookies.txt \
-d '{"eventType": "create_team", "data": {"id": "...", "name": "New Team", "color": "#3498db"}}'
4. Logout¶
CSRF Protection¶
All mutating API requests must include the header:
The value is always the string 1. This prevents cross-site request forgery by ensuring the request was made from JavaScript code (browsers cannot set custom headers on cross-origin form submissions without CORS preflight).
Exempt from CSRF: POST /api/auth/login (no session exists yet).
If the header is missing on a mutating request, the API returns:
Roles and Permissions¶
Three authorization policies control access:
| Policy | Roles | Applied To |
|---|---|---|
| ViewerOrAbove | viewer, editor, admin | Read endpoints (GET teams, principles, objectives, history, SSE, export) |
| EditorOrAbove | editor, admin | Event submission (POST events) |
| AdminOnly | admin | User management, global event log |
Additionally, certain events submitted through POST /api/events require admin role even though the endpoint only requires EditorOrAbove:
create_team,update_team_name,update_team_color,delete_teamrestore_history
Non-admin users attempting these events receive a 403 response.
Session Details¶
| Property | Value |
|---|---|
| Cookie name | techstrat_session |
| Lifetime | 7 days from creation |
| Storage | PostgreSQL sessions table |
| Cache | In-memory, 5-minute TTL |
Sessions are cleaned up automatically by a background service that runs hourly.
Check Current Session¶
To verify your authentication status and retrieve your user info:
Response (200):
{
"success": true,
"userId": "a1b2c3d4-...",
"username": "editor",
"role": "editor",
"error": null
}
Response (401): Session is invalid or expired.
Rate Limiting¶
Login attempts are rate-limited per username:
- Threshold: 5 failed attempts within 15 minutes
- Lockout: Account is temporarily locked after threshold is reached
- Reset: Successful login clears the failure counter
- Scope: In-memory only (resets on application restart)
Blazor Client Integration¶
Both Blazor WASM applications handle authentication automatically:
- The browser sends the
techstrat_sessioncookie with every request (same-origin) - The API clients (
StrategyApiClientandAdminApiClient) includeX-CSRF-Token: 1on all mutating requests - Session state is tracked in the application state services (
StrategyStateandAdminState) - Unauthenticated users are redirected to the login page