Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.snakysec.com/llms.txt

Use this file to discover all available pages before exploring further.

Report Model — Schema v3.0

Spécification du format des artefacts d’audit générés par le moteur PowerShell.

Nomenclature

artifacts/audit/<framework>-<product-area>-<tenantId>-<timestamp>.json
  • <framework> : cis | scuba
  • <product-area> : entra | exchange | teams | sharepoint | defender | purview
  • <tenantId> : GUID tenant Entra
  • <timestamp> : ISO 8601 compact (20260414T213045Z)
Exemple : artifacts/audit/cis-entra-12345678-abcd-...-20260414T213045Z.json

Structure de l’artefact

{
  "schemaVersion": "3.0",
  "generatedAt": "2026-04-14T21:30:45Z",
  "runMetadata": {
    "framework": "cis",               // cis | scuba
    "frameworkVersion": "v6.0.1",     // v6.0.1 (CIS) | v1.5.0 (SCuBA)
    "productArea": "entra",
    "runnerVersion": "3.0.0",
    "authMode": "oidc-wif",           // oidc-wif | cert-x509 | secret
    "isHybrid": false                  // Test-MsspTenantHybrid
  },
  "tenant": {
    "tenantId": "<guid>",
    "tenantName": "Contoso",
    "skus": ["ENTERPRISEPREMIUM", "SPE_E5", ...]
  },
  "summary": {
    "total": 60,
    "compliant": 42,
    "finding": 8,
    "manual": 5,
    "not_applicable": 3,
    "insufficient_perms": 1,
    "not_assessed": 1,
    "error": 0
  },
  "controls": [
    {
      "id": "CIS-ENTRA-1.1.1",
      "title": "...",
      "level": 1,                     // CIS L1 | L2  —  SCuBA: absent
      "method": "automated",          // automated | manual
      "status": "compliant",          // voir taxonomie ci-dessous
      "severity": "high",             // critical | high | medium | low
      "evidence": {                   // payload brut (Graph JSON ou cmdlet output)
        "endpoint": "/policies/authorizationPolicy",
        "response": { ... },
        "apiVersion": "v1.0"          // v1.0 | beta (quand renseigné par le contrôle)
      },
      "check": {                      // condition évaluée
        "property": "allowedToSignUpEmailBasedSubscriptions",
        "operator": "eq",
        "expected": false,
        "observed": true
      },
      "remediation": {
        "instructions": "...",
        "graphSetUrl": "https://...",
        "portalUrl": "https://..."
      },
      "mappings": {
        "cis": "CIS-ENTRA-1.1.1",
        "iso27001": "A.5.15",
        "nistCsf2": "PR.AC-01"
      },
      "requiredPermissions": ["Policy.Read.All"],
      "requiredLicense": null,
      "applicability": {
        "hybridOnly": false,
        "cloudOnly": false
      },
      "manualValidation": null         // objet présent quand method=manual
    }
  ]
}

Taxonomie des statuts (v3.0 — 7 valeurs)

StatutSignificationConversion GapFinding
compliantContrôle évalué, conformeNon
findingContrôle évalué, non conformeOui (→ OPEN)
manualContrôle non automatisable — nécessite validation humaineNon (guide dans manualValidation)
not_applicableContrôle non applicable (licence manquante, hybrid-only sur cloud-only, etc.)Non
insufficient_permsPermissions Graph insuffisantes pour évaluerNon (audit log)
not_assessedÉvaluation impossible (dépendance externe, endpoint indisponible)Non
errorErreur technique (throw dans le check)Non (audit log + Sentry)

Import pipeline

platform/src/lib/import/index.ts :
  1. Télécharge l’artefact depuis GitLab (via API job artifact).
  2. Valide le schéma v3 (Zod).
  3. Upsert AuditRun avec le summary.
  4. Insère/update ControlResult par contrôle.
  5. Pour chaque status: "finding", crée un GapFinding en état OPEN (ou update si existant).
  6. Génère les alertes (score dégradé, critical finding).

Génération rapports

À partir des ControlResult + GapFinding en DB :
  • PDF (/api/v1/audits/:id/report) — Score exécutif + scores domaine + table contrôles + plan remédiation
  • Excel (/api/v1/audits/:id/report/excel) — 6 onglets (Summary, Domain Scores, Framework Mapping, All Controls, Failed Controls, Remediation Plan)
  • HTML (/api/v1/audits/:id/report/html) — Standalone (CSS/JS inline), search + filtres temps réel

Évolution schéma

  • Breaking change sur le schéma → incrémenter schemaVersion majeur et supporter parallèlement l’ancien dans l’import pipeline pendant ≥ 1 release.
  • Nouveau champ optionnel → conserver schemaVersion 3.x.