nis2-agile/docs/STANDARD_INSTALLER_INTEGRATION.md
DevEnv nis2-agile c0bf7b6c15 [DOCS] Standard cross-suite AgileHub + governance CLAUDE.md + registri agent
- CLAUDE.md: TZ, SSO, vault-steward, versioning, persona v2.0, multitenant, KB RAG
- docs/standards: persona-conversational-rules v2.0
- docs/STANDARD_*: installer-integration, email-relay, AI-prodotto, marketing-tenant, multitenant
- AGENT_CHANGES.md + OPEN_TICKETS.md (registri agent automatico)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 15:41:54 +02:00

299 lines
15 KiB
Markdown

# STANDARD AgileHub — Installer Integration (canonico)
> **Autorità**: AgileHub (single source of truth per la suite Agile Software).
> **Versione**: 1.0.1 — 2026-04-19 (patch: chiarimento payload tenants/report)
> **Stato**: ADOTTATO. Sostituisce qualsiasi proposta prodotto in caso di conflitto.
> **Destinatari**: team TRPG, SustainAI, NIS2, TAXAI (AllTax), LG231, DFM, MKTG, ALLRISK, WMS, MADEBYCLOUD, CertiSource.
> **Spec origine**: `AGILEHUB_INSTALLER_INTEGRATION_SPEC.md` v1.0 (TRPG, 2026-04-19) — recepita con override sotto.
> **Registry DB**: record master in `nexus_hub.hub_standards` (slug=`installer-integration`, version=`1.0.1`). Questo file è una **copia derivata** — in caso di disallineamento vince il DB.
## Changelog
### v1.0.1 — 2026-04-19 (patch, non breaking)
- **§3.1 `POST /api/tenants/report`**: chiarito che `license_key` è **obbligatorio** nel body (era implicito via "firma HMAC obbligatoria" ma non listato nel payload d'esempio). Serve al middleware HMAC per il lookup della `hub_signing_key`. Origine: smoke test TRPG 2026-04-19 21:15 — 404 LICENSE_NOT_FOUND senza license_key. Decisione AgileHub: consistency > minimal payload (defence in depth anti-tamper).
- TRPG già conforme via commit `5c1aa2e` (2026-04-19).
- Altri prodotti: allineare payload `tenants/report` aggiungendo `license_key` string.
### v1.0 — 2026-04-19
- Versione iniziale adottata. Spec origine TRPG recepita con override AgileHub.
---
## 1. Portata e autorità
Questo documento definisce **il contratto unico** fra AgileHub e i prodotti installati on-premise (o white-label) della suite. Vale per:
- Registrazione prodotti in AgileHub (`hub_products`)
- Provisioning istanze cliente (orchestrator SSH + installer script prodotto)
- Licensing + heartbeat + alert
- Onboarding tenant (consulting_firms) cross-istanza
- Firma HMAC + vault SSH
**Regola di precedenza**: in caso di conflitto fra una proposta prodotto (es. `*_INTEGRATION_SPEC.md` nel loro `docs/`) e questo standard, **vince questo standard**. Deviazioni motivate vanno chieste via ticket AgileHub con tag `standard-exception`.
---
## 2. Decisioni AgileHub (override sulla spec TRPG v1.0)
### 2.1 Hostname ufficiale
| Ruolo | Hostname | Uso |
|-------|----------|-----|
| Hub UI | `https://agilehub.agile.software` | Dashboard admin, `/admin/products/*` |
| Hub API (licensing) | `https://agilehub.agile.software/api/license/*` | endpoint validate/activate/register/report |
| Hub API (installer orchestrator) | `https://agilehub.agile.software/api/installer/*` | wizard, job status, log streaming |
> **NO `hub.agile.software`**. I prodotti che chiamano `hub.agile.software` vanno corretti prima del pilota.
### 2.2 Stack tecnico
| Layer | Scelta |
|-------|--------|
| Backend licensing/installer | **Node.js 20 + Express** (pattern `nexus-*-ms`), microservizio nuovo `nexus-hub-ms` porta **4217** |
| DB | **MySQL host Hetzner** (172.18.0.1:3306), DB dedicato **`nexus_hub`**, user `nexus_user` |
| Frontend | **Next.js 15 + React 19** in `nexus-dashboard`, nuova sezione `/admin/products/*` |
| Job queue (Fase 3) | **BullMQ su Redis** (da aggiungere infra). Fino a Fase 2: cron + status polling |
| Email | Microservizio esistente **`email-automation-ms`** (NO SendGrid/MailHog esterni) |
| Secret vault | **AES-256-GCM env-based**, chiave in `/etc/agilehub/vault.env` (NO HashiCorp Vault/KMS) |
| SSH worker | **ssh2** (npm) invocato da `nexus-hub-ms`, chiave decifrata on-demand |
### 2.3 Prefisso tabelle e naming DB
- DB dedicato: `nexus_hub`
- Tabelle: prefisso `hub_` mantenuto (compat con spec origine). Accesso esclusivo da `nexus-hub-ms`.
- Cross-DB query verso `nexus_ticket_db`, `nexus_tenant_db`, `nexus_lead_db` sono permesse solo via GRANT dedicato a `nexus_user` (pattern già in uso per SSO).
### 2.4 Ruoli
| Ruolo | Permessi |
|-------|----------|
| `hub_admin` | Tutto tranne provisioning SSH |
| `hub_installer` | **Nuovo**. Lettura `hub_*`, esecuzione wizard, decrypt chiavi SSH con audit obbligatorio |
| `hub_support` | Solo lettura `hub_instances`, `hub_tenants`, `hub_license_heartbeats` |
Il ruolo `hub_installer` è **richiesto** per Fase 3. Non riutilizzare `hub_admin`: blast radius troppo ampio.
### 2.5 Versioning
Recepita la regola TRPG: **version mai hardcodata nei seed o nelle migration**. La hub la registra da payload heartbeat. Per `hub_products.version` (ultima release disponibile) leggere on-demand via `GET https://<product>.agile.software/version.json` oppure aggiornare via `POST /api/products/:slug/version` (admin-only).
### 2.6 Integrazione obbligatoria con SSO
`hub_tenants.owner_email` **DEVE** essere foreign-key logica verso `sso_identities.email` (DB `nexus_tenant_db`). Al provisioning di un nuovo tenant:
1. `nexus-hub-ms` POST `/api/auth/admin/tenants/create` sull'istanza
2. L'istanza crea `consulting_firm` + `user` locale
3. `nexus-hub-ms` replica l'identità in `sso_identities` (se non esiste)
4. Prima login dell'owner → SSO flow standard (Fase 2 SSO)
**Prodotti che non hanno ancora SSO dual-mode**: finché non è attivo, `hub_tenants` funziona stand-alone ma `owner_email` deve comunque essere univoco cross-istanza.
### 2.7 Deprecazione `products.json`
`/opt/agent-ai/hub/products.json` è **deprecato** dalla Fase 2. Entro la Fase 2 completa:
- `hub_products` diventa la sorgente di verità
- La UI legge da `hub_products`, non più da `products.json`
- `products.json` resta come fallback statico per landing page esterne, generato da cron da `hub_products`
### 2.8 Multi-prodotto da subito
Fase 1 va implementata **generica** (non TRPG-specific). Lo schema, gli endpoint e le firme HMAC supportano `product_slug` variabile fin dal primo giorno. Il seed iniziale è per TRPG, ma il codice non hardcoda nulla.
---
## 3. Contratto API canonico
### 3.1 Endpoint hub (Istanza → AgileHub)
Tutti su `https://agilehub.agile.software/api/...`, header obbligatorio:
```
X-Product-Signature: hmac_sha256(body, HUB_SIGNING_KEY_<PRODUCT_SLUG_UPPER>)
Content-Type: application/json
```
| Endpoint | Scopo | Chiamato da |
|----------|-------|-------------|
| `POST /api/license/activate` | Prima attivazione dopo install | `install-<slug>.sh` |
| `POST /api/license/validate` | Heartbeat periodico (24h default, 1h se anomalia) | cron istanza |
| `POST /api/instances/register` | Registrazione finale istanza | `install-<slug>.sh` |
| `POST /api/tenants/report` | Sync tenant create/update/archive | istanza, on-change |
| `GET /api/products/:slug/version` | Ultima versione disponibile | `update-<slug>.sh` |
Payload: identici alla spec TRPG §6 (validate/activate/register/report). Campi obbligatori aggiuntivi in **tutti** i body:
- `product_slug` — sempre, anche dove la spec TRPG lo omette implicitamente
- `license_key`**sempre** (v1.0.1 clarification). Serve al middleware HMAC per lookup di `hub_signing_key` prima della verifica firma. Include `tenants/report` che nella spec origine non lo listava esplicitamente.
**Eccezione**: `POST /api/license/activate` non porta `X-Product-Signature` (primo handshake, la chiave non esiste ancora) ma deve comunque includere `license_key` per il match iniziale.
### 3.2 Endpoint istanza (AgileHub → Istanza)
Ogni prodotto della suite **deve** esporre:
| Endpoint | Scopo | Auth |
|----------|-------|------|
| `POST /api/auth/admin/tenants/create` | Onboarding tenant da hub | Bearer JWT service + `X-Hub-Signature` |
| `POST /api/auth/admin/tenants/:id/suspend` | Sospensione tenant | idem |
| `POST /api/auth/admin/tenants/:id/resume` | Riattivazione tenant | idem |
| `GET /api/auth/admin/health` | Health check completo per hub | API key service |
**Shape risposta**: identica alla spec TRPG §5.2. Ogni prodotto implementa il proprio endpoint ma lo shape è vincolante.
### 3.3 Installer script non-interattivo (obbligatorio per prodotti orchestrati)
Ogni prodotto della suite che vuole supportare provisioning orchestrato da AgileHub **deve** fornire uno script:
```
install-<slug>.sh --non-interactive --json-output \
--slug=... --domain=... --client-name=... --admin-email=... --admin-name=... \
--license-key=... --hub-url=https://agilehub.agile.software \
--<provider-key-1>=... --<provider-key-2>=... \
[--smtp-host=... ...] [--force-reinstall]
```
**Exit codes standard** (identici per tutti i prodotti):
| Codice | Significato |
|--------|-------------|
| 0 | Success |
| 10 | Preflight failed (docker, RAM, disk, porte) |
| 20 | Secret generation failed |
| 30 | Hub activation failed (license invalid) |
| 40 | Docker load/up failed |
| 50 | Migration DB failed |
| 60 | Seed/admin creation failed |
| 70 | SSL setup failed |
| 80 | Verify-install failed |
| 90 | Internal error |
**JSON output**: shape identica a spec TRPG §5.1. Campo `product_slug` obbligatorio in entrambi i rami (success/failure).
---
## 4. Schema DB canonico (DB `nexus_hub`)
Recepito integralmente dallo schema TRPG §3.1 (8 tabelle):
- `hub_products`
- `hub_instances`
- `hub_instance_provisioning_logs`
- `hub_licenses`
- `hub_license_heartbeats`
- `hub_license_alerts`
- `hub_tenants`
- `hub_ssh_credentials`
**Modifiche AgileHub**:
1. `hub_products.framework` VARCHAR(32) NULL — aggiunto, indica stack prodotto (`php-vanilla`, `node-express`, `nextjs`, ecc.) utile all'orchestrator
2. `hub_instances.sso_enabled` BOOLEAN DEFAULT FALSE — aggiunto, indica se il prodotto ha SSO attivo su quell'istanza
3. `hub_tenants.sso_identity_id` INT NULL — FK logica a `sso_identities.id` (riempito quando SSO attivo)
4. Tutte le tabelle hanno `tenant_id INT NULL` per compat futuro con multi-tenancy hub (oggi NULL, riservato)
Migration canonical: `nexus-hub-ms/migrations/001-initial-schema.sql` (da creare). **Sub-approval obbligatoria** prima dell'esecuzione su produzione (maintenance mode come da CLAUDE.md).
---
## 5. Sicurezza
### 5.1 Firma HMAC
- **Algoritmo**: HMAC-SHA256
- **Chiave**: `HUB_SIGNING_KEY_<PRODUCT_SLUG_UPPER>` (es. `HUB_SIGNING_KEY_TRPG`, `HUB_SIGNING_KEY_SUSTAINAI`)
- **Generazione**: `openssl rand -hex 32`
- **Storage**: in `/etc/agilehub/vault.env` sull'host AgileHub + `.env` di ogni istanza (propagata da installer al momento di `activate`)
- **Rotazione**: ogni 6 mesi, bidirezionale coordinata
### 5.2 SSH vault
- Cifratura: AES-256-GCM
- Master key: `HUB_VAULT_KEY` in `/etc/agilehub/vault.env` (NON in DB, NON in repo git)
- Ogni decrypt logga in `hub_audit_logs` con `user_id`, `timestamp`, `source_ip`, `purpose`
- Sudo whitelist sul server target: file `/etc/sudoers.d/<slug>-installer` con binari strettamente necessari
### 5.3 JWT service-to-service
- Algoritmo: RS256
- Chiave privata AgileHub + chiave pubblica distribuita ai prodotti al momento dell'attivazione
- Claim obbligatori: `iss=agilehub`, `aud=<product_slug>`, `role=service`, `exp` ≤ 5 minuti
- Ogni prodotto verifica `iss` + `aud` + `exp` + firma
---
## 6. Fasi di rollout (coordinate cross-prodotto)
| Fase | Durata | Chi fa cosa | Bloccante per |
|------|--------|-------------|---------------|
| **Fase 1** — API licensing hub | 2-3 gg | AgileHub: `nexus-hub-ms` + migration `nexus_hub` + 5 endpoint + seed 11 prodotti | Prima installazione cliente qualsiasi prodotto |
| **Fase 1b** — Installer script prodotto | 3-5 gg/prodotto | Ogni prodotto: `install-<slug>.sh` non-interattivo + `update-<slug>.sh` + `/api/auth/admin/tenants/*` endpoint | Pilota white-label di quel prodotto |
| **Fase 2** — UI Prodotti read-only | 3-4 gg | AgileHub: sidebar "Prodotti", elenco, detail read-only, heartbeat dashboard | Visibilità pilota |
| **Fase 3** — Orchestrator + wizard | 6-8 gg | AgileHub: wizard 5-step, SSH worker, log streaming, rollback, BullMQ, encrypt vault | Onboarding cliente self-service |
| **Fase 4** — Multi-prodotto generalizzato | 2-3 gg | AgileHub: template wizard per prodotto, `installer_orchestrator_config` drive-based, billing hook | Scale-up suite |
**Pilota**: TRPG primo. Dopo pilota OK, checklist per onboarding secondo prodotto (SustainAI probabile next).
---
## 7. Obblighi prodotti della suite
Per essere "orchestrabile" da AgileHub, un prodotto **DEVE**:
1. ✅ Fornire `install-<slug>.sh --non-interactive --json-output` con exit codes e shape JSON canonici
2. ✅ Fornire `update-<slug>.sh` (Fase 3, no urgenza) con stesso pattern
3. ✅ Esporre `GET /version.json` con `{version, released_at, changelog_url}`
4. ✅ Esporre `GET /api/auth/admin/health` autenticato
5. ✅ Esporre `POST /api/auth/admin/tenants/create|:id/suspend|:id/resume` con HMAC + JWT service
6. ✅ Chiamare `POST /api/license/activate` alla fine di `install-<slug>.sh`
7. ✅ Avere un cron `license-heartbeat.sh` che chiama `POST /api/license/validate` ogni 24h (1h se anomalia)
8. ✅ Chiamare `POST /api/tenants/report` ad ogni create/update/archive consulting_firm
9. ✅ Gestire stati licenza: `valid → read_only (48h grace) → locked (168h)` con banner UI maintenance
10. ✅ Propagare `HUB_SIGNING_KEY_<SLUG>` nel `.env` istanza al momento dell'attivazione
Un prodotto che **non** rispetta questi 10 punti non può fare parte del catalogo installer AgileHub. Può restare nel menu `products.json` come link esterno (`installer_type=external_link`) finché non si adegua.
---
## 8. Domande aperte — risposte ufficiali
Le 10 domande di §11 della spec TRPG trovano risposta nel capitolo 2 di questo doc. Riepilogo:
1. **Framework hub**: Node.js/Express (non PHP).
2. **DB**: MySQL host Hetzner, DB dedicato `nexus_hub`.
3. **Job queue**: cron fino a Fase 2, BullMQ/Redis da Fase 3.
4. **UI**: Next.js 15 + React 19 (nexus-dashboard).
5. **Vault SSH**: AES-256-GCM env-based.
6. **Monitoring**: `/health` endpoint + cron watchdog esistente. Prometheus opzionale in Fase 4.
7. **Ruolo installer**: nuovo `hub_installer` separato da `hub_admin`.
8. **Email**: `email-automation-ms` esistente.
9. **Multi-prodotto**: generico da Fase 1, seed TRPG ma codice agnostic.
10. **Billing**: nessun Stripe oggi. `hub_customers` placeholder, billing in Fase 4.
---
## 9. Prossimi passi
1. **AgileHub**: scaffold `nexus-hub-ms` + migration `001-initial-schema.sql` (sub-approval richiesta)
2. **AgileHub**: distribuire questo documento a tutti i prodotti della suite via SSH Hetzner
3. **TRPG**: adeguare `install-trpg.sh` al contratto §3.3 (hostname `agilehub.agile.software`, exit codes canonici, JSON shape)
4. **TRPG**: implementare `/api/auth/admin/tenants/*` endpoint con HMAC + JWT (§3.2)
5. **Suite**: ogni team leggere questo doc e aprire ticket AgileHub con tag `installer-readiness` per dichiarare quando saranno pronti
---
## 10. Riferimenti
- Spec origine TRPG: `/var/www/trpg-agile/docs/AGILEHUB_INSTALLER_INTEGRATION_SPEC.md` (v1.0, 2026-04-19)
- Roadmap TRPG: `/var/www/trpg-agile/docs/INSTALLER_ROADMAP.md`
- White-label TRPG: `/var/www/trpg-agile/docs/INSTALLER_WHITELABEL.md`
- Licensing model TRPG: `/var/www/trpg-agile/docs/PROTEZIONE_FASE4_LICENSING.md`
- Multi-studio TRPG: `/var/www/trpg-agile/docs/MULTI_STUDIO_SPEC.md`
- SSO AgileHub: `/projects/agile-services/docs/SPEC_SSO_SINGLE_SIGN_ON.md`
- SSO fasi: `/projects/agile-services/docs/SSO_FASI_IMPLEMENTAZIONE.md`
- CLAUDE.md AgileHub: `/projects/agile-services/CLAUDE.md` (regole maintenance + agent + escalation)
---
**Firma autorità**: questo documento è **canonico** per la suite Agile Software. Modifiche richiedono consenso AgileHub + notifica a tutti i prodotti della suite.
**Versione**: 1.0 — 2026-04-19
**Prossima revisione**: dopo completamento pilota TRPG (stimata 2026-05-31).