core-user-service
Manages internal user records. Each user in this service maps to a Better Auth user via betterAuthUserId and belongs to exactly one organization. Provides user CRUD, profile management, permissions, search, and the builder pattern for onboarding.
Worker name: crow-core-user-service
Domain (prod): internal.users.crowai.dev
Domain (dev): dev.internal.users.crowai.dev
Schema
user
| Column | Type | Notes |
|---|---|---|
| id | text PK | Internal UUID |
| betterAuthUserId | text | unique, FK to auth service user |
| organizationId | text | Internal org UUID |
| text | ||
| name | text | |
| profilePictureUrl | text | nullable, R2 URL |
| onboardingId | text | nullable |
| permissions | text | JSON (chat, interactions, patterns, teamManagement, apiKeyManagement) |
| status | text | default pending, also active |
| role | text | default member, also owner, admin |
| createdAt | integer | epoch ms |
| updatedAt | integer | epoch ms |
Routes
| Method | Path | Description | Auth |
|---|---|---|---|
| POST | /api/v1/users | Create user | Service key |
| POST | /api/v1/users/create | Create user directly (onboarding) | Service key |
| GET | /api/v1/users/{id} | Get user by internal ID | JWT |
| GET | /api/v1/users/by-auth-id/{betterAuthUserId} | Lookup by Better Auth ID | Service key (fail-closed) |
| GET | /api/v1/users/me | Get current user from JWT | JWT |
| GET | /api/v1/users/{id}/permissions | Get user permissions | JWT |
| GET | /api/v1/users/by-organization/{organizationId} | List users in org | JWT |
| GET | /api/v1/users/search-email?q= | Search users by email prefix | JWT + org context |
| POST | /api/v1/users/check-emails | Check which emails exist as users | Service key |
| PATCH | /api/v1/users/{id}/profile | Update name/profile picture URL | JWT |
| POST | /api/v1/users/{id}/profile-picture | Upload profile picture to R2 | JWT |
| POST | /api/v1/users/onboard | Update profile after signup | JWT |
| POST | /api/v1/user-builders | Create user builder (onboarding) | Service key |
| GET | /api/v1/user-builders/{id} | Get user builder | Service key |
| POST | /api/v1/user-builders/{id}/finalize | Finalize builder into user | Service key |
| GET | /api/v1/billing-builders | Proxy to billing service builders | Service key |
Environment Variables
| Variable | Example |
|---|---|
| ENVIRONMENT | dev |
| AUTH_SERVICE_URL | https://dev.internal.auth-api.crowai.dev |
Secrets
| Secret | Purpose |
|---|---|
| BETTER_AUTH_SECRET | JWT verification |
| INTERNAL_GATEWAY_KEY | Gateway trust validation |
Bindings
| Binding | Type | Name |
|---|---|---|
| DB | D1 | crow-core-user-service-db |
| R2_BUCKET | R2 | crow-core-user-service-store (profile pictures) |
Dependencies
- Inbound: auth service (user sync, by-auth-id lookup), gateway (org resolution), org service (member listing)
- Outbound: auth service (JWT verification)
Key Behaviors
- INTERNAL_GATEWAY_KEY guard: All
/api/v1/*routes require theX-Internal-Keyheader matching the shared secret - Service key guards: Write endpoints (
/users,/users/create,/user-builders,/billing-builders,/check-emails) requireX-Service-API-Key - by-auth-id fail-closed: Returns 401 if no auth header is present (not fail-open)
- Permissions JSON structure:
{ chat: { enabled, components, lookbackWindow }, interactions, patterns, teamManagement, apiKeyManagement }