Una ricerca che non accetta testo libero
L’audit log di un enterprise account aggrega le azioni di tutte le organizzazioni che possiede e si raggiunge dalle impostazioni dell’enterprise, sotto Settings e poi Audit log. La casella di ricerca somiglia a un motore di ricerca, ma non lo è: la documentazione è esplicita nel dire che non si possono cercare voci usando del testo. Se scrivi il nome di una persona o una frase, non ottieni nulla di sensato. L’unico linguaggio accettato sono i qualificatori.
Quelli che un amministratore usa ogni giorno sono action, actor, user, repo, ip, country, operation, created e hashed_token. Il qualificatore operation non accetta nomi di eventi ma classi di operazione: access, authentication, create, modify, remove, restore, transfer. Il qualificatore action, invece, si appoggia alla nomenclatura degli eventi, che segue sempre la forma categoria punto azione: business.add_admin, business.enable_saml, repo.destroy, code_scanning.alert_closed_by_user, enterprise_domain.verify. È il motivo per cui la pagina di riferimento degli eventi dell’audit log va tenuta aperta accanto alla console: senza il nome esatto dell’evento la ricerca resta vuota e sembra, erroneamente, che il fatto non sia mai accaduto.
Il dettaglio che salva le indagini è created. Per impostazione predefinita l’interfaccia mostra solo gli eventi degli ultimi tre mesi, e created è l’unico modo per uscire da quella finestra. La sintassi segue lo standard ISO 8601 nel formato anno-mese-giorno, accetta gli operatori di confronto e gli intervalli con il doppio punto, per esempio created:>=YYYY-MM-DD oppure created:YYYY-MM-DD..YYYY-MM-DD. Puoi aggiungere ora, minuti e secondi con l’offset di fuso quando ti serve la precisione al minuto. L’esame verifica proprio questo: davanti a uno scenario in cui un revisore chiede evidenze più vecchie del periodo mostrato, la risposta corretta non è “esportare tutto” né “aprire un ticket”, ma aggiungere created alla query.
Eventi Git: la risposta dipende dal canale che interroghi
Qui la documentazione si contraddice a seconda della pagina, e conviene impararla come una differenza fra canali invece che come una regola unica. Nell’interfaccia web gli eventi Git non compaiono fra i risultati della ricerca: la pagina sulla ricerca dell’audit log lo afferma senza eccezioni. Nella REST API, invece, gli eventi Git si ottengono passando il parametro include con valore git oppure all sull’endpoint dell’audit log dell’enterprise; senza quel parametro ricevi solo l’attività web. Attenzione al rovescio della medaglia: chiedendo include=git ottieni soltanto gli eventi Git, perché quelli generati dal browser o dalle API non vengono inclusi. Il valore all è l’unico che ti dà entrambi. La GraphQL API non restituisce affatto gli eventi Git: per quelli serve la REST.
Va aggiunto che la conservazione degli eventi Git è sensibilmente più breve di quella degli altri eventi dell’audit log. Se ti servono cloni, fetch e push oltre quella finestra, l’unica strada sostenibile è l’audit log streaming, che invia in continuo il flusso verso destinazioni come Amazon S3, Azure Blob Storage, Azure Event Hubs, Datadog, Google Cloud Storage o Splunk. Lo stream contiene sia gli audit event sia i Git event di tutto l’enterprise, e una impostazione separata permette di aggiungere gli API request events, limitati però agli endpoint rilevanti per la sicurezza.
Risalire a un token e a un indirizzo IP
Il campo hashed_token contiene l’hash SHA-256 del token usato per autenticarsi. Non è una curiosità crittografica: è la procedura ufficiale per tracciare un token trapelato. Se possiedi il valore del token, ne calcoli l’hash e cerchi quello.
echo -n IL_TUO_TOKEN | openssl dgst -sha256 -binary | base64
Nell’interfaccia web il valore va racchiuso fra virgolette, nella forma hashed_token:"VALORE". Via API lo stesso valore va prima codificato in URI, perché contiene caratteri come la barra e il più. Sbagliare la codifica produce zero risultati, non un errore: un’altra ricerca che sembra assolvere e invece non ha mai interrogato nulla.
Il qualificatore ip funziona solo se hai attivato Enable source IP disclosure nella scheda Settings dell’audit log. La funzione è disponibile a prescindere dal metodo di autenticazione, quindi anche su GHEC con account personali, ma lì gli indirizzi non compaiono per l’autenticazione a GitHub.com né per le attività su risorse personali: la visibilità completa la ottieni sulle risorse di proprietà dell’enterprise o delle organizzazioni, condizione naturale con Enterprise Managed Users e con GHEC con data residency, che EMU lo richiede. Su GHES il quadro cambia ancora: l’audit log vive sull’istanza insieme ai system log, con file distinti per l’autenticazione Git e per le richieste HTTP, e il comportamento può variare fra release, quindi verifica sempre la documentazione della versione che stai amministrando.
Rate limit: riconoscerli prima che diventino un ticket
Sull’uso delle API la domanda d’esame tipica non è quale sia il limite, ma come ci si accorge di averlo superato. Nella REST API ogni risposta porta gli header x-ratelimit-limit, x-ratelimit-remaining, x-ratelimit-used, x-ratelimit-reset e x-ratelimit-resource. Superato il limite primario ricevi un 403 oppure un 429 con x-ratelimit-remaining a zero. I secondary rate limit, pensati contro concorrenza eccessiva e abusi, sono diversi: quando scattano può comparire l’header retry-after, e finché non sono trascorsi quei secondi non devi ritentare. Esiste l’endpoint /rate_limit per ispezionare lo stato senza consumare il limite primario, ma la guida consiglia di leggere gli header invece di interrogarlo.
La GraphQL API ha un modello a punti, con l’oggetto rateLimit che espone limit, remaining, used e resetAt. Ed è qui la confusione più costosa: superando il limite primario in GraphQL lo stato della risposta resta 200, con l’errore nel corpo. Un client che controlla solo il codice HTTP crede di aver ricevuto dati validi. Infine, l’audit log API ha una soglia propria, più bassa di quella generale: le integrazioni che ci girano sopra vanno temporizzate, non lanciate a raffica. Per l’automazione di enterprise, preferisci una GitHub App con installation access token a un personal access token, e implementa backoff esponenziale rispettando retry-after.