# 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://.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_) Content-Type: application/json ``` | Endpoint | Scopo | Chiamato da | |----------|-------|-------------| | `POST /api/license/activate` | Prima attivazione dopo install | `install-.sh` | | `POST /api/license/validate` | Heartbeat periodico (24h default, 1h se anomalia) | cron istanza | | `POST /api/instances/register` | Registrazione finale istanza | `install-.sh` | | `POST /api/tenants/report` | Sync tenant create/update/archive | istanza, on-change | | `GET /api/products/:slug/version` | Ultima versione disponibile | `update-.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-.sh --non-interactive --json-output \ --slug=... --domain=... --client-name=... --admin-email=... --admin-name=... \ --license-key=... --hub-url=https://agilehub.agile.software \ --=... --=... \ [--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_` (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/-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=`, `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-.sh` non-interattivo + `update-.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-.sh --non-interactive --json-output` con exit codes e shape JSON canonici 2. ✅ Fornire `update-.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-.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_` 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).