I tre livelli di policy e la gerarchia che li lega
Le leve di governo di Actions vivono in Settings > Actions > General, nella sezione Policies. Un’organizzazione sceglie fra tre stati: consentire tutto (Allow all actions and reusable workflows), spegnere del tutto Actions, oppure la via di mezzo — Allow OWNER, and select non-OWNER, actions and reusable workflows — che apre la porta a quello che è già dentro il perimetro e chiede una lista esplicita per tutto il resto.
La cosa da fissare bene in testa è che questi tre stati esistono a tre altezze diverse: enterprise, organization e singolo repository. Non si sommano: si restringono. Una policy fissata più in alto definisce il massimo consentito più in basso, quindi l’amministratore di un repository può essere più severo dell’organizzazione ma non può mai essere più permissivo. Se l’enterprise consente solo le action interne, nessun proprietario di repository potrà riabilitare il Marketplace per conto proprio, e i controlli corrispondenti appaiono disattivati nella pagina delle impostazioni. È il modello mentale che l’esame verifica più spesso su questo dominio: davanti a uno scenario in cui un team lamenta di non poter usare una certa action, la risposta corretta quasi mai è “cambia il repository”, quasi sempre è “guarda il livello superiore”.
Vale anche la pena ricordare che disabilitare Actions non cancella nulla: i file di workflow restano nel repository, semplicemente non vengono più eseguiti.
La allow list e le sue eccezioni
Quando si sceglie l’opzione intermedia compaiono tre controlli aggiuntivi. Allow actions created by GitHub ammette le action pubblicate dalle organizzazioni actions e github. Allow Marketplace actions by verified creators ammette quelle di autori con badge verificato. Infine Allow or block specified actions and reusable workflows apre il campo di testo dove si scrive la lista vera e propria.
La sintassi va conosciuta a memoria. Per una action si indica OWNER/REPOSITORY@TAG-OR-SHA, per un reusable workflow si aggiunge il percorso completo del file, quindi OWNER/REPOSITORY/PATH/FILENAME@TAG-OR-SHA. Le voci si separano con la virgola, l’asterisco * funziona da carattere jolly su owner, nome del repository e riferimento, e il prefisso ! trasforma una voce in un blocco: una lista come space-org/*, !space-org/action@* ammette tutto quello che pubblica quell’organizzazione tranne un repository specifico.
Qui si annida la confusione tipica. La allow list non si applica alle action locali, quelle richiamate con un percorso relativo che inizia per ./, né ai reusable workflow che vivono nello stesso repository, nella stessa organizzazione o nella stessa enterprise: sono consentiti per costruzione e non vanno elencati. Se in un quesito d’esame vedete un workflow che fallisce con un errore di policy mentre chiama ./.github/actions/setup, la allow list non è la causa. Attenzione anche al riferimento: actions/checkout@v4 in lista non copre automaticamente un pin a SHA della stessa versione, perché il confronto avviene sulla stringa che scrivete nel uses.
Componenti riusabili: pubblicarli e renderli raggiungibili
Un componente scritto benissimo resta inutile se gli altri repository non lo vedono. Per action e reusable workflow ospitati in un repository privato serve un passaggio esplicito: nelle impostazioni di quel repository, sotto Settings > Actions > General, nella sezione Access, si sceglie Accessible from repositories in the ORGANIZATION-NAME organization. Da quel momento il runner riceve un token di installazione con accesso in sola lettura e durata limitata per scaricare il codice. Il rovescio della medaglia è documentato e vale la pena citarlo in sede di revisione: gli outside collaborator degli altri repository possono leggere nei log tracce del contenuto privato pur non avendo accesso diretto al repository di origine.
I reusable workflow devono stare in .github/workflows; le sottocartelle non sono supportate. Si richiamano con uses a livello di job e, all’interno della stessa organizzazione o enterprise, i segreti si passano in blocco con secrets: inherit. Una composite action è invece un pacchetto di step, senza job, e nei log compare come un unico passo — differenza che ricorre spesso nelle domande a scelta multipla.
jobs:
build:
uses: my-org/shared-workflows/.github/workflows/ci.yml@v2
secrets: inherit
I workflow templates sono la terza forma di riuso, quella pensata per far partire i team dal punto giusto. Vivono nel repository speciale .github dell’organizzazione, nella cartella workflow-templates, e ogni template è una coppia di file con lo stesso nome: il .yml del workflow e un .properties.json che ne descrive i metadati. Nel file di proprietà name e description sono obbligatori, mentre iconName, categories e filePatterns sono facoltativi e servono a farlo apparire nel posto giusto quando qualcuno crea un nuovo workflow. Un template non è un componente vivo: viene copiato nel repository di destinazione e da lì segue vita propria, al contrario del reusable workflow che resta centralizzato e si aggiorna in un punto solo.
I permessi predefiniti del GITHUB_TOKEN
Sotto Workflow permissions, sempre nella stessa pagina, si decide con quali permessi nasce il GITHUB_TOKEN in ogni job: sola lettura oppure lettura e scrittura. L’impostazione restrittiva è quella raccomandata e si applica a cascata ai repository dell’organizzazione. Il blocco permissions, dichiarato a livello di workflow o di singolo job, sovrascrive esplicitamente questo punto di partenza per quell’esecuzione, ed è la ragione per cui conviene tenere il default stretto e allargare solo dove serve.
Accanto c’è una casella separata, Allow GitHub Actions to create and approve pull requests, disattivata per le nuove organizzazioni: è un cancello a sé, che nessun blocco permissions nel workflow può aggirare. Ricordate infine che gli eventi generati con il GITHUB_TOKEN non innescano nuove esecuzioni di workflow, salvo poche eccezioni documentate — dettaglio che spiega molte pipeline apparentemente “morte” negli scenari d’esame.