From 4222e827f9f742d9749d94846483649c8390b788 Mon Sep 17 00:00:00 2001 From: DevEnv nis2-agile Date: Sat, 13 Jun 2026 09:41:22 +0200 Subject: [PATCH] [DEMO] Archivio scambio AgileHub 2026-06-13: HMAC #1 CHIUSO (runtime-avatar = no HMAC per-msg) - INCOMING_FROM_AGILEHUB: contratto HMAC external/v1 (canale ticket) + chiarimento canale runtime-avatar (X-Internal-Key, no HMAC per-messaggio) + persona ARIA pronta (RAG 402) + piano Fase 1. - OUTGOING aggiornato: punto coordinamento #1 marcato CHIUSO (demo-mode.js HMAC_ENFORCE=false, a851caf). --- ...G_FROM_AGILEHUB_2026_06_13_hmac_e_piano.md | 38 +++++++++++++++++++ ...26_06_13_demo_avatar_nis2_product_ready.md | 2 +- 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 docs/INCOMING_FROM_AGILEHUB_2026_06_13_hmac_e_piano.md diff --git a/docs/INCOMING_FROM_AGILEHUB_2026_06_13_hmac_e_piano.md b/docs/INCOMING_FROM_AGILEHUB_2026_06_13_hmac_e_piano.md new file mode 100644 index 0000000..1aea28e --- /dev/null +++ b/docs/INCOMING_FROM_AGILEHUB_2026_06_13_hmac_e_piano.md @@ -0,0 +1,38 @@ +# AgileHub → NIS2 — Chiusura HMAC (#1) + piano avatar formazione/demo + +> **Da**: AgileHub · **A**: NIS2 · **Data**: 2026-06-13 · Per gli atti. +> Risposta nostra: `docs/OUTGOING_TO_AGILEHUB_2026_06_13_demo_avatar_nis2_product_ready.md` (punto #1 chiuso). + +## #1 — HMAC canonical (gateway external/v1 — canale ticket/egress, scope `tickets:*`) +Verifier: `crypto.js` + `externalAuth.js` del gateway external/v1. `canonicalize()` deve produrre ESATTAMENTE: + +``` +METHOD \n ORIGINAL_URL \n X-Cred-Id \n X-Cred-Timestamp \n X-Cred-Nonce \n X-Tenant-Ref \n SHA256HEX(rawBody) +``` + +Gotcha: +- Separatore = singolo `\n` (LF 0x0A). No CRLF, no spazi attorno. +- `METHOD` maiuscolo. +- PATH = `req.originalUrl` = **path + query string** così com'è inviato (se c'è `?a=1` va incluso identico). NON solo il pathname. +- Ultimo campo = sha256 hex **lowercase** del rawBody esatto (body vuoto → `sha256("")` = `e3b0c4…`). +- Firma: HMAC-SHA256, chiave = `signing_key` **hex-decodificata in byte** (`Buffer.from(keyHex,'hex')`, non la stringa hex come utf8), output hex lowercase. +- Header firma: `X-Cred-Signature: v1=` (prefisso `v1=`). +- `X-Cred-Timestamp` = Unix **secondi** (non ms). Anti-replay ±300s + nonce unico per credenziale. +- Header obbligatori: `X-Cred-Id`, `X-Cred-Timestamp`, `X-Cred-Nonce`, `X-Tenant-Ref`, `X-Cred-Signature`. +- Rif.: `DEV_GUIDE_AGILEHUB_EXTERNAL_API.md §3` + `API_GUIDE §3`. + +### ⚠️ Chiarimento di canale (decisivo) +Questo HMAC è del **gateway external/v1** (canale ticket/egress). Il **runtime avatar demo** (`/demo-session/start` + LLM dimostrazione) **NON usa HMAC per-messaggio**: usa **`X-Internal-Key` server-to-server** (come ALLTAX). +→ **Risoluzione NIS2**: la nostra `demo-mode.js` è il canale **runtime-avatar** (postMessage widget→SPA), quindi **niente HMAC per-messaggio** (origin-verified) + `X-Internal-Key` server-to-server (già su `reset-dataset`). **Non serve** credenziale `nis2_extcred_…`. (Se in futuro NIS2 userà external/v1 → si conia la credenziale e si usa la canonical sopra.) + +## Stato lato AgileHub +- **Persona `ARIA_SUPPORT_NIS2`** già pronta e vestita: Tavus "Giulia" + voce ARIA "Charlotte" IT + Sonnet 4.6 + **RAG repo 402**. Zero da creare. +- **Same-origin** su `dimostrazione.agile.software` (scelto): preparano il vhost (proxy `/api/*` + CSP iframe); vhost condiviso → backup + OK prima del reload. +- **Formazione = sottosistema condiviso** (scelto): build vero (schema + endpoint attestato/esame 80%/progresso + collaudo). **NIS2 = pilota genesi**. + +## Cosa serve da NIS2 per partire (Fase 1) — FORNITO +1. Le 22 mappe + tag `demo:nis2-tour-2026:stepN` + scelta repo (402 vs dedicato). → `docs/mappa-logica/` su Gitea main; mapping step→mappa fornito nell'OUTGOING. +2. Artefatto SPA + route + `/api/*` da proxare + CSP. → **NIS2 è multi-pagina, non un bundle**: reverse-proxy dell'app sotto `dimostrazione`; route/asset/CSP forniti nell'OUTGOING. +3. Tassonomia + banca export. → `docs/formazione/` su Gitea main. + +→ Appena hanno (1) e (3) partono. Ci hanno chiesto se procedere col design del sottosistema formazione: **risposto sì, procedete ora** (export già in Gitea). diff --git a/docs/OUTGOING_TO_AGILEHUB_2026_06_13_demo_avatar_nis2_product_ready.md b/docs/OUTGOING_TO_AGILEHUB_2026_06_13_demo_avatar_nis2_product_ready.md index 8ecadba..7447304 100644 --- a/docs/OUTGOING_TO_AGILEHUB_2026_06_13_demo_avatar_nis2_product_ready.md +++ b/docs/OUTGOING_TO_AGILEHUB_2026_06_13_demo_avatar_nis2_product_ready.md @@ -32,7 +32,7 @@ - **Collaudo oggettivo** (definizione di "fatto"). ## Punti di coordinamento da chiudere insieme (al collaudo) -1. **HMAC canonical del MESSAGGIO**: la chiave canale è a contratto (`SHA-256(demo_jwt+":"+seed+":demo-control-channel")`); la *canonicalizzazione del messaggio* per l'HMAC non è fissata nello standard. In `demo-mode.js` → `canonicalize()` è marcata **TO-RECONCILE**: diteci la forma esatta del vostro parser (campi/ordine/separatore) e la allineo. *(In `demo-mode.js`: `HMAC_ENFORCE=true`.)* +1. ~~**HMAC canonical del MESSAGGIO**~~ → **CHIUSO 2026-06-13** (vedi `INCOMING_FROM_AGILEHUB_2026_06_13_hmac_e_piano.md`). Chiarito che la `demo-mode.js` è il **canale runtime-avatar** (postMessage widget→SPA): **niente HMAC per-messaggio**, security = `ev.origin` (same-origin) + `X-Internal-Key` server-to-server (già su `reset-dataset`). `demo-mode.js` aggiornato: `HMAC_ENFORCE=false` (commit `a851caf`). L'HMAC canonical `METHOD\nURL\n…\nsha256(body)` resta documentato per il **gateway external/v1** (canale ticket), non usato dall'avatar. 2. **Ops same-origin**: `dimostrazione.agile.software` deve servire la SPA NIS2 **same-origin** con la landing e proxare `/api/*` → backend NIS2, con CSP che consenta l'iframe. In alternativa vi do uno `SPA_BASE` dedicato. *(Senza same-origin l'HMAC via `sessionStorage` e gli URL del manifest non risolvono.)* 3. **`data-demo-action` anchors**: le azioni read-only del tour (`open-tab-*`, `open-ai-panel`, `open-first-detail`) sono in whitelist (`demo-selectors.js`) ma gli anchor nel DOM sono da cablare (sweep id residuo). Per il tour attuale (navigate + highlight) **non sono bloccanti**. 4. **Sweep id stabili (132)**: in completamento; il manifest attuale àncora gli highlight a **id già esistenti e verificati** (non i 132), quindi il tour funziona già.