Il blocco arriva prima che il segreto entri nella cronologia

Push protection è la parte preventiva di GitHub Secret Protection, il prodotto che la documentazione storica chiamava secret scanning e che oggi vive sotto l’ombrello delle GitHub Security suites (la certificazione, invece, continua a chiamarsi GitHub Advanced Security). La differenza con l’analisi retrospettiva è tutta qui: il rilevamento su codice già pubblicato produce un alert su una credenziale che è comunque uscita, mentre push protection rifiuta la scrittura, quindi non c’è nulla da revocare a valle.

Il controllo non riguarda solo git push. Copre i commit creati dall’interfaccia web, il caricamento di file nel repository, le richieste effettuate tramite REST API e le interazioni con il GitHub MCP server (queste ultime sui repository pubblici). È un punto che vale la pena fissare, perché la protezione perde senso se resta legata a un solo canale: chi aggira git scrivendo dall’editor del browser incontra lo stesso muro.

Da riga di comando lo sviluppatore riceve un messaggio remote che nomina il tipo di segreto rilevato ed elenca le posizioni: per ciascun commit compaiono l’hash e il percorso del file con la riga. Nel messaggio c’è anche un URL per procedere dall’interfaccia web. Quell’URL è personale: funziona per l’utente che ha tentato il push, mentre a chiunque altro risponde 404. Se il segreto sta in un commit più vecchio della punta del branch, rimuoverlo dal file e committare sopra non basta — serve riscrivere la storia, tipicamente con un rebase interattivo sul commit più antico interessato.

Sui repository pubblici il rilevamento dei segreti funziona gratuitamente; su repository privati e internal serve la licenza GitHub Secret Protection su GitHub Team o GitHub Enterprise Cloud. È una distinzione che l’esame ama trasformare in scenario: “un’organizzazione con repository privati vede alert senza aver acquistato nulla” è quasi sempre falso.

Tre ragioni di bypass, tre conseguenze diverse

Quando il push viene sbloccato, l’interfaccia chiede una motivazione. Le opzioni sono tre e non sono intercambiabili, perché ognuna decide che cosa succede all’alert generato:

  • It’s used in tests — il valore serve solo in ambiente di test. L’alert viene chiuso e risolto con quella motivazione.
  • It’s a false positive — la stringa non è una credenziale reale. Anche qui l’alert viene chiuso, risolto come falso positivo.
  • I’ll fix it later — il segreto è vero e verrà rimediato dopo. L’alert resta aperto, e partono le notifiche all’autore del commit e agli amministratori del repository.

Confermata la scelta, si preme Allow me to push this secret e si dispone di una finestra di tempo limitata per ritentare il push prima che la procedura vada rifatta.

Qui si concentra la confusione tipica. Molti ricordano che “il bypass chiude l’alert” e rispondono male alla domanda d’esame costruita proprio su questo: solo le due motivazioni che negano il rischio chiudono l’alert, mentre il rinvio lascia una traccia aperta e visibile. Chi verifica dopo il fatto filtra gli alert con bypassed:true per isolare esattamente i casi in cui qualcuno ha forzato la mano. A livello aggregato, la security overview riporta quante push contenenti segreti sono state bloccate, quante volte la protezione è stata aggirata e la distribuzione percentuale delle motivazioni scelte: se “I’ll fix it later” domina, il problema non è tecnico ma di processo.

Chi può sbloccare: bypass list e richieste

Per impostazione predefinita chi ha accesso in scrittura può bypassare. Con delegated bypass l’organizzazione restringe il permesso. Sul repository si va in Settings > Advanced Security, nella sezione Push protection si apre il menu Who can bypass push protection for secret scanning e si sceglie Specific roles or teams, popolando la Bypass list; un attore può essere marcato Exempt per saltare del tutto l’approvazione. A livello di organizzazione lo stesso controllo si imposta dentro una security configuration (Bypass privileges > Specific actors) e poi si applica ai repository.

Chi non è in lista non viene bloccato senza vie d’uscita: vede un’opzione per aprire una richiesta con una giustificazione, che i revisori — organization owner, security manager o titolari di un ruolo personalizzato con il permesso di gestire le richieste di bypass — approvano o negano via email. Le richieste non esaminate scadono.

Attenzione a non fondere questo meccanismo con delegated alert dismissal: il primo decide chi può pushare un segreto bloccato, il secondo decide chi può chiudere un alert già esistente e vale anche per code scanning e per gli alert delle dipendenze. Sono impostazioni separate, con revisori che possono coincidere ma non con lo stesso ambito.

Validity check: quali credenziali sono pericolose adesso

Un elenco piatto di alert dice quanti segreti sono trapelati, non quali stiano ancora aprendo porte. I validity check colmano il divario interrogando il provider del servizio: GitHub invia richieste GET verso endpoint poco invasivi, talvolta combinando il token con dati di contesto come host o URL, e riporta sull’alert uno stato fra active, inactive e unknown.

La funzionalità non è attiva per impostazione predefinita. Sul repository si abilita da Settings > Advanced Security, sotto Secret Protection, premendo Enable accanto a Validity checks e salvando; per estenderla a molti repository si usa una security configuration a livello di organizzazione o enterprise. Una volta attiva, GitHub ricontrolla periodicamente la credenziale, ed è possibile anche una verifica on demand sul singolo segreto.

L’effetto sul lavoro è concreto: gli alert si filtrano con validity:active, validity:inactive e validity:unknown, così la coda smette di essere cronologica e diventa ordinata per rischio reale. Un token active va revocato subito; uno inactive va comunque bonificato dalla cronologia, ma non è un incendio. E unknown non significa sicuro: significa che il provider non risponde o che quel tipo di segreto non supporta il controllo. Trattarlo come innocuo è l’errore che l’esame mette volentieri fra le distrattori.