# Security — Vigilant Entities / Amwāl OS

> Audit-ready security overview. Maps platform controls to OWASP ASVS,
> ISO 27001 Annex A, SOC 2 Trust Service Criteria, and NIST 800-53.
>
> Companion documents:
> - `THREAT_MODEL.md` — STRIDE threat model + attacker personas
> - `RBAC_MATRIX.md` — role/capability matrix
> - `INCIDENT_RESPONSE.md` — IR playbook
> - `BACKUP_RUNBOOK.md` — backup/restore procedure
> - `VENDOR_RISK.md` — third-party risk register
> - `/app/sbom.json` — Software Bill of Materials (CycloneDX)
> - `/api/security/audit/verify` — runtime audit-chain integrity check

---

## 1. Reporting a vulnerability

We follow a coordinated disclosure model.

| Channel              | Use case                                          |
|----------------------|---------------------------------------------------|
| `security@vigilantentities.com` | Encrypted reports (PGP key linked in `security.txt`) |
| `https://vigilantentities.com/security` | Report form for non-cryptographic reports |
| `.well-known/security.txt` | RFC 9116 disclosure index            |

Acknowledgement SLA: 24h. Triage SLA: 5 business days. Fix SLA varies
by severity (P0 ≤ 24h, P1 ≤ 7d, P2 ≤ 30d, P3 best effort).

---

## 2. OWASP Top 10 (2021) coverage matrix

| OWASP risk                          | Mitigation in this codebase                                              |
|-------------------------------------|--------------------------------------------------------------------------|
| A01 Broken Access Control           | RBAC via `auth_utils.get_current_user` + `require_roles`. Audit-cloaked Maker. |
| A02 Cryptographic Failures          | bcrypt for passwords. HS256 JWT (≥128-bit-entropy secret check at boot). HSTS preload + force-HTTPS. |
| A03 Injection                       | Motor (Mongo) param binding; Dawud heuristic scanner middleware blocks score≥80 requests. |
| A04 Insecure Design                 | Threat model in `THREAT_MODEL.md`; STRIDE walk for every new feature.    |
| A05 Security Misconfiguration       | Strict CSP, HSTS, X-Frame-Options=DENY, COOP/CORP, Permissions-Policy. OpenAPI docs gated by `VE_EXPOSE_DOCS`. |
| A06 Vulnerable & Outdated Components| `pip-audit` + `yarn audit` baseline in `/app/security/dependency-audit.md`. CycloneDX SBOM at `/app/sbom.json`. |
| A07 Identification & Auth Failures  | Brute-force lockout (`brute_force_service.py`), per-device JWT (`did` claim) + revocation, geo-anomaly alert, MFA-like email step-up via magic-link. |
| A08 Software & Data Integrity       | Hash-chained audit log (`audit_chain.py`). Integrity verifiable via `/api/security/audit/verify`. |
| A09 Logging & Monitoring Failures   | Structured logs (`vigilant.*` loggers), per-incident `incident_id`, audit trail for every privileged action, suspicious-signin email alert. |
| A10 SSRF                            | Outbound HTTP allowlist; egress only to Stripe / Resend / AWS Bedrock / configured tenant webhooks. |

---

## 3. Compliance mapping (high-level)

### ISO 27001 Annex A

| Annex A clause                                | Implementation                            |
|-----------------------------------------------|-------------------------------------------|
| A.5 Information security policies             | This document + Vendor Risk Register     |
| A.6 Organization of information security      | RBAC matrix, role separation             |
| A.8 Asset management                          | SBOM, asset inventory in admin cockpit   |
| A.9.4 System & application access control     | JWT + RBAC + brute-force + device revoke |
| A.10 Cryptography                             | bcrypt, HS256, JWT-secret strength check |
| A.12.3 Backup                                 | `BACKUP_RUNBOOK.md` (daily Mongo dump @ 02:00 UTC) |
| A.12.4 Logging & monitoring                   | Audit-chain hash-linked logs             |
| A.12.6 Vulnerability management               | Dependency audit, scheduled scans        |
| A.13.1 Network security                       | TLS enforced; HSTS preload; no plaintext |
| A.13.2 Information transfer                   | TLS + encrypted email magic-links        |
| A.14.2 Security in development                | Threat model + code review + lint gates  |
| A.15 Supplier relationships                   | `VENDOR_RISK.md` register                |
| A.16 Information security incidents           | `INCIDENT_RESPONSE.md` playbook          |
| A.17 Business continuity                      | Multi-region scheduler; restore RTO 4h   |
| A.18 Compliance                               | GDPR endpoints (`/api/auth/me/export`, `/delete`) + audit-chain |

### SOC 2 Trust Service Criteria

| TSC      | Control                                                | Evidence                            |
|----------|--------------------------------------------------------|-------------------------------------|
| CC1.1    | Demonstrates commitment to integrity                  | Code of conduct in `THREAT_MODEL.md`|
| CC6.1    | Logical access controls                                | `auth_utils.py`, `routes_auth.py`  |
| CC6.6    | Logical access for transmissions                       | TLS, HSTS, CSP, CORS allowlist     |
| CC6.7    | Restricts logical access (account lifecycle)           | Brute-force, device revoke, GDPR delete |
| CC7.1    | Detection of system anomalies                          | Suspicious sign-in alert, Dawud scanner |
| CC7.2    | Monitors for security incidents                        | Audit-chain, structured logs       |
| CC7.3    | Communicates security incidents                        | `INCIDENT_RESPONSE.md`             |
| CC8.1    | Authorizes / designs / develops / approves changes     | Git history + PR review checklist  |
| CC9.1    | Identifies, selects, develops risk mitigation activities | `VENDOR_RISK.md`                 |

### GDPR (subset)

| Article | Right                              | Endpoint / control                          |
|---------|------------------------------------|---------------------------------------------|
| Art. 15 | Right of access                    | `GET /api/auth/me/export`                  |
| Art. 16 | Right to rectification             | `PUT /api/auth/me`                         |
| Art. 17 | Right to erasure                   | `POST /api/auth/me/delete` (anonymise; audit history preserved per Art. 17(3)(b)) |
| Art. 20 | Data portability                   | `/api/auth/me/export` returns JSON        |
| Art. 25 | Privacy by design                  | PII redaction in logs, geo lookup is offline |
| Art. 32 | Security of processing             | This document                              |
| Art. 33 | Breach notification (72h)          | `INCIDENT_RESPONSE.md`                     |

### NIST 800-53 (rev 5) — Moderate baseline

| Family | Examples                                            |
|--------|-----------------------------------------------------|
| AC     | AC-2, AC-3, AC-6, AC-7 — accounts, RBAC, lockout    |
| AU     | AU-2, AU-9, AU-12 — audit, integrity, generation    |
| IA     | IA-2, IA-5, IA-8 — MFA-like, password policy        |
| SC     | SC-5, SC-7, SC-8, SC-12, SC-13 — DoS, headers, crypto |
| SI     | SI-2, SI-4, SI-7 — flaw remediation, monitoring, integrity |

---

## 4. Runtime hardening (what the code actually does)

- `security_headers.py` — HSTS preload, strict CSP, X-Frame-Options DENY,
  X-Content-Type-Options nosniff, Referrer-Policy, Permissions-Policy,
  Cross-Origin-Opener-Policy, Cross-Origin-Resource-Policy.
- `rate_limit.py` — token-bucket per IP, tighter on `/auth/*`.
- `password_policy.py` — NIST 800-63B (length 12-128, classes, blocklist).
- `error_handler.py` — incident_id, no stack leak in prod.
- `brute_force_service.py` — per-account lockout after 5 failures, 15-minute
  cooldown, exponential backoff.
- `device_service.py` + `routes_auth.py` — JWT-`did` binding, surgical
  per-device revoke.
- `alert_geo_service.py` — new-country sign-in alert with one-click revoke.
- `audit_service.py` + `audit_chain.py` — append-only, tamper-evident logs.
- `routes_gdpr.py` — Art. 15 / 17 / 20 endpoints.
- `maker_first_boot.py` — no default credentials; random secure password
  on first boot; logged + emailed once.

---

## 5. Audit-chain integrity (proof-of-tamper-evidence)

```
GET /api/security/audit/verify
Authorization: Bearer <admin JWT>

→ 200 OK
{
  "ok": true,
  "total": 18429,
  "tenant_id": "primary"
}

If a row was modified:
{
  "ok": false,
  "broken_at": 17812,
  "reason": "entry_hash mismatch — this entry has been modified",
  "tenant_id": "primary"
}
```

The chain walks `prev_hash → entry_hash` for every audit_logs row.
Any modification, insertion, or deletion of past entries breaks the chain.

---

## 6. Operational expectations

- **JWT secret**: must be ≥ 32 chars, ≥ 128 bits entropy. Boot aborts otherwise.
- **HTTPS-only**: HSTS preload header is set. Production must terminate TLS.
- **Backups**: daily Mongo dump at 02:00 UTC (scheduler). Retention 30d.
- **Patching**: monthly `pip-audit` + `yarn audit`; criticals patched ≤ 7d.
- **Pen-test**: annual external pen-test (most recent results in `pentests/`).

---

## 7. Last reviewed

- 2026-02-12 — v120 hardening pass (Tier 1+2+3 controls landed).
- Next scheduled review: 2026-05-12 (quarterly cadence).
