- CLAUDE.md + AGENTS.md: canonical guiding principles for AI agents and developers (tenant isolation, no RLS, stack, security, conventions, environment gotchas) - SECURITY.md: required security controls (isolation, secrets, auth, input handling, least privilege) with VAPT status - GOVERNANCE.md: how changes are validated before merge — deterministic gates + AI review, risk tiers, human accountability - CONTRIBUTING.md: code hygiene, definition of done, file hygiene - docs/wiki/: product reference (overview, domain model, features, roles & access, API reference, glossary) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2.2 KiB
Roles & access
Authentication
HTTP Basic auth, scoped per tenant. Every API call (except the two public endpoints) carries:
- an
Authorization: Basic base64(email:password)header, and - an
X-Tenantheader naming the agency (or the agency is taken from the subdomain).
The password is verified against the user row inside the named tenant, so credentials from one agency never authenticate at another. Passwords are stored as bcrypt hashes.
Basic auth replays a reusable credential on every request and the SPA holds it client-side. That is acceptable for this reference build behind TLS; a public deployment should move to short-lived tokens. See SECURITY.md.
Roles
| Role | Intended capability |
|---|---|
| agent | Search, book, manage and cancel bookings; view the dashboard. |
| admin | Everything an agent can do, plus agency administration. |
Both roles exist on the user record and the API exposes an admin/agent
distinction. Note: admin-only functionality is not yet built, so today the
two roles are functionally identical — the RequireAdmin gate exists but is
wired to no route. When admin features are added they must be gated explicitly
(see GOVERNANCE.md).
Tenant status
A tenant is active or suspended. A suspended tenant's users cannot sign in,
and the tenant is hidden from the public agency picker.
Demo accounts
Seeded by 002_seed.sql. Password for all: demo1234.
| Agency | Role | |
|---|---|---|
| Skyline Travel | admin@skyline.test |
admin |
| Skyline Travel | agent@skyline.test |
agent |
| Globetrotter Tours | admin@globetrotter.test |
admin |
| Globetrotter Tours | agent@globetrotter.test |
agent |
Sign in to each agency and search JFK → LHR: the same route is priced
differently per tenant — the isolation made visible.
Public (unauthenticated) endpoints
Only two, by necessity:
GET /api/health— liveness.GET /api/tenants— the agency list for the sign-in picker (returns slug and name only; active tenants only).
Everything else requires a valid, tenant-scoped credential.