Appearance
Integration & Conformance
Audience: Bank integration / FMS / SOC engineering leads
Purpose: Prove that onboarding is config + a joint test week, not a custom build
last-verified:72298a8(FMS conformance package)
Verify us: nothing on this page requires trusting Waspada at runtime. Contracts are published, signatures are offline-checkable, and CI fails if the published verifier drifts from the gateway signer. Field mapping (ingress → egress) and partner_case_id vs mule_key are documented in the contracts README.
What you get
| Artifact | What it proves | Location |
|---|---|---|
| Ingress schema | Shape of POST /api/v1/telemetry/ingest | telemetry-ingest.schema.json |
| Egress schema (v2.0.0) | Shape of the FMS webhook alert | fms-alert.schema.json |
| Offline verify | Alert is authentically ours and untampered | apps/gateway-api/scripts/verify-alert.mjs |
| Sample vector | Signed alert + gateway public key | apps/gateway-api/contracts/examples/ |
| Conformance simulator | Schema + pilot invariants + FMS response matrix | apps/gateway-api/scripts/fms-simulator.mjs |
| STIX lint CI | Real formatter output passes STIX 2.1 pre-flight | .github/workflows/contracts.yml |
| Drift guard | Published canonical bytes ≡ buildGatewaySignPayload | apps/gateway-api/tests/contract-drift.test.ts |
Full engineer README: apps/gateway-api/contracts/README.md.
Offline signature verification
Every alert carries cryptographic_proof.gateway_signature (RSA-SHA256). Fetch the public key once (GET /api/v1/gateway/public-key), then verify any alert with no network and no trust:
bash
cd apps/gateway-api
node scripts/verify-alert.mjs contracts/examples/alert.sample.json contracts/examples/gateway_public_key.pem
# VALID → authentic, untampered
# INVALID → tampered, wrong key, or contract-version mismatchCanonical signed key order (contract v2.0.0) is fixed and CI-guarded — see the contracts README. Nested indicators / enrichment_data must not be re-keyed by intermediaries.
v1 → v2 is a breaking change (24 August 2026)
mule_key moved from an unkeyed SHA-256 to a keyed HMAC under a consortium pepper, and a new required mule_key_epoch sits directly after mule_key in the signed key order. Two consequences for an existing integration:
- Every
mule_keyvalue changes for the same account. Join on(mule_key, mule_key_epoch). - A v1 offline verifier reports
INVALIDon a v2 alert, and the current verifier reportsCONTRACT MISMATCHon a v1 alert. Both are by design — not a tampering event. Verifying across the change would let you keep joining a key space that no longer means what it did.
Rebuild your canonical-bytes reconstruction from the order above before ingesting v2 alerts.
Conformance simulator (before your FMS)
Run a shareable “bank FMS” that validates every alert against the published schema and pilot invariants (disposition=advisory, action_requested=MONITOR), and can emulate 200 / 429 / 5xx / timeout so outbox retry behaviour is exercised:
bash
cd apps/gateway-api
node scripts/fms-simulator.mjs
# SIM_MODE=sequence | fail-rate | timeout — see contracts READMEPoint FMS_WEBHOOK_URL (or load-test --mock-fms) at it. Related ops docs: FMS Webhooks, durable-path soak.
STIX 2.1 egress
STIX bundles are produced by the gateway formatter. A fast lint runs in CI on real formatter output (emit-sample-stix → validate-stix). The authoritative OASIS stix2-validator step is currently non-blocking until custom x_waspada_* extensions are reviewed — flip to required after one clean CI run.
What this does not settle
Semantic mapping of our urgency / disposition / action_requested onto your FMS case/queue model is discovered in the joint integration week. These artifacts make format, authenticity, and delivery behaviour verifiable in advance.
Claims we still do not make
- “BNM-compliant” / “RMiT-certified” / “BNM-ready production”
- That public / WhatsApp triage alone drives bank FMS or corroboration (ADV-005)
- Sub-second gateway ingest on the durable topology (memory path p99 is measured separately — executive summary)