Appearance
VAPT Engagement Brief
Document type: Scoped testing mandate for an independent CREST (or equivalent) VAPT provider
Version: 0.1 · Date: 2026-07-11
Owner: Waspada AI engineering
Related: Executive summary · RMiT mapping · Security overview · Phase B1–B4 runtime
1. Purpose
Commission an independent vulnerability assessment and penetration test of the Waspada gateway and adjacent trust boundaries so that:
- An FI CISO can attach an external assurance letter to their RMiT §11 / Appendix 5 evidence pack.
- Residual findings are tracked against a known architecture (not discovered from a blank box).
- Discovery billing is minimised — auditors receive trust-boundary maps, prior adversarial findings, and measured soak artifacts up front.
This brief is not a VAPT report and not a claim of compliance.
2. System under test (SUT)
| Component | Role | Typical deploy |
|---|---|---|
@waspada/sdk (edge) | On-device extraction, PII strip, JWT-bound telemetry | Partner WebView / browser |
gateway-api | JWT verify, defense-in-depth PII, RDAP enrich, FMS/STIX/SSE, durable B1–B4 path | Railway / FI VPC |
analyst-dashboard | Authenticated SSE consumer | Static + API key / ticket |
| Redis | JTI / rate limits / tickets; Streams (waspada:events); SSE pub/sub | Managed Redis |
| Postgres | alerts (DEK+AAD), audit_events, delivery_outbox, processed_events | Managed Postgres |
Product posture: advisory mule-fraud telemetry. Automated freeze is out of scope for the product and for this test (bank owns disposition).
3. Trust boundaries (test narrative)
Auditors should treat these as the primary attack surfaces. We want findings mapped to a boundary ID.
┌─ TB-1 Client device ─────────────────────────────────────┐
│ Evidence → OCR/PDF → extract → PII strip → indicators │
│ Local AES-GCM evidence store (optional) │
└────────────────────────────┬─────────────────────────────┘
│ HTTPS + partner RS256 JWT
▼
┌─ TB-2 Edge / partner network ────────────────────────────┐
│ Partner app holds signing key; Waspada does not │
└────────────────────────────┬─────────────────────────────┘
│
▼
┌─ TB-3 Gateway API (hardened runtime) ────────────────────┐
│ Pre-auth rate limit → JWT verify → payload bind │
│ PII dual gate → RDAP (SSRF-capped) → pipeline │
│ Redis Streams publish · audit_events · encrypted alerts │
│ delivery_outbox → FMS webhook · SSE ticket fan-out │
└───────────────┬────────────────────────────┬─────────────┘
│ │
▼ ▼
┌─ TB-4 Data plane ──────┐ ┌─ TB-5 Egress ──────────────┐
│ Redis + Postgres │ │ Bank FMS webhook (HTTPS) │
│ KEK env / KMS-bound │ │ STIX export │
│ Per-row DEK + AAD │ │ Analyst SSE (ticket auth) │
└────────────────────────┘ └────────────────────────────┘| ID | Boundary | What “break” means |
|---|---|---|
| TB-1 | Client | Extract PII that should have been stripped; bypass allowlists; abuse local store |
| TB-2 | Partner auth | Forge/replay JWT; confuse kid/issuer; escalate partner identity |
| TB-3 | Gateway | Unauth access to alerts/SSE; demo signing oracle in hardened mode; SSRF via RDAP/URL; DoS via unbounded work |
| TB-4 | Data plane | Cross-tenant read; decrypt without KEK; AAD strip/swap; outbox injection; Streams idempotency bypass |
| TB-5 | Egress | Alert tamper undetected; webhook SSRF from gateway; SSE data leak without ticket |
4. In scope
4.1 Application / API
POST /api/v1/telemetry/ingest(authn, authz, replayjti, payload hash binding, rate limits)- Analyst auth → SSE ticket minting →
GETalert stream - FMS delivery path (outbox claim → decrypt → POST) including fail-open vs fail-closed config
- STIX export endpoints / serializers (if exposed on the tested deploy)
/healthand any unauthenticated surfaces- Production boot guards: missing
REDIS_URL/ALERT_DATA_KEK/ gateway PEM must refuse boot in hardened/production mode
4.2 Cryptography & tenancy
- Partner JWT verification (RS256,
kid, expiry, issuer) - Gateway alert signatures (RSA-SHA256 from env PEM — no ephemeral keys in prod)
- Per-row AES-256-GCM DEK, KEK wrap, AAD
tenant_id:alert_id:field - Tenant isolation on
alerts,audit_events,delivery_outbox,processed_events
4.3 Async durability
- Redis Streams consumer-group behaviour and atomic
processed_eventsclaim (inline + consumer share one winner) - Outbox status machine (
pending→in_flight→succeeded/failed/dead_lettered) with lease reaper for stalein_flight - Cross-replica SSE pub/sub (
waspada:sse) — tenant-scoped fan-out (ADV-004); Redis messages are{v:1, tenant_id, payload}envelopes
4.4 Known residual (must be tested / confirmed)
- No
XAUTOCLAIMPEL sweep (B5) — confirm stuck Streams PEL behaviour after simulated worker crash; document as accepted risk or finding. (Outboxin_flight+ eventin_progressleases are reaped — retest those paths.) - Claim integrity (ADV-003) — public marketing/docs must match executive summary non-claims (no “RMiT-certified”, absolute zero-PII, or sub-second durable ingest). Retest landing / whitepaper / docs after each copy change.
- Audit writes are 1 INSERT/event — abuse for storage/CPU amplification
- Durable ingest latency ~2 s p99 under load is a design trade-off; DoS tests should still attempt amplification beyond published soak
4.5 Configuration review
- Env matrix:
REQUIRE_REDIS,ALLOW_MEMORY_STORE,FMS_DELIVERY_REQUIRED,FMS_WEBHOOK_URL,ALERT_DATA_KEK, gateway PEMs - Confirm demo / ephemeral signing paths are unreachable on the hardened target
5. Out of scope (unless FI expands SOW)
| Item | Reason |
|---|---|
| Partner bank FMS / core banking | Third-party; advisory only |
| Physical / social engineering of FI staff | Separate engagement |
| Full source-code audit of all monorepo packages | Optional add-on; default is grey-box on deployed SUT + provided design docs |
| Mobile OS / WebView browser engine CVEs | Platform; test our bridge/allowlist behaviour only |
| DDoS at network layer beyond agreed rate | Coordinate with host (Railway / FI SOC) |
| Destruction of production customer data | Use staging / dedicated VAPT project only |
| Claiming RMiT certification | FI + regulator process; VAPT is an input |
6. Methodology expectations
| Mode | Required |
|---|---|
| Grey-box | Yes — credentials for one test partner JWT keypair + analyst API key; architecture docs below |
| Black-box | Optional first 1–2 days without keys, then grey-box |
| Authenticated | Partner ingest + analyst SSE |
| Unauthenticated | All public routes, CORS, ticket guessing, webhook callbacks if any |
| Dependency / SCA | Include lockfile CVE review for gateway runtime |
| Transport | TLS to staging endpoint; no requirement to break TLS itself |
Rules of engagement
- Target: staging / dedicated VAPT deploy only (never production partner traffic).
- Provide 24h contact; stop on critical data-destruction risk.
- No intentional ransomware / crypto-wipe.
- Rate-limit / WAF may be raised for the window; document the final config in the report.
- Timebox: recommend 5–8 working days grey-box + 2 days report (adjust to provider).
7. Priority test cases (control the narrative)
These are the cases we already red-teamed internally. Auditors should re-validate and attempt to go further.
| # | Case | Boundary | Pass criteria (summary) |
|---|---|---|---|
| V-01 | Unauthenticated SSE / alert disclosure | TB-3 / TB-5 | No alert payload without valid ticket |
| V-02 | Demo / ephemeral gateway signing in hardened mode | TB-3 | Boot refuse or path absent |
| V-03 | JWT forge, kid confusion, expired/replayed jti | TB-2 | Reject; replay store shared via Redis |
| V-04 | Payload hash / signature binding bypass | TB-3 | Mutated body rejected |
| V-05 | NRIC / phone / email egress | TB-1 / TB-3 | Dual gate strips; no mule←NRIC confusion |
| V-06 | RDAP / URL SSRF (metadata, link-local, credentialed URLs) | TB-3 | Blocked / capped |
| V-07 | Cross-tenant alert or outbox read / SSE fan-out | TB-4 / TB-5 | DB reads scoped by tenant_id; SSE clients only receive alerts for their bound tenant scope |
| V-08 | Ciphertext swap / AAD mismatch decrypt | TB-4 | Decrypt fail; no silent success |
| V-09 | Outbox re-drive / idempotency key collision | TB-4 / TB-5 | Keyed by fms:${event_id}; no duplicate FMS enqueue; stale in_flight reaped by lease |
| V-10 | Streams + inline double-process | TB-4 | Atomic lease-aware processed_events claim (in_progress→committed); stale claims reaped; corroboration bumps only on new alert |
| V-11 | Worker crash → stuck PEL (no XAUTOCLAIM) | TB-4 | Streams PEL still B5 residual; outbox in_flight + event in_progress leases are reaped so a future XAUTOCLAIM retry is not defeated |
| V-12 | Rate-limit / memory exhaustion via large bodies | TB-3 | Limits hold; no OOM under agreed budget |
| V-13 | Analyst key in query string / ticket theft | TB-5 | Tickets short-lived; key not required in EventSource URL long-term |
| V-14 | FMS webhook SSRF from configurable URL | TB-5 | HTTPS-only in prod; block private targets if enforced |
8. Evidence pack (provide to provider on kickoff)
| Artifact | Location |
|---|---|
| Executive status / claims boundary | executive-summary.md |
| RMiT working table | rmit-mapping.md |
| DPIA draft | dpia.md |
| Data flows | data-flows.md |
| B0 foundations | phase-b0-foundations.md |
| B1–B4 runtime + known gaps | phase-b1-b4-runtime.md |
| Advisory contract | advisory-contract.md |
| Memory ingest soak | load-test/REPORT.md |
| Durable + mock-FMS soak | load-test/REPORT-durable.md |
| Extraction CI gate | Available on request |
| AppSec hardening trail | 13 internal hardening sprints (credibility → B0 → eval → RMiT/B1–B4 → load-test) |
Access to provide
- Staging base URL +
/health - One partner public key registered; corresponding private key for JWT signing (test-only)
- Analyst API key
- Read-only DB view or sanitized row samples for crypto/tenancy checks (optional but accelerates TB-4)
- Redis ACL user limited to app key prefixes (optional)
9. Deliverables required from the provider
- Executive letter (1–2 pages) suitable for FI CISO attachment.
- Technical report with findings rated Critical / High / Medium / Low / Informational; each mapped to a TB-* ID and, where applicable, an RMiT cite (§11 / App. 5 / crypto / access).
- Reproduction steps and evidence (request/response, screenshots, PoC scripts).
- Retest window (recommend +10 working days after fixes) and updated letter.
- Explicit statement on V-11 (XAUTOCLAIM gap) — accepted risk vs finding.
Severity guidance we accept: OWASP / CVSS v3.1; privilege relative to partner vs anonymous.
10. Success criteria for Waspada
| Outcome | Meaning |
|---|---|
| Ready for pilot attachment | No open Critical/High on TB-2/TB-3/TB-4/TB-5 after retest; Mediums scheduled with owners |
| RMiT evidence input | Letter + report filed against §11 / Appendix 5 gap row in rmit-mapping.md |
| Score impact | Supports moving production readiness narrative from ~7.5–7.6 toward 8.0+ once letter lands — does not by itself certify BNM/RMiT |
11. Suggested SOW one-pager (paste into RFP)
Grey-box VAPT of Waspada AI staging gateway (Fastify) including partner JWT ingest, analyst SSE tickets, Redis Streams + Postgres durable path (encrypted alerts, audit log, FMS outbox), RDAP enrichment SSRF controls, and production boot guards. Edge SDK in-scope for PII-strip and telemetry allowlist only. Out of scope: bank FMS, production data, network DDoS. Provider delivers CISO letter + technical report mapped to supplied trust-boundary IDs, with retest. Kickoff pack includes RMiT mapping, DPIA, B1–B4 runtime notes, and load/soak reports.
Change log
| Date | Change |
|---|---|
| 2026-07-11 | v0.1 — initial engagement brief for provider RFP / kickoff |