Add project guidance, security/governance/hygiene rules, and product wiki
- 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>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
45b5b34680
commit
035711f08c
@@ -0,0 +1,61 @@
|
||||
# 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-Tenant` header 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](../../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](../../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 | Email | 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.
|
||||
Reference in New Issue
Block a user