{
    "description": "Webhook signature test vectors (X-LMS-Signature: t={timestamp},v1={hex}[,v1={hex}]). A request is valid when hex(HMAC-SHA256(secret, \"{timestamp}.{raw_body}\")) equals any v1 value (constant-time comparison) and |now - timestamp| <= tolerance_seconds. During secret rotation the header carries two v1 signatures.",
    "algorithm": "HMAC-SHA256",
    "tolerance_seconds": 300,
    "vectors": [
        {
            "name": "valid",
            "secret": "whsec_test_4f9a1c7e2b8d",
            "raw_body": "{\"id\":\"7f3c2a9e-1b4d-4c8a-9e2f-5a6b7c8d9e01\",\"type\":\"course.completed\",\"created_at\":\"2025-10-09T08:53:20+00:00\",\"data\":{\"user\":{\"id\":\"3b9d6c1e-8a2f-4e7b-9c5d-1f2e3a4b5c6d\",\"employee_no\":\"E1001\"},\"course\":{\"id\":\"9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d\",\"code\":\"SAFETY-101\"},\"department_id\":null,\"attempt_id\":\"0c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f\",\"enrollment_id\":\"5e6f7a8b-9c0d-4e1f-8a2b-3c4d5e6f7a8b\",\"status\":\"passed\",\"score\":92,\"completed_at\":\"2025-10-09T08:53:18+00:00\"}}",
            "timestamp": 1760000000,
            "now": 1760000010,
            "header": "t=1760000000,v1=970ea87885bbbf477149b6018c0d032418d168c221a80b9344fbf753c744b9e9",
            "valid": true
        },
        {
            "name": "valid_previous_secret_during_rotation",
            "secret": "whsec_test_old_93b2e1",
            "raw_body": "{\"id\":\"7f3c2a9e-1b4d-4c8a-9e2f-5a6b7c8d9e01\",\"type\":\"course.completed\",\"created_at\":\"2025-10-09T08:53:20+00:00\",\"data\":{\"user\":{\"id\":\"3b9d6c1e-8a2f-4e7b-9c5d-1f2e3a4b5c6d\",\"employee_no\":\"E1001\"},\"course\":{\"id\":\"9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d\",\"code\":\"SAFETY-101\"},\"department_id\":null,\"attempt_id\":\"0c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f\",\"enrollment_id\":\"5e6f7a8b-9c0d-4e1f-8a2b-3c4d5e6f7a8b\",\"status\":\"passed\",\"score\":92,\"completed_at\":\"2025-10-09T08:53:18+00:00\"}}",
            "timestamp": 1760000000,
            "now": 1760000000,
            "header": "t=1760000000,v1=0f529f3018259bd644ffeaceb66e9abd38d21a841cc128bd5d7487d26a54c22d,v1=61e4027ddca3ee77462dea6a5484711fbb404df984241791b04f70b09542d211",
            "valid": true
        },
        {
            "name": "wrong_secret",
            "secret": "whsec_test_other_1a2b3c",
            "raw_body": "{\"id\":\"7f3c2a9e-1b4d-4c8a-9e2f-5a6b7c8d9e01\",\"type\":\"course.completed\",\"created_at\":\"2025-10-09T08:53:20+00:00\",\"data\":{\"user\":{\"id\":\"3b9d6c1e-8a2f-4e7b-9c5d-1f2e3a4b5c6d\",\"employee_no\":\"E1001\"},\"course\":{\"id\":\"9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d\",\"code\":\"SAFETY-101\"},\"department_id\":null,\"attempt_id\":\"0c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f\",\"enrollment_id\":\"5e6f7a8b-9c0d-4e1f-8a2b-3c4d5e6f7a8b\",\"status\":\"passed\",\"score\":92,\"completed_at\":\"2025-10-09T08:53:18+00:00\"}}",
            "timestamp": 1760000000,
            "now": 1760000000,
            "header": "t=1760000000,v1=970ea87885bbbf477149b6018c0d032418d168c221a80b9344fbf753c744b9e9",
            "valid": false
        },
        {
            "name": "body_modified",
            "secret": "whsec_test_4f9a1c7e2b8d",
            "raw_body": "{\"id\":\"7f3c2a9e-1b4d-4c8a-9e2f-5a6b7c8d9e01\",\"type\":\"course.completed\",\"created_at\":\"2025-10-09T08:53:20+00:00\",\"data\":{\"user\":{\"id\":\"3b9d6c1e-8a2f-4e7b-9c5d-1f2e3a4b5c6d\",\"employee_no\":\"E1001\"},\"course\":{\"id\":\"9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d\",\"code\":\"SAFETY-101\"},\"department_id\":null,\"attempt_id\":\"0c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f\",\"enrollment_id\":\"5e6f7a8b-9c0d-4e1f-8a2b-3c4d5e6f7a8b\",\"status\":\"passed\",\"score\":100,\"completed_at\":\"2025-10-09T08:53:18+00:00\"}}",
            "timestamp": 1760000000,
            "now": 1760000000,
            "header": "t=1760000000,v1=970ea87885bbbf477149b6018c0d032418d168c221a80b9344fbf753c744b9e9",
            "valid": false
        },
        {
            "name": "timestamp_too_old",
            "secret": "whsec_test_4f9a1c7e2b8d",
            "raw_body": "{\"id\":\"7f3c2a9e-1b4d-4c8a-9e2f-5a6b7c8d9e01\",\"type\":\"course.completed\",\"created_at\":\"2025-10-09T08:53:20+00:00\",\"data\":{\"user\":{\"id\":\"3b9d6c1e-8a2f-4e7b-9c5d-1f2e3a4b5c6d\",\"employee_no\":\"E1001\"},\"course\":{\"id\":\"9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d\",\"code\":\"SAFETY-101\"},\"department_id\":null,\"attempt_id\":\"0c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f\",\"enrollment_id\":\"5e6f7a8b-9c0d-4e1f-8a2b-3c4d5e6f7a8b\",\"status\":\"passed\",\"score\":92,\"completed_at\":\"2025-10-09T08:53:18+00:00\"}}",
            "timestamp": 1760000000,
            "now": 1760000301,
            "header": "t=1760000000,v1=970ea87885bbbf477149b6018c0d032418d168c221a80b9344fbf753c744b9e9",
            "valid": false
        }
    ]
}
