Identity¶
User management and authentication service. Handles user CRUD, OAuth account linking, token lifecycle, transactional emails, and the notification system.
| Property | Value |
|---|---|
| Port | 8007 |
| Language | Python 3.13 |
| Framework | FastAPI |
| Source | services/identity/ |
| Route prefix | /api/v1/identity |
Architecture¶
The Identity service follows the standard repository pattern:
- Routes — FastAPI endpoints for user management, internal auth operations, and notifications
- Service — Business logic for password hashing, token rotation, email dispatch, and notification creation
- Repository — SQLAlchemy 2.0 async queries against the
users,refresh_tokens,oauth_accounts, andnotificationstables - Consumer — Background
asyncio.Taskthat subscribes to domain events and creates per-user notifications
Endpoints¶
Internal Endpoints (called by Gateway only)¶
These endpoints are not exposed through the gateway proxy. The gateway calls them directly during authentication flows.
| Method | Path | Description |
|---|---|---|
POST |
/internal/auth/login |
Validate email/password |
POST |
/internal/auth/register |
Create new user account |
POST |
/internal/auth/refresh |
Rotate refresh token |
POST |
/internal/auth/revoke |
Revoke a refresh token |
POST |
/internal/auth/oauth/link |
Link OAuth account to user |
POST |
/internal/auth/oauth/find |
Find user by OAuth provider + ID |
POST |
/internal/auth/forgot-password |
Initiate password reset |
POST |
/internal/auth/reset-password |
Complete password reset with token |
POST |
/internal/auth/verify-email |
Verify email with token |
Public Endpoints (proxied through Gateway)¶
| Method | Path | Auth | Description |
|---|---|---|---|
GET |
/api/v1/identity/users/me |
Bearer | Get current user profile |
PUT |
/api/v1/identity/users/me |
Bearer | Update current user profile |
GET |
/api/v1/identity/users/me/settings |
Bearer | Get user preferences |
PUT |
/api/v1/identity/users/me/settings |
Bearer | Update user preferences |
PUT |
/api/v1/identity/users/me/password |
Bearer | Change password |
GET |
/api/v1/identity/users |
Admin | List all users |
POST |
/api/v1/identity/users/invite |
Admin | Invite new user via email |
PUT |
/api/v1/identity/users/:id/role |
Admin | Change user role |
PUT |
/api/v1/identity/users/:id/status |
Admin | Activate/deactivate user |
GET |
/api/v1/identity/notifications |
Bearer | List notifications (paginated) |
PATCH |
/api/v1/identity/notifications/{id}/read |
Bearer | Mark notification as read |
POST |
/api/v1/identity/notifications/read-all |
Bearer | Mark all as read |
GET |
/api/v1/identity/notifications/unread-count |
Bearer | Get unread count |
GET |
/api/v1/identity/notifications/preferences |
Bearer | Get notification preferences |
PUT |
/api/v1/identity/notifications/preferences |
Bearer | Update notification preferences |
See Notifications for full API reference and event mapping.
Auth Flows¶
Email/Password Login¶
sequenceDiagram
participant Client
participant Gateway
participant Identity
Client->>Gateway: POST /api/v1/auth/login {email, password}
Gateway->>Identity: POST /internal/auth/login {email, password}
Identity->>Identity: Verify bcrypt hash
Identity->>Gateway: {user, refresh_token}
Gateway->>Gateway: Sign JWT (15-min, HS256)
Gateway->>Client: {access_token, refresh_token, user}
OAuth Login (GitHub/Google)¶
sequenceDiagram
participant Client
participant Gateway
participant Provider as GitHub/Google
participant Identity
Client->>Gateway: GET /api/v1/auth/oauth/github
Gateway->>Client: 302 → GitHub authorize URL (with state)
Client->>Provider: User authorizes
Provider->>Gateway: GET /callback?code=xxx&state=yyy
Gateway->>Provider: Exchange code for access token
Gateway->>Provider: Fetch user profile
Gateway->>Identity: POST /internal/auth/oauth/find
alt User exists
Identity->>Gateway: {user}
else New user
Gateway->>Identity: POST /internal/auth/register
Gateway->>Identity: POST /internal/auth/oauth/link
Identity->>Gateway: {user}
end
Gateway->>Gateway: Sign JWT (15-min)
Gateway->>Client: Set cookies + redirect to dashboard
Token Refresh¶
sequenceDiagram
participant Client
participant Gateway
participant Identity
Client->>Gateway: POST /api/v1/auth/refresh {refresh_token}
Gateway->>Identity: POST /internal/auth/refresh {refresh_token}
Identity->>Identity: Validate token, check family
Identity->>Identity: Rotate: revoke old, issue new
Identity->>Gateway: {user, new_refresh_token}
Gateway->>Gateway: Sign new JWT (15-min)
Gateway->>Client: {access_token, refresh_token}
Password Reset¶
sequenceDiagram
participant Client
participant Gateway
participant Identity
Client->>Gateway: POST /api/v1/auth/forgot-password {email}
Gateway->>Identity: POST /internal/auth/forgot-password
Identity->>Identity: Generate reset token, send email
Identity->>Gateway: 200 OK
Client->>Gateway: POST /api/v1/auth/reset-password {token, new_password}
Gateway->>Identity: POST /internal/auth/reset-password
Identity->>Identity: Validate token, hash new password
Identity->>Gateway: 200 OK
Configuration¶
| Variable | Default | Description |
|---|---|---|
DATABASE_URL |
(from CommonSettings) | PostgreSQL connection |
REDIS_URL |
redis://localhost:6379 |
Redis for session/token caching |
SMTP_HOST |
localhost |
SMTP server for transactional emails |
SMTP_PORT |
587 |
SMTP port |
SMTP_USER |
-- | SMTP username |
SMTP_PASS |
-- | SMTP password |
SMTP_FROM |
noreply@orion.local |
From address for emails |
Email in Development
In development mode, transactional emails (verification, reset, invite) are stubbed and logged to the console instead of being sent via SMTP.
Database Tables¶
| Table | Description |
|---|---|
users |
User accounts (id, email, name, password_hash, role, status) |
refresh_tokens |
Opaque refresh tokens with family tracking for theft detection |
oauth_accounts |
OAuth provider links (provider, provider_user_id, user_id) |
notifications |
Per-user notifications (type, title, body, metadata, read status) |
Security¶
- Password hashing — bcrypt with cost factor 12
- Refresh tokens — Opaque, 30-day expiry, DB-backed with family tracking
- Token theft detection — If a revoked token from a family is reused, the entire family is invalidated
- Email verification — Required before full account access (configurable)
Related Documentation
- Authentication API — Full auth endpoint reference
- Security Architecture — Security design and threat model
- Gateway — OAuth endpoints and user header forwarding
- Notifications — Notification API reference and event mapping