# OfficeCom Sentinel n8n Contract ## Request - method: `POST` - content type: `application/json` - example webhook: `https://n8n.example.com/webhook/ocsentinel-ingest` ## Required Payload Intent The endpoint should send one signed JSON document per scan run containing: - device identity - client version - scan metadata - attack findings - CVE correlation summary - raw status fields needed for downstream NinjaOne updates ## Expected Downstream Work n8n is responsible for: - ingest validation - storage in the central backend - organization-wide aggregation - NinjaOne organization API updates ## Required n8n Workflow The webhook itself may be reachable only on the internal network. It does not require public access to the n8n editor or API. Every managed device must be able to reach the webhook URL over HTTPS. 1. `Webhook`: accept `POST` on the configured private URL. 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. 3. `Code`: calculate SHA-256 over the raw request body and compare it with `X-ATN-Payload-SHA256`. Calculate HMAC-SHA256 over the following exact newline-separated string and compare it in constant time with `X-ATN-Signature`: ```text \n\n\n\n ``` 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`, then return `202`. 6. A separate scheduled n8n workflow reads `ocsentinel.organization_summary` and `ocsentinel.current_device_status` to update the NinjaOne organization fields through the API. Use an n8n credential for the shared HMAC secret and a separate n8n credential for PostgreSQL. Do not store either value in workflow JSON or this repository. ## PostgreSQL Scope - The client only knows its outward upload destination. - PostgreSQL connection details belong to the internal ingest or n8n side. - If the PostgreSQL IP changes, update the internal server-side configuration and review it during the next release.