Trust Score
/[locale]/trust-score affiche un seul chiffre et le détail par catégorie.
L’algorithme traite chaque ligne de signal_streams arrivée durant les
30 derniers jours.
Algorithme
- Collecter tous les signaux avec
severity NOT IN (NULL, 'info')des 30 derniers jours pour le tenant. - Severity → poids numérique :
info=0 low=1 medium=4 high=15 critical=40
- Par catégorie :
category_score = max(0, 100 - sum(weights) * scaling_factor)avecscaling_factor = 1.0. Un seul critical fait perdre -40 (100 → 60), trois criticals clampent à 0. score_total= moyenne pondérée des huit catégories, en utilisanttrust_score_weights.configcomme poids.
Huit catégories
| Key | Poids défaut | Sources qui alimentent |
|---|---|---|
cves | 15 | supply_chain (Phase 4.2) |
compliance | 20 | license_check (1.8) |
identity | 15 | secrets_scan, endpoint_posture, identity_audit, auth_geo |
ai_risk | 10 | (ai_traces.pii_hits via chemin séparé) |
process_dna | 10 | clock_check, container_posture |
cert_dns | 10 | cert_scan(_internal), ct_monitor, dns_check |
backup | 10 | backup_check |
incident_response | 10 | (cycle de vie des alertes, Phase 5.1) |
Override par tenant via POST /api/v1/trust-score/weights
(admin/owner + TOTP en production).
Reproductibilité
inputs_hash = sha256(window_start.Unix || window_end.Unix || sorted [signal_id|severity|category]).
Le worker n’écrit un nouveau snapshot que lorsque inputs_hash diffère de
la ligne précédente — pas de séries temporelles vides entre les findings.
Endpoints
GET /api/v1/trust-score/currentGET /api/v1/trust-score/history?window=90d 1h..365dGET /api/v1/trust-score/category/:cat/contributors top 20 par catégorieGET /api/v1/trust-score/explain top 10 toutes catégoriesPOST /api/v1/trust-score/weights admin + TOTP-prodLa fenêtre par défaut pour history est de 90 jours ; l’API weights accepte exactement les 8 clés ci-dessus, somme > 0.
Sous le capot
- Table :
trust_score_snapshots(computed_at, tenant_id, score_total, category_scores JSONB, weights_version, inputs_hash) - Weights :
trust_score_weights(id PK, tenant_id NULLABLE, weights_version, config JSONB)— tenant_id NULL = défaut globaldefault-v1 - Calculator :
hub/api/trust_score/calculator.go— testable viaCalculator.CalculateAt(ctx, tenant, now)