From f3920575352194a995ba4e8881e2bcb4e56f5049 Mon Sep 17 00:00:00 2001 From: OfficeCom Codex Date: Sat, 25 Jul 2026 21:26:56 +0200 Subject: [PATCH] Document n8n raw body signature validation --- docs/ocsentinel-n8n-contract.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/ocsentinel-n8n-contract.md b/docs/ocsentinel-n8n-contract.md index fb52404..fd5ebbe 100644 --- a/docs/ocsentinel-n8n-contract.md +++ b/docs/ocsentinel-n8n-contract.md @@ -36,7 +36,7 @@ For the isolated development environment only, HTTP is permitted at `http://172.16.41.197:5678/webhook/ocsentinel-ingest`. Do not reuse this URL, the development shared secret, or a disabled-TLS configuration in production. -1. `Webhook`: accept `POST` on the configured private URL. +1. `Webhook`: accept `POST` on the configured private URL and enable **Raw Body**. 2. `Code`: reject a request if `X-ATN-Device`, `X-ATN-Timestamp`, `X-ATN-Nonce`, `X-ATN-Version`, `X-ATN-Payload-SHA256`, or `X-ATN-Signature` is missing; reject timestamps outside five minutes. @@ -49,6 +49,11 @@ the development shared secret, or a disabled-TLS configuration in production. \n\n\n\n ``` +In the current n8n Webhook node, the raw bytes are exposed as Base64 at +`$binary.data.data`. Decode this value before calculating the payload hash. +Do not hash `JSON.stringify($json.body)`: parsing and reserializing JSON +changes whitespace and can change the signed byte sequence. + 4. `Postgres`: insert the nonce into `ocsentinel.ingest_nonce` with a short expiry. If it already exists, return `409` and do not process the report. 5. `Postgres`: upsert the device, insert a row in `ocsentinel.scan_report`,