[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).
This commit is contained in:
@@ -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=<hex>` (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).
|
||||
@@ -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à.
|
||||
|
||||
Reference in New Issue
Block a user