# Security Policy

This file is the public-facing companion to `docs/policies/D04-information-security-policy.md`
(the controlled InfoSec Policy that satisfies ISO 27001 §5.2). It tells
external researchers and customers how to report a vulnerability, what we
treat as in-scope, and how we will respond.

---

## Reporting a vulnerability

Please **do not** open a public GitHub issue for security problems.

Instead, email **`security@bluedxp.com`** with:

1. A description of the issue (what, where, how reproducible).
2. The minimum repro steps and any proof-of-concept artifact you can share.
3. Your contact details (so we can keep you informed and credit you, if you
   wish, after a fix lands).

We will acknowledge within **2 business days**, share an initial impact
assessment within **5 business days**, and target a fix or mitigation for
critical issues within **30 calendar days**. Lower-severity issues are
batched into the next minor release.

If the issue is actively being exploited or affects production data, mark
the email subject `[ACTIVE]` and we will treat it as a Sev-1 incident under
SOP-019 (change management) and SOP-022 (hazard / incident reporting in the
IMS manual).

---

## Scope

In scope:

- Production deployment at **`https://wajeeh.app`** (and the alternate brand
  alias `https://app.bluedxp.com`).
- Code in this repository: every file under `api/`, every top-level `*.html`
  shell, the Vercel routing in `vercel.json`, the IMS manual, and every
  controlled doc under `docs/policies/` and `docs/ims/`.
- The Hazalyze WhatsApp gateway integration as exposed by
  `api/webhooks/hazalyze.js` (the gateway itself is a separate repository
  and is governed by its own security policy).

Out of scope:

- Third-party services we depend on (Vercel, Anthropic, Neon Postgres,
  Vercel Blob, OpenSanctions, Terminal49, GDELT, Sentinel Hub,
  Tomorrow.io, OpenWeather, ZATCA provider). Report those upstream.
- Local-only artifacts in `.tmp-seed/`, `.gateway-inspect/` and
  `backups/` — these are working-tree-only and never deployed.
- Brute-force / volumetric DDoS — we layer Vercel's edge limits with a
  Postgres-backed rate limiter (`api/_lib/rate-limit.js`), but absolute
  capacity is a vendor concern.

---

## Current security baseline (as of v1.12.0 of the IMS manual)

Auditors and customers can verify each of these against the codebase:

| Control                                            | Evidence                                                                                                                                                                        |
| -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Legacy static-key fallback **disabled by default** | `api/_lib/guard.js` — gated by `BLUEDXP_LEGACY_KEY_ENABLED` (default `false`); every legacy-key acceptance writes a critical `security_event`                                   |
| Admin MFA enforcement                              | `api/auth.js` — `BLUEDXP_REQUIRE_MFA_FOR_ADMINS` with grace window `BLUEDXP_MFA_GRACE_DAYS`; soft → hard escalation                                                             |
| TOTP / MFA secrets **encrypted at rest**           | `api/_lib/totp.js` — HKDF-SHA256 + AES-256-GCM, keyed by `BLUEDXP_MFA_KEY`; transparent rollover for legacy plaintext rows                                                      |
| Two-person approval for new accounts               | `api/_lib/access-approval.js` — `BLUEDXP_ACCESS_REQUIRE_TWO_APPROVERS=true` by default; self-approval and same-admin-twice blocked                                              |
| Postgres-backed rate limiting                      | `api/_lib/rate-limit.js` — SHA-256 hashed keys (PII-safe), in-process LRU fast-deny, fail-open if Postgres unavailable                                                          |
| Strict HTTP security headers                       | `vercel.json` — CSP (`object-src 'none'`, `frame-ancestors 'none'`, `upgrade-insecure-requests`), HSTS, COOP, CORP, Permissions-Policy, X-Content-Type-Options, Referrer-Policy |
| Per-route CORS allowlist                           | `BLUEDXP_ALLOWED_ORIGINS` env, applied in `api/blob-rfi.js`                                                                                                                     |
| Webhook authenticity                               | HMAC-SHA256 with timing-safe compare (`api/_lib/driver-share-token.js`, Hazalyze webhook handler)                                                                               |
| Tamper-evident audit chain                         | `security_events` table — append-only, hash-chained; SOP-025 evidence vault adds blob anchoring                                                                                 |

The IMS manual's `RISKS` array (R01–R20) names every threat we model, the
ISO clause it maps to, and the explicit treatment.

---

## Coordinated disclosure

We follow a standard 90-day coordinated-disclosure window. After we ship a
fix:

1. We credit the reporter in the IMS manual `CHANGELOG` entry (unless they
   ask to remain anonymous).
2. We file a `security_events` row that names the CVE-equivalent, the
   patched version, and the deploy SHA.
3. For customer-impacting issues we send a notification through the in-app
   notification service (`api/_lib/notify.js` → `notification` channel) and
   offer a one-page incident report to enterprise tenants on request.

If you have not heard from us within the SLA above, please re-send to the
same email and CC `org-admin@bluedxp.com`.

---

## What this file is **not**

- It is not the controlled InfoSec Policy. That is
  `docs/policies/D04-information-security-policy.md`, which is owned by
  `PLATFORM_ADMIN + COMPLIANCE_OFFICER` and approved by Top Management.
- It is not the security baseline runbook. That is
  `SECURITY_HARDENING_ACTIONS.md`, which records every control change and
  the deploy that landed it.
- It is not a vulnerability disclosure database. We do not yet publish CVEs;
  we cite affected versions in the IMS manual `CHANGELOG`.
