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:
nilesh.p
2026-10-10 13:31:04 +05:30
co-authored by Claude Opus 4.8
parent 45b5b34680
commit 035711f08c
12 changed files with 788 additions and 0 deletions
+79
View File
@@ -0,0 +1,79 @@
# Security rules
Required security controls for TravelHub. These are not suggestions — a change
that breaks one is rejected. They exist because this is a **multi-tenant** system
holding traveller PII (names, passport numbers, contact details) where a single
leaked `WHERE` clause exposes every tenant.
Findings from the whitebox assessment and their status are in
[`security/VAPT-REPORT.md`](security/VAPT-REPORT.md).
## 1. Tenant isolation
- The tenant id is derived from the **authenticated identity**, never from the
URL, query string, header value, or request body. A client cannot choose or
forge the tenant it acts as.
- Every query against a tenant-owned table (`users`, `flights`, `bookings`,
`passengers`) filters on `tenant_id` as its first parameter. No exceptions.
- A miss within the tenant returns **404**, never 403 — existence of another
tenant's record must not be observable.
- **No PostgreSQL row-level security.** Isolation is enforced in the repository
layer by the rules above (see [CLAUDE.md](CLAUDE.md) for the rationale). At
scale, prefer schema- or database-per-tenant, not RLS.
## 2. Secrets
- **Never commit a secret.** `.env` and `*.env` are git-ignored; only
`.env.example` (placeholders) is tracked. Credentials, tokens and DB passwords
live in `.env` and are read at runtime.
- The `pre-commit` hook scans staged content for credential patterns and blocks
them. Do not bypass it (`--no-verify`) to commit a secret.
- **Never print or log a credential.** The e2e API-capture redacts the
`Authorization` header (it is the Basic-auth secret); keep it redacted in any
report or log.
- **If a secret is ever committed or exposed, rotate it immediately** — assume
it is compromised. Scrubbing history is not enough on its own.
## 3. Authentication & credential storage
- Passwords are hashed with **bcrypt in application code** at cost ≥ 12.
- The real hash and the not-found timing-dummy hash must use the **same cost** —
a mismatch creates a username-enumeration timing oracle (VAPT FINDING-2).
- 401 responses omit `WWW-Authenticate` (so the browser dialog doesn't fight the
SPA sign-in); a missing user still pays for a bcrypt comparison (timing).
- Authentication endpoints must be **rate-limited** before any public exposure.
## 4. Input handling
- **All SQL is parameterised** (`$1…$n`). Never concatenate a value into SQL.
Anything that must reach the SQL text (e.g. a sort column) is whitelisted.
- JSON request bodies use `DisallowUnknownFields` (blocks mass-assignment) and
are size-capped (`http.MaxBytesReader`).
- Validate and normalise free-text on input; treat the API as the trust
boundary, not the client.
## 5. Transport & least privilege
- Any non-local database connection uses **TLS** (`sslmode=verify-full`);
`disable` is only for loopback dev.
- The running service connects to PostgreSQL as a **least-privilege role**
(DML only), never a superuser. Migrations run under a separate, higher
privileged role the service never uses.
## 6. Dependencies & headers
- Run dependency scanning in CI: `govulncheck` (Go) and `npm audit` (frontend).
- Responses carry baseline security headers (`nosniff`, `X-Frame-Options`,
`Referrer-Policy`, `Cache-Control: no-store` on authenticated JSON, HSTS behind
TLS); the SPA ships a restrictive CSP.
## 7. Data handling
- Treat passenger PII as sensitive. Do not log it; do not put real PII in seed
or test data (use synthetic values).
- Reports (evidence, test) may contain synthetic test data only.
## Reporting a vulnerability
Raise security issues privately with the repository owner (do not open a public
issue). Include steps to reproduce and the affected files.