Tre livelli in cui una decisione diventa vincolante
Una scelta di sicurezza resta negoziabile finché vive nelle impostazioni del singolo repository. Diventa policy quando la scrivi in un livello che il repository non controlla, e i livelli sono tre, con compiti diversi.
La security configuration è una raccolta di interruttori di abilitazione per le funzionalità delle GitHub Security suites — GitHub Secret Protection, GitHub Code Security e la parte di supply chain con dependency graph e Dependabot — applicabile ai repository di un’organizzazione. Puoi partire dalla GitHub-recommended configuration o crearne una personalizzata; al livello di enterprise la distribuisci con Apply to, scegliendo All repositories oppure All repositories without configurations, e puoi farla applicare in automatico ai repository nuovi in base alla visibilità. Due dettagli che vale la pena fissare: la configuration raggiunge anche i repository archiviati, perché alcune funzionalità continuano a girarci sopra, e un repository trasferito dentro l’organizzazione non eredita nulla, va configurato a mano.
I global settings dell’organizzazione sono un’altra leva. La configuration dice se una funzionalità è accesa su un repository; i global settings dicono come si comporta ovunque. Vivono sotto Settings > Advanced Security > Global settings e ospitano i custom patterns di Secret Protection, le auto-triage rules di Dependabot, i grouped security updates, i model pack di CodeQL e Copilot Autofix. La documentazione consiglia di usare le due leve insieme, non in alternativa.
Il terzo livello sono i rulesets, che agiscono sulla pull request e non sul repository. La merge protection basata su ruleset blocca il merge quando un required tool trova un alert di una severità definita nel ruleset, quando la sua analisi è ancora in corso, oppure quando quel tool non è configurato nel repository. Non è un required status check, e non si applica ai merge queue group né alle pull request di Dependabot analizzate da default setup.
Enforcement, e dove si rompe davvero
Applicare una configuration lascia comunque libero l’amministratore del repository di spegnere ciò che hai acceso. L’enforcement chiude quella porta: con una configuration enforced gli amministratori del repository non possono cambiare lo stato di abilitazione delle funzionalità governate dalla configuration. Le funzionalità che la configuration lascia not set, invece, restano libere: l’enforcement copre solo ciò che hai deciso esplicitamente.
Il punto più insidioso riguarda chi automatizza. Se qualcuno prova a modificare via REST API uno stato bloccato, la doc avverte che “the API call will appear to succeed, but no enablement statuses will change”. Nessun errore, nessun 403: uno script di remediation può quindi riportare mille volte “fatto” senza aver cambiato nulla.
Poi ci sono i casi documentati in cui l’enforcement non si applica del tutto. Il primo è il classico da esame: GitHub Actions inizialmente abilitato sul repository e poi disabilitato nel repository. Il secondo è quando le Actions richieste dalle configurazioni di code scanning non sono disponibili nel repository. Il terzo è quando cambia la definizione di quali linguaggi non devono essere analizzati con il default setup di code scanning. Morale: l’enforcement governa le impostazioni di sicurezza, non le dipendenze operative su cui quelle impostazioni poggiano.
Per accorgersene esiste lo stato della configuration su ciascun repository: attached, attaching, updating, enforced, removed, removed_by_enterprise, failed, detached. Lo stato removed segnala che una modifica a livello di repository è entrata in conflitto con la configuration, failed che la configuration non è riuscita ad agganciarsi. Un audit serio parte da qui, non dal numero di repository a cui hai cliccato Apply.
Bypassare un blocco non è chiudere un alert
Sono due deleghe distinte e l’esame le mette volentieri nella stessa domanda.
Il delegated bypass riguarda la push protection di Secret Protection: chi può pubblicare un commit che contiene un segreto bloccato. Organization owner, security manager e gli attori inseriti nella bypass list passano direttamente; tutti gli altri aprono una bypass request che qualcuno deve approvare, e che non resta aperta per sempre. Accanto al bypass esistono le exemptions, pensate per l’automazione fidata: saltano del tutto la push protection, e la documentazione invita a concederle con cautela perché possono portare a segreti esposti. Per distribuire il lavoro di revisione senza regalare privilegi si usa un custom organization role con il permesso “review and manage secret scanning bypass requests”.
Il delegated alert dismissal riguarda invece la chiusura degli alert — code scanning, secret scanning e Dependabot. Quando è attivo, chi ha accesso in scrittura al repository deve richiedere la chiusura; organization owner e security manager approvano o negano, ricevono notifica via email e possono chiudere direttamente. Il primo controllo protegge il codice in ingresso, il secondo protegge il registro dei rischi: confonderli è l’errore più comune su questo dominio.
Le viste seguono la stessa logica. In security overview, owner e security manager vedono tutti i repository in tutte le viste e sono gli unici ad accedere alla vista Assessments; l’amministratore di repository vede i propri; chi ha accesso in scrittura vede solo i dati di code scanning e Dependabot dei repository su cui lavora; chi ha accesso in lettura o triage non vede nulla.
Workflow CodeQL approvati e governance su scala
Il default setup di code scanning si accende per tutti i repository idonei dell’organizzazione, e con una configuration lo si può filtrare sui repository che interessano. Per i repository non idonei la doc indirizza all’advanced setup, distribuito con uno script di bulk configuration a partire da un workflow creato e testato prima — GitHub cita come esempi la GitHub CLI extension gh-add-files, ghas-cli in Python, ghas-enablement in NodeJS e Create-ActionsPRs in PowerShell. In ogni caso GitHub Actions deve essere abilitato per l’organizzazione o l’enterprise.
Per imporre una configurazione CodeQL approvata senza mantenere un workflow per repository esiste la repository property github-codeql-config-file, che punta al percorso locale o remoto di un file di configurazione. Il file viene unito a quello che il default setup genera da solo, vale sia per default che per advanced setup, e un input config-file esplicito nella action codeql-action/init ha la precedenza.
name: "Configurazione CodeQL approvata"
disable-default-queries: false
queries:
- uses: security-extended
paths-ignore:
- vendor
- '**/*.test.js'
La verifica, infine, va automatizzata quanto l’applicazione: gli stati della configuration per trovare i repository failed o removed, la coverage view per la copertura reale, l’Export CSV di security overview che esporta i dati corrispondenti ai filtri applicati. Ricorda anche il confine di licenza: su repository pubblici molte funzionalità sono gratuite, mentre su privati e internal cose come custom patterns, delegated bypass, auto-triage rules e la stessa security overview richiedono Secret Protection o Code Security.