Files
stack/docs/4-api/2-authentication/1-endpoints.md
Jason Woltje 12abdfe81d feat(#93): implement agent spawn via federation
Implements FED-010: Agent Spawn via Federation feature that enables
spawning and managing Claude agents on remote federated Mosaic Stack
instances via COMMAND message type.

Features:
- Federation agent command types (spawn, status, kill)
- FederationAgentService for handling agent operations
- Integration with orchestrator's agent spawner/lifecycle services
- API endpoints for spawning, querying status, and killing agents
- Full command routing through federation COMMAND infrastructure
- Comprehensive test coverage (12/12 tests passing)

Architecture:
- Hub → Spoke: Spawn agents on remote instances
- Command flow: FederationController → FederationAgentService →
  CommandService → Remote Orchestrator
- Response handling: Remote orchestrator returns agent status/results
- Security: Connection validation, signature verification

Files created:
- apps/api/src/federation/types/federation-agent.types.ts
- apps/api/src/federation/federation-agent.service.ts
- apps/api/src/federation/federation-agent.service.spec.ts

Files modified:
- apps/api/src/federation/command.service.ts (agent command routing)
- apps/api/src/federation/federation.controller.ts (agent endpoints)
- apps/api/src/federation/federation.module.ts (service registration)
- apps/orchestrator/src/api/agents/agents.controller.ts (status endpoint)
- apps/orchestrator/src/api/agents/agents.module.ts (lifecycle integration)

Testing:
- 12/12 tests passing for FederationAgentService
- All command service tests passing
- TypeScript compilation successful
- Linting passed

Refs #93

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-03 14:37:06 -06:00

415 lines
6.8 KiB
Markdown

# Authentication Endpoints
Complete reference for authentication API endpoints powered by BetterAuth.
## Base URL
```
http://localhost:3001/auth
```
All authentication endpoints are prefixed with `/auth`.
## Endpoints
### Sign Up
Create a new user account with email and password.
```http
POST /auth/sign-up
```
**Request Body:**
```json
{
"email": "user@example.com",
"password": "SecurePass123!",
"name": "John Doe"
}
```
**Response (201):**
```json
{
"user": {
"id": "user-uuid",
"email": "user@example.com",
"name": "John Doe",
"emailVerified": false
},
"session": {
"id": "session-uuid",
"token": "eyJhbGciOiJIUzI1NiIs...",
"expiresAt": "2026-01-29T12:00:00.000Z"
}
}
```
**Errors:**
- `409 Conflict` — Email already exists
- `422 Validation Error` — Invalid input
---
### Sign In
Authenticate with email and password.
```http
POST /auth/sign-in
```
**Request Body:**
```json
{
"email": "user@example.com",
"password": "SecurePass123!"
}
```
**Response (200):**
```json
{
"user": {
"id": "user-uuid",
"email": "user@example.com",
"name": "John Doe"
},
"session": {
"id": "session-uuid",
"token": "eyJhbGciOiJIUzI1NiIs...",
"expiresAt": "2026-01-29T12:00:00.000Z"
}
}
```
**Errors:**
- `401 Unauthorized` — Invalid credentials
---
### Sign Out
Invalidate current session.
```http
POST /auth/sign-out
```
**Headers:**
```http
Authorization: Bearer {session_token}
```
**Response (200):**
```json
{
"success": true
}
```
---
### Get Session
Retrieve current session information.
```http
GET /auth/session
```
**Headers:**
```http
Authorization: Bearer {session_token}
```
**Response (200):**
```json
{
"user": {
"id": "user-uuid",
"email": "user@example.com",
"name": "John Doe"
},
"session": {
"id": "session-uuid",
"expiresAt": "2026-01-29T12:00:00.000Z"
}
}
```
**Errors:**
- `401 Unauthorized` — Invalid or expired session
---
### Get Profile
Get authenticated user's profile (custom endpoint).
```http
GET /auth/profile
```
**Headers:**
```http
Authorization: Bearer {session_token}
```
**Response (200):**
```json
{
"id": "user-uuid",
"email": "user@example.com",
"name": "John Doe",
"emailVerified": false
}
```
**Errors:**
- `401 Unauthorized` — Not authenticated
---
### OIDC Callback
OAuth callback handler for Authentik (and other OIDC providers).
```http
GET /auth/callback/authentik
```
**Query Parameters:**
- `code` — Authorization code from provider
- `state` — CSRF protection token
This endpoint is called by the OIDC provider after successful authentication.
**Response:**
- Redirects to frontend with session token
---
## Authentication Flow
### Email/Password Flow
```
1. User submits credentials → POST /auth/sign-in
2. Server validates credentials
3. Server creates session
4. Server returns session token
5. Client stores token
6. Client includes token in subsequent requests
```
### OIDC Flow
```
1. User clicks "Sign in with Authentik"
2. Frontend redirects to Authentik
3. User authenticates with Authentik
4. Authentik redirects to /auth/callback/authentik
5. Server exchanges code for tokens
6. Server creates/updates user
7. Server creates session
8. Server redirects to frontend with session token
```
## Using Session Tokens
Include the session token in the `Authorization` header for all authenticated requests:
```http
GET /api/tasks
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
```
### Token Storage
**Frontend (Browser):**
- Store in `httpOnly` cookie (most secure)
- Or `localStorage` (less secure, XSS vulnerable)
**Mobile/Desktop:**
- Secure storage (Keychain on iOS, KeyStore on Android)
### Token Expiration
Tokens expire after 24 hours (configurable via `JWT_EXPIRATION`).
**Check expiration:**
```typescript
import { AuthSession } from "@mosaic/shared";
const isExpired = (session: AuthSession) => {
return new Date(session.session.expiresAt) < new Date();
};
```
**Refresh flow** (future implementation):
```http
POST /auth/refresh
```
## Error Responses
### 401 Unauthorized
```json
{
"error": {
"code": "UNAUTHORIZED",
"message": "Invalid or expired session token"
}
}
```
### 422 Validation Error
```json
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Input validation failed",
"details": {
"email": "Invalid email format",
"password": "Must be at least 8 characters"
}
}
}
```
## Examples
### Sign Up
```bash
curl -X POST http://localhost:3001/auth/sign-up \
-H "Content-Type: application/json" \
-d '{
"email": "jane@example.com",
"password": "SecurePass123!",
"name": "Jane Doe"
}'
```
### Sign In
```bash
curl -X POST http://localhost:3001/auth/sign-in \
-H "Content-Type: application/json" \
-d '{
"email": "jane@example.com",
"password": "SecurePass123!"
}'
```
**Save the token from response:**
```bash
TOKEN=$(curl -X POST http://localhost:3001/auth/sign-in \
-H "Content-Type: application/json" \
-d '{"email":"jane@example.com","password":"SecurePass123!"}' \
| jq -r '.session.token')
```
### Get Profile
```bash
curl http://localhost:3001/auth/profile \
-H "Authorization: Bearer $TOKEN"
```
### Sign Out
```bash
curl -X POST http://localhost:3001/auth/sign-out \
-H "Authorization: Bearer $TOKEN"
```
## Security Considerations
### Password Requirements
- Minimum 8 characters
- At least one uppercase letter
- At least one lowercase letter
- At least one number
Configure in `apps/api/src/auth/auth.config.ts`.
### Rate Limiting
- Sign-up: 5 requests per hour per IP
- Sign-in: 10 requests per hour per IP (prevents brute force)
### CSRF Protection
OIDC flow includes `state` parameter for CSRF protection.
### Token Security
- Tokens are signed with `JWT_SECRET`
- Use strong secret (min 32 characters)
- Rotate secret regularly in production
- Never expose tokens in logs
## TypeScript Types
All authentication types are available from `@mosaic/shared`:
```typescript
import type {
AuthUser,
AuthSession,
LoginRequest,
LoginResponse,
} from '@mosaic/shared';
// Use in frontend
const login = async (req: LoginRequest): Promise<AuthSession> => {
const res = await fetch('/auth/sign-in', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(req),
});
return res.json();
};
// Use in backend
@Post('sign-in')
async signIn(@Body() request: LoginRequest): Promise<LoginResponse> {
// ...
}
```
See [API Types](2-types.md) for complete type definitions.
## Next Steps
- **Configure OIDC** — [Configuration → Authentik](../../1-getting-started/3-configuration/2-authentik.md)
- **Review Types** — [Authentication Types](2-types.md)
- **Understand Architecture** — [Architecture → Authentication](../../3-architecture/2-authentication/1-betterauth.md)