<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>DevOps on My personal blog</title>
        <link>https://www.matteobianchi.eu/categories/devops/</link>
        <description>Recent content in DevOps on My personal blog</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>en</language>
        <lastBuildDate>Tue, 29 Sep 2026 09:00:00 +0200</lastBuildDate><atom:link href="https://www.matteobianchi.eu/categories/devops/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>DevSecOps in pratica: la serie</title>
        <link>https://www.matteobianchi.eu/p/devsecops-la-serie/</link>
        <pubDate>Tue, 10 Mar 2026 09:00:00 +0200</pubDate>
        
        <guid>https://www.matteobianchi.eu/p/devsecops-la-serie/</guid>
        <description>&lt;img src="https://www.matteobianchi.eu/p/devsecops-la-serie/cover.png" alt="Featured image of post DevSecOps in pratica: la serie" /&gt;&lt;h2 id=&#34;perché-questa-serie&#34;&gt;Perché questa serie
&lt;/h2&gt;&lt;p&gt;Per anni la sicurezza è arrivata alla fine: un audit a ridosso del rilascio, una lista di
vulnerabilità da sistemare &lt;em&gt;dopo&lt;/em&gt; che il codice era già scritto, un cancello che rallentava la
consegna senza renderla più sicura. &lt;strong&gt;DevSecOps&lt;/strong&gt; ribalta questo ordine: la sicurezza entra in ogni
fase del ciclo di vita, automatizzata, misurata e trattata come responsabilità di tutti — non come
il compito di un team separato alla fine della catena.&lt;/p&gt;
&lt;p&gt;Questa serie è un percorso pratico in &lt;strong&gt;30 capitoli&lt;/strong&gt;. Non un elenco di strumenti, ma un modo di
pensare: ogni controllo il più presto possibile (&lt;em&gt;shift left&lt;/em&gt;), ogni artefatto verificabile, ogni
decisione di rischio esplicita. Gli strumenti cambiano ogni due anni; i principi no.&lt;/p&gt;
&lt;h2 id=&#34;come-è-organizzata&#34;&gt;Come è organizzata
&lt;/h2&gt;&lt;pre class=&#34;mermaid&#34;&gt;
  flowchart LR
    C[Cultura&amp;lt;br/&amp;gt;shift-left] --&amp;gt; D[Design&amp;lt;br/&amp;gt;threat model]
    D --&amp;gt; B[Build&amp;lt;br/&amp;gt;SAST/SCA/segreti]
    B --&amp;gt; A[Artefatti&amp;lt;br/&amp;gt;SBOM/firma/SLSA]
    A --&amp;gt; P[Deploy&amp;lt;br/&amp;gt;pipeline/IaC/policy]
    P --&amp;gt; R[Runtime&amp;lt;br/&amp;gt;K8s/admission/Falco]
    R --&amp;gt; O[Operate&amp;lt;br/&amp;gt;vuln mgmt/IR/metriche]
    O --&amp;gt; C
    style C fill:#fde2e4,stroke:#e63946
    style R fill:#e8f0fe,stroke:#4361ee
&lt;/pre&gt;

&lt;p&gt;Il filo conduttore segue il viaggio del codice: nasce da una &lt;strong&gt;cultura&lt;/strong&gt; e da un &lt;strong&gt;design&lt;/strong&gt; sicuri,
viene &lt;strong&gt;costruito&lt;/strong&gt; con controlli automatici, impacchettato in &lt;strong&gt;artefatti&lt;/strong&gt; verificabili, portato in
produzione da una &lt;strong&gt;pipeline&lt;/strong&gt; governata, difeso a &lt;strong&gt;runtime&lt;/strong&gt; e &lt;strong&gt;operato&lt;/strong&gt; con misure e risposta
agli incidenti. Poi si ricomincia: DevSecOps è un ciclo, non una linea.&lt;/p&gt;
&lt;h2 id=&#34;i-capitoli&#34;&gt;I capitoli
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Fondamenta&lt;/strong&gt; — Cos&amp;rsquo;è DevSecOps, il Secure SDLC, il threat modeling nel ciclo, la gestione dei
segreti.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Build&lt;/strong&gt; — SAST, SCA e dipendenze, DAST, IAST/RASP, fuzzing: trovare i difetti mentre si scrive.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Supply chain&lt;/strong&gt; — SBOM, SLSA, firma degli artefatti: fidarsi solo di ciò che si può verificare.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pipeline e deploy&lt;/strong&gt; — Sicurezza della CI/CD, IaC security, policy as code nella pipeline.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Runtime&lt;/strong&gt; — Sicurezza delle immagini, hardening di Kubernetes, admission control, runtime
security, segreti e identità dei workload.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Operate&lt;/strong&gt; — Patch management, security gates, vulnerability management, logging e detection,
incident response, compliance as code, metriche e cultura.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;a-chi-si-rivolge&#34;&gt;A chi si rivolge
&lt;/h2&gt;&lt;p&gt;A chi scrive codice e vuole capire dove la sicurezza tocca il suo lavoro; a chi gestisce pipeline e
cluster e deve renderli difendibili; a chi guida team e vuole misurare il rischio invece di
subirlo. Diamo per note le basi di Git, container e CI/CD; tutto il resto lo costruiamo insieme.&lt;/p&gt;
&lt;p&gt;DevSecOps non rallenta la consegna: la rende &lt;em&gt;ripetibile&lt;/em&gt;. Un rilascio sicuro e automatizzato è più
veloce di un audit manuale fatto nel panico la sera prima. Partiamo dal perché, nel primo capitolo.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Cultura e security champions: ciò che regge tutto</title>
        <link>https://www.matteobianchi.eu/p/cultura-security-champions/</link>
        <pubDate>Tue, 29 Sep 2026 09:00:00 +0200</pubDate>
        
        <guid>https://www.matteobianchi.eu/p/cultura-security-champions/</guid>
        <description>&lt;img src="https://www.matteobianchi.eu/p/cultura-security-champions/cover.png" alt="Featured image of post Cultura e security champions: ciò che regge tutto" /&gt;&lt;h2 id=&#34;perché-conta&#34;&gt;Perché conta
&lt;/h2&gt;&lt;p&gt;Abbiamo attraversato trenta capitoli di strumenti, controlli e metriche. Ma tutto quanto —
&lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/sast-analisi-statica/&#34; &gt;SAST&lt;/a&gt;, &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/firma-artefatti-sigstore/&#34; &gt;firma&lt;/a&gt;,
&lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/security-gates/&#34; &gt;gate&lt;/a&gt;, &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/metriche-devsecops/&#34; &gt;metriche&lt;/a&gt; —
poggia su un presupposto che nessuno strumento può fornire: che le persone &lt;em&gt;vogliano&lt;/em&gt; la sicurezza. Un
team che vive i controlli come un nemico li aggirerà, non importa quanto siano buoni. La cultura è
l&amp;rsquo;infrastruttura invisibile su cui sta tutto il resto, ed è il motivo per cui questo è l&amp;rsquo;ultimo
capitolo e non il primo: ora si capisce &lt;em&gt;cosa&lt;/em&gt; la cultura deve sostenere.&lt;/p&gt;
&lt;h2 id=&#34;il-principio-sicurezza-come-abilitatore&#34;&gt;Il principio: sicurezza come abilitatore
&lt;/h2&gt;&lt;pre class=&#34;mermaid&#34;&gt;
  flowchart LR
    A[Sicurezza come&amp;lt;br/&amp;gt;freno / cancello] --&amp;gt; A1[Team la aggira&amp;lt;br/&amp;gt;→ attrito, segreti, buchi]
    B[Sicurezza come&amp;lt;br/&amp;gt;abilitatore / guardrail] --&amp;gt; B1[Team la adotta&amp;lt;br/&amp;gt;→ consegna veloce E sicura]
    style A1 fill:#fde2e4,stroke:#e63946
    style B1 fill:#e8f0fe,stroke:#4361ee
&lt;/pre&gt;

&lt;p&gt;Il cambio di cornice è tutto. Un controllo vissuto come &lt;em&gt;freno&lt;/em&gt; genera attrito, e l&amp;rsquo;attrito genera
aggiramenti: il gate disattivato, il segreto committato &amp;ldquo;per fare in fretta&amp;rdquo;, l&amp;rsquo;eccezione che diventa
regola. Un controllo vissuto come &lt;em&gt;guardrail&lt;/em&gt; — qualcosa che ti fa andare veloce &lt;em&gt;perché&lt;/em&gt; ti tiene in
carreggiata — viene adottato. Il lavoro della cultura è spostare la percezione dal primo al secondo: la
sicurezza che dà strumenti, default sicuri e feedback utile, non che dice solo &amp;ldquo;no&amp;rdquo;.&lt;/p&gt;
&lt;h2 id=&#34;i-security-champions&#34;&gt;I security champions
&lt;/h2&gt;&lt;p&gt;Il team di sicurezza non può essere ovunque, e non deve: ricreerebbe il silo che DevSecOps vuole
abolire. Il modello che scala è il &lt;strong&gt;security champion&lt;/strong&gt;: una persona &lt;em&gt;dentro&lt;/em&gt; ogni team di sviluppo,
non necessariamente un esperto, che fa da ponte.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Porta il contesto di sicurezza nel team&lt;/strong&gt;: partecipa alle decisioni di design, solleva la domanda
di &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/threat-modeling-nel-ciclo/&#34; &gt;threat modeling&lt;/a&gt; al momento giusto.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Porta il contesto del team alla sicurezza&lt;/strong&gt;: spiega perché un certo gate è impraticabile, dove i
controlli creano attrito inutile.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Diffonde la conoscenza&lt;/strong&gt;: è il primo punto di contatto, moltiplica la competenza senza
moltiplicare il team di sicurezza.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I champion funzionano se sono &lt;em&gt;supportati&lt;/em&gt; — tempo dedicato, formazione, riconoscimento — non se è un
titolo in più su chi è già oberato.&lt;/p&gt;
&lt;h2 id=&#34;default-sicuri-la-cultura-nel-codice&#34;&gt;Default sicuri: la cultura nel codice
&lt;/h2&gt;&lt;p&gt;La cultura più efficace è quella che non richiede eroismo quotidiano. Rendere la &lt;em&gt;via sicura&lt;/em&gt; anche la
&lt;em&gt;via facile&lt;/em&gt;: template di pipeline che arrivano già con i controlli, immagini base
&lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/container-image-security/&#34; &gt;approvate e minimali&lt;/a&gt;, librerie interne sicure per
default, scaffold di progetto che nascono &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/kubernetes-hardening/&#34; &gt;hardened&lt;/a&gt;. Così
lo sviluppatore fa la cosa sicura senza doverci pensare, e la cosa insicura richiede uno sforzo
consapevole. È cultura cristallizzata in strumenti.&lt;/p&gt;
&lt;h2 id=&#34;blameless-come-norma&#34;&gt;Blameless come norma
&lt;/h2&gt;&lt;p&gt;L&amp;rsquo;abbiamo visto per gli &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/incident-response-devsecops/&#34; &gt;incidenti&lt;/a&gt; e per le
&lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/metriche-devsecops/&#34; &gt;metriche&lt;/a&gt;: la colpa nasconde i problemi, l&amp;rsquo;apertura li
risolve. Una cultura in cui segnalare un errore o un dubbio di sicurezza è sicuro — anzi, premiato — è
una cultura che &lt;em&gt;vede&lt;/em&gt; i suoi rischi. Una in cui ammettere un errore costa è una cultura cieca per
scelta. Questo non è un dettaglio soft: è ciò che determina se la tua detection e la tua IR hanno
materiale su cui lavorare o se tutto viene insabbiato fino all&amp;rsquo;incidente grande.&lt;/p&gt;
&lt;h2 id=&#34;chiusura-della-serie&#34;&gt;Chiusura della serie
&lt;/h2&gt;&lt;p&gt;Trenta capitoli, un unico filo: portare la sicurezza &lt;em&gt;dentro&lt;/em&gt; il ciclo di sviluppo invece di
appiccicarla alla fine. Dal &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/cos-e-devsecops/&#34; &gt;perché&lt;/a&gt; dello shift-left, ai
controlli di build, alla &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/supply-chain-slsa/&#34; &gt;supply chain&lt;/a&gt;, alla pipeline, al
runtime di Kubernetes, all&amp;rsquo;operare nel tempo. Gli strumenti che abbiamo nominato cambieranno — tra due
anni alcuni avranno nomi diversi. I principi no: trovare presto costa meno, fidarsi solo di ciò che si
verifica, difendere in profondità, misurare senza ingannarsi, e — soprattutto — fare della sicurezza
una proprietà del &lt;em&gt;come lavoriamo&lt;/em&gt;, non un reparto alla fine della catena. Quella proprietà non si
compra: si costruisce, una cultura e un default sicuro alla volta.&lt;/p&gt;


&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Domanda:&lt;/strong&gt; &#34;cambiare la cultura&#34; suona come la raccomandazione vaga con cui si chiudono tutti gli articoli di sicurezza. Concretamente, da dove parte un team che oggi vive la sicurezza come un freno?&lt;/summary&gt;
&lt;p&gt;Hai ragione a diffidare: &#34;cambiate cultura&#34; come imperativo astratto è inutile, perché la cultura non si
decreta, si costruisce con atti concreti e ripetuti che cambiano l&#39;esperienza quotidiana delle persone.
Ecco da dove si parte, in ordine di impatto. Primo e più potente: togliere attrito prima di aggiungere
controlli. Se oggi la sicurezza è vissuta come freno, quasi sempre è perché &lt;em&gt;lo è&lt;/em&gt; — gate rumorosi,
falsi positivi, processi manuali. Prima di chiedere alle persone di &#34;apprezzare la sicurezza&#34;, rendi i
controlli esistenti meno dolorosi: taratura dei falsi positivi, feedback nella pull request invece che in
un report, default sicuri che non richiedono lavoro. Un solo controllo che passa da ostacolo a invisibile
cambia la percezione più di qualsiasi predica. Secondo: rendi la via sicura la via facile, concretamente —
un template di pipeline con i controlli già dentro, un&#39;immagine base approvata, uno scaffold di progetto
che nasce hardened. Non chiedere allo sviluppatore di ricordarsi di essere sicuro, fai sì che lo sia per
default e che l&#39;insicurezza richieda uno sforzo. Terzo: nomina e sostieni un security champion per team,
con tempo vero allocato (non &#34;in più del lavoro vero&#34;) e riconoscimento visibile — è la persona che
traduce in entrambe le direzioni ed è il tuo moltiplicatore. Quarto: scegli una vittoria dimostrabile e
raccontala. Un CVE critico patchato in ore grazie alla SBOM invece che in settimane; un incidente contenuto
in fretta grazie alla detection; un deploy sicuro che è stato anche &lt;em&gt;più veloce&lt;/em&gt;. Le persone cambiano
abitudine quando vedono il beneficio, non quando lo sentono affermare. Quinto: rendi il blameless reale —
la prossima volta che qualcuno segnala un proprio errore, la reazione pubblica dev&#39;essere gratitudine e un
fix di sistema, non una colpa; una sola reazione sbagliata qui azzera anni di parole. Nota cosa hanno in
comune questi punti: nessuno è &#34;indire una campagna sulla cultura&#34;. Sono atti tecnici e gestionali
concreti — meno attrito, default sicuri, persone supportate, prove visibili, sicurezza nel segnalare — la
cui &lt;em&gt;somma&lt;/em&gt;, nel tempo, è ciò che chiamiamo cultura. La cultura non è il punto di partenza da cui
discendono le pratiche; è il risultato che emerge da pratiche ripetute che rendono la sicurezza, giorno
dopo giorno, la scelta facile e conveniente. Si parte dagli atti, e la cultura segue.&lt;/p&gt;
&lt;/details&gt;


&lt;h2 id=&#34;conclusione&#34;&gt;Conclusione
&lt;/h2&gt;&lt;p&gt;La cultura è ciò che regge tutto il resto: sicurezza come abilitatore e non come freno, security
champions che moltiplicano la competenza nei team, default sicuri che fanno della via giusta la via
facile, blameless come norma che rende visibili i rischi. Gli strumenti dei trenta capitoli funzionano
solo dentro questa cornice — e la cornice si costruisce con atti concreti, non con proclami. Qui la
serie DevSecOps si chiude: la sicurezza migliore non è quella che si aggiunge alla fine, è quella che
nessuno nota più perché è semplicemente &lt;em&gt;come si lavora&lt;/em&gt;.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Metriche DevSecOps: misurare senza ingannarsi</title>
        <link>https://www.matteobianchi.eu/p/metriche-devsecops/</link>
        <pubDate>Tue, 22 Sep 2026 09:00:00 +0200</pubDate>
        
        <guid>https://www.matteobianchi.eu/p/metriche-devsecops/</guid>
        <description>&lt;img src="https://www.matteobianchi.eu/p/metriche-devsecops/cover.png" alt="Featured image of post Metriche DevSecOps: misurare senza ingannarsi" /&gt;&lt;h2 id=&#34;perché-conta&#34;&gt;Perché conta
&lt;/h2&gt;&lt;p&gt;Abbiamo costruito controlli lungo tutto il ciclo. Funzionano? Migliorano? Senza &lt;strong&gt;metriche&lt;/strong&gt;, la
sicurezza è opinione: chi urla più forte ottiene le risorse. Ma le metriche sbagliate sono peggio di
nessuna, perché orientano il comportamento nella direzione sbagliata con l&amp;rsquo;autorità apparente del
numero. Questo capitolo è su cosa misurare per governare DevSecOps — e sulle trappole che trasformano
una buona intenzione in un incentivo perverso.&lt;/p&gt;
&lt;h2 id=&#34;le-metriche-che-contano&#34;&gt;Le metriche che contano
&lt;/h2&gt;&lt;pre class=&#34;mermaid&#34;&gt;
  flowchart TD
    V[Velocità&amp;lt;br/&amp;gt;DORA: frequenza deploy,&amp;lt;br/&amp;gt;lead time] 
    S[Sicurezza&amp;lt;br/&amp;gt;MTTR vuln, escape rate,&amp;lt;br/&amp;gt;copertura controlli]
    V --&amp;gt;|non in conflitto| EQ[Un buon programma&amp;lt;br/&amp;gt;migliora ENTRAMBE]
    S --&amp;gt; EQ
    style EQ fill:#e8f0fe,stroke:#4361ee
&lt;/pre&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;MTTR delle vulnerabilità&lt;/strong&gt; (Mean Time To Remediate): quanto tempo passa dalla scoperta di un CVE
alla sua correzione in produzione. È la metrica regina: misura la capacità di &lt;em&gt;reagire&lt;/em&gt;, che è ciò
che conta davvero.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Escape rate&lt;/strong&gt;: quanti difetti sfuggono ai controlli e arrivano in produzione (o peggio, a un
incidente). Misura l&amp;rsquo;efficacia &lt;em&gt;reale&lt;/em&gt; della pipeline di controlli.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Copertura dei controlli&lt;/strong&gt;: quale percentuale di servizi ha SAST, SCA, scanning immagini, firma. La
sicurezza è forte quanto l&amp;rsquo;anello più scoperto.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Metriche DORA&lt;/strong&gt; (frequenza di deploy, lead time, change failure rate, tempo di ripristino): perché
la sicurezza non deve distruggere la velocità, e le due vanno lette &lt;em&gt;insieme&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;mttr-la-forma-che-conta&#34;&gt;MTTR: la forma che conta
&lt;/h2&gt;&lt;p&gt;Un MTTR medio nasconde la coda pericolosa. La media può essere buona mentre pochi CVE critici restano
aperti per mesi:&lt;/p&gt;
&lt;p&gt;$$ \text{MTTR} = \frac{1}{n}\sum_{i=1}^{n} (t_{\text{fix},i} - t_{\text{scoperta},i}) $$&lt;/p&gt;
&lt;p&gt;La media su tutti gli $n$ CVE livella i casi gravi con i banali. Meglio misurare l&amp;rsquo;MTTR &lt;em&gt;per severità&lt;/em&gt;
e guardare i &lt;strong&gt;percentili&lt;/strong&gt; (il 95° percentile dei critici), non la media: è nella coda — i pochi CVE
critici dimenticati — che vivono gli incidenti, non nel valore medio.&lt;/p&gt;
&lt;h2 id=&#34;la-metrica-tossica-vulnerabilità-trovate&#34;&gt;La metrica tossica: &amp;ldquo;vulnerabilità trovate&amp;rdquo;
&lt;/h2&gt;&lt;p&gt;Contare le vulnerabilità &lt;em&gt;trovate&lt;/em&gt; come misura di performance è un classico errore. Più cerchi, più
trovi: il numero sale quando &lt;em&gt;migliori&lt;/em&gt; la detection, e scende quando &lt;em&gt;smetti di guardare&lt;/em&gt;. Premiare
&amp;ldquo;poche vulnerabilità trovate&amp;rdquo; incentiva a cercare meno, l&amp;rsquo;esatto contrario dell&amp;rsquo;obiettivo. Conta ciò
che riguarda il &lt;em&gt;rischio gestito&lt;/em&gt; — MTTR, escape rate, copertura — non l&amp;rsquo;attività grezza.&lt;/p&gt;
&lt;h2 id=&#34;la-legge-di-goodhart&#34;&gt;La legge di Goodhart
&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;Quando una misura diventa un obiettivo, cessa di essere una buona misura.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;È il rischio di &lt;em&gt;ogni&lt;/em&gt; metrica, non di una sola. Se l&amp;rsquo;MTTR diventa il bersaglio su cui si viene
valutati, si imparerà a chiudere i ticket velocemente — magari marcando come &amp;ldquo;risolto&amp;rdquo; senza
risolvere, o declassando la severità per far quadrare i numeri. Le contromisure: usare le metriche per
&lt;em&gt;apprendere e orientare&lt;/em&gt;, non per punire; guardarne &lt;em&gt;più d&amp;rsquo;una&lt;/em&gt; insieme così barare su una peggiora
l&amp;rsquo;altra (chiudere ticket in fretta fa salire l&amp;rsquo;escape rate); e verificare sul campo che il numero
rifletta la realtà. Lo stesso principio del &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/incident-response-devsecops/&#34; &gt;postmortem blameless&lt;/a&gt;:
le metriche servono a migliorare il sistema, non a trovare colpevoli.&lt;/p&gt;
&lt;h2 id=&#34;maturità-nel-tempo&#34;&gt;Maturità, nel tempo
&lt;/h2&gt;&lt;p&gt;Oltre ai numeri operativi, un modello come &lt;strong&gt;OWASP DSOMM&lt;/strong&gt; misura la &lt;em&gt;maturità&lt;/em&gt; dei controlli nel
tempo — la stessa logica del &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/secure-sdlc/&#34; &gt;Secure SDLC&lt;/a&gt;: non &amp;ldquo;fai SAST?&amp;rdquo; ma &amp;ldquo;a
che livello, con quale copertura, con quale efficacia?&amp;rdquo;. Serve a mostrare una traiettoria di
miglioramento, che è ciò che un programma di sicurezza deve dimostrare più di qualsiasi valore
assoluto.&lt;/p&gt;


&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Domanda:&lt;/strong&gt; se ogni metrica è soggetta alla legge di Goodhart e può essere manipolata, non è meglio evitare di misurare e fidarsi del giudizio degli esperti?&lt;/summary&gt;
&lt;p&gt;No, e questa è la conclusione sbagliata da trarre da Goodhart — una trappola simmetrica a quella che
mette in guardia. &#34;Non misurare e fidarsi del giudizio&#34; suona prudente ma significa tornare esattamente al
mondo che le metriche risolvono: la sicurezza come opinione, dove le risorse vanno a chi è più
persuasivo o più allarmista, dove non sai se stai migliorando o peggiorando, dove non puoi dimostrare a
nessuno — né a te stesso — che un controllo vale il suo costo. Il giudizio degli esperti è prezioso ma non
scala, non è verificabile e non protegge da bias: due esperti onesti possono dissentire su dove sta il
rischio, e senza dati la discussione non si chiude. Goodhart non dice &#34;non misurare&#34;, dice &#34;non trasformare
una singola misura in &lt;em&gt;il&lt;/em&gt; bersaglio da ottimizzare a tutti i costi&#34;. La differenza è enorme. Le
contromisure pratiche esistono e sono quelle che un programma maturo applica: primo, misurare un
&lt;em&gt;insieme&lt;/em&gt; bilanciato di metriche che si tengono a vicenda, così barare sull&#39;una peggiora l&#39;altra —
accorciare l&#39;MTTR chiudendo ticket a vuoto fa esplodere l&#39;escape rate e il tasso di riapertura, e il trucco
emerge. Secondo, separare le metriche di &lt;em&gt;apprendimento&lt;/em&gt; (che usi per capire dove migliorare, e che
non devi mai legare a valutazioni individuali, o le corrompi) dalle metriche di &lt;em&gt;allineamento&lt;/em&gt; con
cui comunichi verso l&#39;alto. Terzo, usare le metriche come inizio di una conversazione, non come verdetto:
un numero che peggiora è una domanda (&#34;perché?&#34;), non una condanna. Quarto, validare periodicamente che il
numero rifletta la realtà con controlli a campione, red team, incidenti reali — se l&#39;escape rate dice zero
ma gli incidenti no, la metrica mente e va aggiustata. Il giudizio degli esperti rientra proprio qui: serve
a scegliere le metriche giuste, a interpretarle, a cogliere ciò che sfugge ai numeri. Non è metriche
&lt;em&gt;contro&lt;/em&gt; giudizio, è metriche &lt;em&gt;che informano&lt;/em&gt; il giudizio. Rinunciare a misurare per paura di
Goodhart è come rinunciare a guidare per paura che il tachimetro possa essere ingannato: la risposta a uno
strumento imperfetto è usarlo con criterio e affiancarne altri, non guidare a occhi chiusi.&lt;/p&gt;
&lt;/details&gt;


&lt;h2 id=&#34;conclusione&#34;&gt;Conclusione
&lt;/h2&gt;&lt;p&gt;Misurare DevSecOps significa guardare MTTR per severità e percentili, escape rate, copertura dei
controlli e metriche DORA insieme — mai &amp;ldquo;vulnerabilità trovate&amp;rdquo;, e sempre con Goodhart in mente: le
metriche orientano e insegnano, non puniscono. Ma nessuna metrica e nessuno strumento funziona se le
persone non vogliono la sicurezza. L&amp;rsquo;ultimo capitolo è quello che tiene su tutti gli altri: la cultura
e i security champions.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Compliance as code: la prova continua</title>
        <link>https://www.matteobianchi.eu/p/compliance-as-code/</link>
        <pubDate>Tue, 15 Sep 2026 09:00:00 +0200</pubDate>
        
        <guid>https://www.matteobianchi.eu/p/compliance-as-code/</guid>
        <description>&lt;img src="https://www.matteobianchi.eu/p/compliance-as-code/cover.png" alt="Featured image of post Compliance as code: la prova continua" /&gt;&lt;h2 id=&#34;perché-conta&#34;&gt;Perché conta
&lt;/h2&gt;&lt;p&gt;Dopo l&amp;rsquo;&lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/incident-response-devsecops/&#34; &gt;incident response&lt;/a&gt;, un altro tipo di
pressione della fase &lt;em&gt;operate&lt;/em&gt;: dimostrare a un revisore, un cliente o un regolatore che i controlli
esistono e funzionano. La compliance tradizionale lo fa a mano — screenshot, fogli di calcolo,
interviste — con un difetto fatale: fotografa un &lt;em&gt;istante&lt;/em&gt;. È vera il giorno dell&amp;rsquo;audit e magari falsa
il giorno dopo, quando qualcuno cambia una configurazione. La &lt;strong&gt;compliance as code&lt;/strong&gt; la rende
&lt;em&gt;continua&lt;/em&gt;: i controlli sono codice che si verifica sempre e produce evidenze da solo.&lt;/p&gt;
&lt;h2 id=&#34;point-in-time-contro-continuo&#34;&gt;Point-in-time contro continuo
&lt;/h2&gt;&lt;pre class=&#34;mermaid&#34;&gt;
  flowchart TD
    subgraph T[Tradizionale]
        A1[Audit annuale] --&amp;gt; A2[Screenshot,&amp;lt;br/&amp;gt;fogli Excel] --&amp;gt; A3[&amp;#34;Conforme&amp;lt;br/&amp;gt;...oggi&amp;#34;]
        A3 --&amp;gt; A4[Drift silenzioso&amp;lt;br/&amp;gt;fino al prossimo audit]
    end
    subgraph C[As code]
        B1[Controlli come codice] --&amp;gt; B2[Verifica continua&amp;lt;br/&amp;gt;in pipeline + runtime]
        B2 --&amp;gt; B3[Evidenze generate&amp;lt;br/&amp;gt;automaticamente]
        B3 --&amp;gt; B2
    end
    style A4 fill:#fde2e4,stroke:#e63946
    style B3 fill:#e8f0fe,stroke:#4361ee
&lt;/pre&gt;

&lt;p&gt;Il problema del modello tradizionale non è la fatica, è la &lt;em&gt;finestra&lt;/em&gt;: tra due audit l&amp;rsquo;infrastruttura
deriva e nessuno lo sa. La compliance as code chiude la finestra verificando in continuo e segnalando
la deviazione quando avviene, non un anno dopo.&lt;/p&gt;
&lt;h2 id=&#34;i-controlli-ci-sono-già&#34;&gt;I controlli ci sono già
&lt;/h2&gt;&lt;p&gt;La buona notizia: gran parte dei controlli richiesti dai framework (ISO 27001, SOC 2, PCI DSS) sono
proprio quelli costruiti in questa serie. Non serve un lavoro parallelo, serve &lt;em&gt;mappare&lt;/em&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Requisito del framework           →  Controllo tecnico già in pipeline
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;#34;gestione delle vulnerabilità&amp;#34;    →  SCA + vulnerability management + gate
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;#34;controllo degli accessi&amp;#34;         →  RBAC + least privilege + identità workload
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;#34;integrità del software&amp;#34;          →  firma Sigstore + provenienza SLSA + SBOM
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;#34;logging e monitoraggio&amp;#34;          →  audit log a prova di manomissione + detection
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Ogni controllo tecnico diventa l&amp;rsquo;evidenza di un requisito. L&amp;rsquo;audit smette di essere &amp;ldquo;trova le prove&amp;rdquo; e
diventa &amp;ldquo;interroga il sistema che le produce già&amp;rdquo;.&lt;/p&gt;
&lt;h2 id=&#34;generare-evidenze-non-raccoglierle&#34;&gt;Generare evidenze, non raccoglierle
&lt;/h2&gt;&lt;p&gt;Il salto di qualità è l&amp;rsquo;evidenza &lt;em&gt;automatica&lt;/em&gt;. Ogni volta che la pipeline firma un&amp;rsquo;immagine, verifica
una policy, blocca un gate o ruota un segreto, genera un record datato e verificabile. Questi record
&lt;em&gt;sono&lt;/em&gt; l&amp;rsquo;evidenza di conformità, prodotta come effetto collaterale del lavoro normale — non raccolta a
mano in vista dell&amp;rsquo;ispezione. Standard emergenti come &lt;strong&gt;OSCAL&lt;/strong&gt; permettono di esprimere i controlli e
la loro verifica in forma leggibile dalle macchine, così l&amp;rsquo;audit può essere in parte automatizzato.&lt;/p&gt;
&lt;h2 id=&#34;policy-as-code-di-nuovo&#34;&gt;Policy as code, di nuovo
&lt;/h2&gt;&lt;p&gt;La compliance as code è, nella pratica, &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/policy-as-code-pipeline/&#34; &gt;policy as code&lt;/a&gt;
applicata ai requisiti normativi: la regola &amp;ldquo;ogni immagine in produzione deve essere firmata&amp;rdquo; è &lt;em&gt;allo
stesso tempo&lt;/em&gt; un controllo di sicurezza e un&amp;rsquo;evidenza di conformità al requisito di integrità del
software. Un solo meccanismo serve due scopi, ed è verificato di continuo invece che attestato una
volta l&amp;rsquo;anno.&lt;/p&gt;
&lt;h2 id=&#34;il-limite-onesto-la-mappatura-resta-umana&#34;&gt;Il limite onesto: la mappatura resta umana
&lt;/h2&gt;&lt;p&gt;Lo strumento verifica i controlli; decidere &lt;em&gt;quali&lt;/em&gt; controlli soddisfano &lt;em&gt;quale&lt;/em&gt; requisito, e se la
copertura è sufficiente, resta un giudizio umano — spesso negoziato con l&amp;rsquo;auditor. La compliance as
code non elimina il revisore: gli dà evidenze migliori e continue, e sposta la conversazione da &amp;ldquo;mi
fai vedere uno screenshot?&amp;rdquo; a &amp;ldquo;interroghiamo insieme il sistema&amp;rdquo;. Riduce la fatica e il teatro, non la
responsabilità.&lt;/p&gt;


&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Domanda:&lt;/strong&gt; se trasformo la compliance in codice automatico, non rischio il &#34;teatro della conformità&#34; inverso — controlli che passano verde ma non riflettono la sicurezza reale, solo spuntati per far felice l&#39;auditor?&lt;/summary&gt;
&lt;p&gt;È il rischio giusto da tenere d&#39;occhio, perché esiste in entrambi i mondi e la compliance as code lo
sposta ma non lo elimina da sola. Il &#34;teatro della conformità&#34; — controlli spuntati che non significano
sicurezza reale — nasce quando la conformità diventa il fine invece del mezzo, e questo può succedere con
gli screenshot come con il codice. La versione as code ha però due difese che il modello manuale non ha,
e un rischio specifico da gestire. Prima difesa: la verifica continua rende molto più difficile il
teatro &lt;em&gt;temporale&lt;/em&gt;. Con gli screenshot &#34;conforme il giorno dell&#39;audit, derivato il giorno dopo&#34; è
la norma; con la verifica continua un controllo che smette di essere vero si accende rosso subito, quindi
il verde significa almeno &#34;vero adesso e ieri e l&#39;altroieri&#34;, non &#34;vero il 15 marzo alle 10&#34;. Seconda
difesa: se il controllo di conformità &lt;em&gt;è&lt;/em&gt; lo stesso controllo di sicurezza operativo — la policy
&#34;solo immagini firmate&#34; che blocca davvero i deploy — allora passarlo per finta significa disattivare la
sicurezza vera, non solo ingannare l&#39;auditor; il costo di barare diventa reale. È esattamente per questo
che vale la pena far coincidere i due, invece di avere controlli di sicurezza &#34;veri&#34; e controlli di
compliance &#34;per l&#39;audit&#34; separati. Il rischio specifico da gestire è il disallineamento tra ciò che il
controllo &lt;em&gt;misura&lt;/em&gt; e ciò che il requisito &lt;em&gt;intende&lt;/em&gt;: un check può essere verde perché misura
la cosa sbagliata o una versione svuotata del requisito — &#34;esiste una policy di password&#34; (verde) mentre
la policy permette &#34;1234&#34;. Qui la compliance as code non ti salva da sola: serve che la mappatura
requisito→controllo sia fatta con onestà e rivista, che i controlli misurino la sostanza e non la forma,
e che qualcuno — interno o auditor — sfidi periodicamente &#34;questo verde dimostra davvero ciò che il
requisito vuole?&#34;. In altre parole, l&#39;automazione elimina il teatro della &lt;em&gt;raccolta&lt;/em&gt; di prove e
della finestra temporale, ma la qualità del &lt;em&gt;significato&lt;/em&gt; dei controlli resta un giudizio umano da
presidiare. Il modo per non cadere nel teatro inverso è ancorare ogni controllo a un rischio reale che ti
interessa ridurre, non a una casella da spuntare: se il controllo esiste perché previene un attacco che
temi, il suo verde vale; se esiste solo perché un documento lo chiede, sei già nel teatro, codice o
screenshot che sia.&lt;/p&gt;
&lt;/details&gt;


&lt;h2 id=&#34;conclusione&#34;&gt;Conclusione
&lt;/h2&gt;&lt;p&gt;La compliance as code rende la conformità continua invece che istantanea: i controlli sono codice
verificato sempre, le evidenze si generano da sole come effetto del lavoro normale, e gran parte dei
requisiti è già coperta dai controlli della pipeline. È policy as code applicata ai framework, con la
mappatura che resta umana. Tutto questo — pipeline, runtime, operate, conformità — va governato e
&lt;em&gt;misurato&lt;/em&gt; per sapere se funziona e migliora. Le metriche DevSecOps sono il prossimo capitolo.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Incident response nel mondo DevSecOps</title>
        <link>https://www.matteobianchi.eu/p/incident-response-devsecops/</link>
        <pubDate>Tue, 08 Sep 2026 09:00:00 +0200</pubDate>
        
        <guid>https://www.matteobianchi.eu/p/incident-response-devsecops/</guid>
        <description>&lt;img src="https://www.matteobianchi.eu/p/incident-response-devsecops/cover.png" alt="Featured image of post Incident response nel mondo DevSecOps" /&gt;&lt;h2 id=&#34;perché-conta&#34;&gt;Perché conta
&lt;/h2&gt;&lt;p&gt;La &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/logging-detection-pipeline/&#34; &gt;detection&lt;/a&gt; scatta. E adesso? Un&amp;rsquo;allerta senza
una risposta preparata è panico in tempo reale: decisioni improvvisate, prove distrutte per sbaglio,
tempi lunghi. La &lt;strong&gt;incident response (IR)&lt;/strong&gt; è il piano che trasforma il caos in procedura. E in un
mondo DevSecOps — infrastruttura immutabile, tutto automatizzato, artefatti verificabili — la risposta
cambia forma rispetto all&amp;rsquo;IR tradizionale: si sfruttano proprio le proprietà che abbiamo costruito nei
capitoli precedenti.&lt;/p&gt;
&lt;h2 id=&#34;le-fasi-in-breve&#34;&gt;Le fasi, in breve
&lt;/h2&gt;&lt;pre class=&#34;mermaid&#34;&gt;
  flowchart LR
    PREP[Preparazione&amp;lt;br/&amp;gt;runbook, ruoli,&amp;lt;br/&amp;gt;accessi] --&amp;gt; DET[Rilevamento&amp;lt;br/&amp;gt;+ analisi]
    DET --&amp;gt; CONT[Contenimento&amp;lt;br/&amp;gt;isola]
    CONT --&amp;gt; ERAD[Eradicazione&amp;lt;br/&amp;gt;rimpiazza]
    ERAD --&amp;gt; REC[Recupero]
    REC --&amp;gt; LESS[Lezioni apprese&amp;lt;br/&amp;gt;postmortem]
    LESS -.migliora.-&amp;gt; PREP
    style CONT fill:#fde2e4,stroke:#e63946
&lt;/pre&gt;

&lt;p&gt;Il modello NIST è un ciclo: ci si &lt;em&gt;prepara&lt;/em&gt; prima, si &lt;em&gt;rileva e analizza&lt;/em&gt;, si &lt;em&gt;contiene&lt;/em&gt;, si &lt;em&gt;eradica&lt;/em&gt;,
si &lt;em&gt;recupera&lt;/em&gt;, e si imparano le &lt;em&gt;lezioni&lt;/em&gt; che migliorano la preparazione. La differenza DevSecOps sta
in come si eseguono contenimento ed eradicazione.&lt;/p&gt;
&lt;h2 id=&#34;isola-e-rimpiazza-non-riparare&#34;&gt;Isola e rimpiazza, non riparare
&lt;/h2&gt;&lt;p&gt;Nell&amp;rsquo;IR classico si &amp;ldquo;ripuliva&amp;rdquo; un server compromesso. In un&amp;rsquo;infrastruttura &lt;strong&gt;immutabile&lt;/strong&gt; è un errore:
non sai cosa l&amp;rsquo;attaccante ha toccato, quindi non puoi fidarti di nessuna pulizia. Il modello
cloud-native è diverso:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Contenimento:  isola il pod/nodo compromesso (network policy, cordon)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;               → preservalo per la forense, NON spegnerlo subito
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Eradicazione:  rimpiazza con un&amp;#39;istanza NUOVA da un artefatto PULITO e firmato
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;               → non riparare il compromesso, sostituiscilo
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Il contenimento sfrutta la &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/microsegmentazione-nello-zero-trust/&#34; &gt;microsegmentazione&lt;/a&gt;:
una network policy che taglia il pod dal resto del cluster lo ferma senza distruggere le prove.
L&amp;rsquo;eradicazione sfrutta gli artefatti &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/firma-artefatti-sigstore/&#34; &gt;firmati&lt;/a&gt; e
immutabili: si ridistribuisce una versione pulita verificabile, con la certezza di cosa contiene.&lt;/p&gt;
&lt;h2 id=&#34;la-provenienza-come-bussola-forense&#34;&gt;La provenienza come bussola forense
&lt;/h2&gt;&lt;p&gt;Durante l&amp;rsquo;analisi, le proprietà costruite prima diventano strumenti d&amp;rsquo;indagine. La
&lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/sbom-trasparenza/&#34; &gt;SBOM&lt;/a&gt; dice esattamente cosa girava nell&amp;rsquo;immagine compromessa.
La &lt;strong&gt;provenienza&lt;/strong&gt; SLSA dice da quale commit e quale build proveniva. Gli
&lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/logging-detection-pipeline/&#34; &gt;audit log&lt;/a&gt; a prova di manomissione danno la
timeline. La domanda &amp;ldquo;cosa è stato toccato?&amp;rdquo; — che senza questi dati richiede settimane — diventa una
serie di query.&lt;/p&gt;
&lt;h2 id=&#34;automazione-contenere-alla-velocità-della-macchina&#34;&gt;Automazione: contenere alla velocità della macchina
&lt;/h2&gt;&lt;p&gt;Gli attacchi automatizzati vanno più veloci di un umano. Per i casi ad alta confidenza, il
contenimento può essere &lt;strong&gt;automatico&lt;/strong&gt; (SOAR): la detection &amp;ldquo;pod che esfiltra dati&amp;rdquo; innesca da sola
l&amp;rsquo;isolamento del pod, poi avvisa gli umani. L&amp;rsquo;automazione compra i minuti che contano, con la stessa
cautela dell&amp;rsquo;enforce nella runtime security: solo su segnali affidabili, per non isolare servizi sani
a un falso positivo.&lt;/p&gt;
&lt;h2 id=&#34;il-blameless-postmortem&#34;&gt;Il blameless postmortem
&lt;/h2&gt;&lt;p&gt;La fase più trascurata e più preziosa. Dopo l&amp;rsquo;incidente, un &lt;strong&gt;postmortem senza colpevoli&lt;/strong&gt; ricostruisce
cosa è successo e &lt;em&gt;perché i controlli non l&amp;rsquo;hanno fermato&lt;/em&gt; — non chi ha sbagliato. L&amp;rsquo;output non è una
reprimenda ma azioni concrete: una regola di detection nuova, un gate più stretto, un controllo
mancante aggiunto alla pipeline. È così che l&amp;rsquo;incidente alimenta il miglioramento invece di ripetersi,
chiudendo il ciclo DevSecOps.&lt;/p&gt;


&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Domanda:&lt;/strong&gt; il &#34;blameless postmortem&#34; non è un modo per non responsabilizzare nessuno? Se nessuno paga per l&#39;errore, cosa impedisce che si ripeta?&lt;/summary&gt;
&lt;p&gt;È l&#39;obiezione classica, e si basa su un&#39;intuizione sbagliata su cosa previene la ripetizione degli
errori. L&#39;idea che la paura della colpa migliori la sicurezza è intuitiva ma smentita da decenni di
pratica nelle industrie ad alto rischio, dall&#39;aviazione alla medicina: la colpa non previene gli errori,
li &lt;em&gt;nasconde&lt;/em&gt;. Se sai che ammettere un errore ti costa, la tua reazione razionale non diventa
&#34;starò più attento&#34;, diventa &#34;non lo segnalerò, non lascerò tracce, dirò che non so come sia successo&#34;.
Il risultato è che perdi esattamente l&#39;informazione che ti serve per correggere il sistema, e l&#39;errore si
ripete — solo che ora nessuno te lo dice finché non esplode di nuovo, più in grande. &#34;Blameless&#34; non
significa &#34;nessuna responsabilità&#34;: significa separare la responsabilità &lt;em&gt;di capire e migliorare il
sistema&lt;/em&gt; (collettiva, aperta, onesta) dalla ricerca di un capro espiatorio (che distrugge l&#39;onestà
senza aggiungere sicurezza). Il postmortem blameless parte da un presupposto preciso: le persone
competenti fanno quasi sempre scelte sensate con le informazioni e gli strumenti che avevano in quel
momento. Quindi se qualcuno ha fatto un errore, la domanda produttiva non è &#34;perché quella persona è
incompetente?&#34; ma &#34;perché il sistema ha &lt;em&gt;permesso&lt;/em&gt; che quell&#39;errore facile da fare arrivasse fino
in produzione? dov&#39;era il controllo che avrebbe dovuto intercettarlo?&#34;. Questo porta ad azioni concrete
che prevengono davvero la ripetizione — un gate mancante, una detection assente, una procedura ambigua,
un valore di default pericoloso — mentre &#34;licenziamo il responsabile&#34; lascia il sistema identico e pronto
a far inciampare la prossima persona allo stesso modo. La responsabilità vera, in questo modello, è dare
seguito alle azioni del postmortem: quello sì che va tracciato e preteso. Punire l&#39;individuo è emotivamente
soddisfacente e tecnicamente inutile; correggere il sistema è il contrario, ed è l&#39;unico che riduce il
tasso di incidenti nel tempo.&lt;/p&gt;
&lt;/details&gt;


&lt;h2 id=&#34;conclusione&#34;&gt;Conclusione
&lt;/h2&gt;&lt;p&gt;L&amp;rsquo;incident response DevSecOps isola e rimpiazza invece di riparare, usa SBOM, provenienza e audit log
come bussola forense, automatizza il contenimento sui segnali affidabili e chiude con un postmortem
blameless che migliora i controlli. Il piano trasforma il panico in procedura. Molto di ciò che
abbiamo costruito — controlli, audit, procedure — deve anche &lt;em&gt;dimostrarsi&lt;/em&gt; a un revisore o a un
regolatore. Farlo senza fermare la consegna è la compliance as code, prossimo capitolo.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Logging e detection per DevSecOps</title>
        <link>https://www.matteobianchi.eu/p/logging-detection-pipeline/</link>
        <pubDate>Tue, 01 Sep 2026 09:00:00 +0200</pubDate>
        
        <guid>https://www.matteobianchi.eu/p/logging-detection-pipeline/</guid>
        <description>&lt;img src="https://www.matteobianchi.eu/p/logging-detection-pipeline/cover.png" alt="Featured image of post Logging e detection per DevSecOps" /&gt;&lt;h2 id=&#34;perché-conta&#34;&gt;Perché conta
&lt;/h2&gt;&lt;p&gt;Il &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/vulnerability-management-triage/&#34; &gt;vulnerability management&lt;/a&gt; ordina ciò che
sappiamo; la &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/runtime-security-falco/&#34; &gt;runtime security&lt;/a&gt; rileva comportamenti
anomali. Ma entrambi dipendono dal &lt;em&gt;vedere&lt;/em&gt;. Senza log, un attacco riuscito è invisibile: non sai che
è successo, non sai cosa è stato toccato, non puoi rispondere. Il logging è la memoria del sistema, e
la detection è ciò che la rende utile. Estende il tema del &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/siem-log-correlation/&#34; &gt;SIEM e della correlazione dei
log&lt;/a&gt; al mondo DevSecOps: pipeline, cluster, runtime.&lt;/p&gt;
&lt;h2 id=&#34;quali-segnali-dove&#34;&gt;Quali segnali, dove
&lt;/h2&gt;&lt;pre class=&#34;mermaid&#34;&gt;
  flowchart TD
    PIPE[Pipeline CI/CD:&amp;lt;br/&amp;gt;chi ha deployato cosa,&amp;lt;br/&amp;gt;accesso ai segreti] --&amp;gt; AGG[Aggregazione&amp;lt;br/&amp;gt;centrale]
    K8S[Audit log K8s:&amp;lt;br/&amp;gt;chiamate all&amp;#39;API,&amp;lt;br/&amp;gt;exec nei pod, RBAC] --&amp;gt; AGG
    RUN[Runtime / Falco:&amp;lt;br/&amp;gt;processi, rete, file] --&amp;gt; AGG
    APP[App:&amp;lt;br/&amp;gt;auth, errori,&amp;lt;br/&amp;gt;accessi ai dati] --&amp;gt; AGG
    AGG --&amp;gt; DET[Detection&amp;lt;br/&amp;gt;+ correlazione]
    DET --&amp;gt; ALERT[Allerte azionabili]
    style DET fill:#fde2e4,stroke:#e63946
&lt;/pre&gt;

&lt;p&gt;I quattro flussi che contano in DevSecOps:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Audit log di Kubernetes&lt;/strong&gt;: ogni chiamata all&amp;rsquo;API — chi ha creato cosa, chi ha letto quali
secret, chi ha fatto &lt;code&gt;exec&lt;/code&gt; in un pod. È la fonte primaria per investigare una compromissione del
cluster.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Log della pipeline&lt;/strong&gt;: chi ha innescato quale deploy, chi ha acceduto a quali segreti, quali
eccezioni ai gate sono state usate. La pipeline è un bersaglio: va osservata.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Eventi di runtime&lt;/strong&gt; (Falco/eBPF): i comportamenti anomali dei container.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Log applicativi&lt;/strong&gt;: autenticazioni, errori, accessi ai dati sensibili.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;a-prova-di-manomissione&#34;&gt;A prova di manomissione
&lt;/h2&gt;&lt;p&gt;Un attaccante esperto, dopo essere entrato, cancella le proprie tracce. Se i log vivono dove gira il
carico, può alterarli. Perciò i log di sicurezza vanno &lt;strong&gt;spediti fuori&lt;/strong&gt; verso un deposito append-only
e ad accesso ristretto, a cui il carico compromesso non può scrivere né cancellare. È il principio di
non-ripudio dello STRIDE: i log servono proprio quando qualcuno vuole poter dire &amp;ldquo;non sono stato io&amp;rdquo;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Log sul nodo compromesso        → l&amp;#39;attaccante li cancella → cieco
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Log spediti a store append-only → immutabili → hai la timeline dell&amp;#39;attacco
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;dal-data-lake-alla-detection&#34;&gt;Dal data lake alla detection
&lt;/h2&gt;&lt;p&gt;Raccogliere tutto e non guardarlo è il fallimento più comune: un data lake costoso che serve solo
dopo, per l&amp;rsquo;autopsia. Il valore sta nella &lt;strong&gt;detection&lt;/strong&gt;: regole che trasformano i log in allerte
&lt;em&gt;mentre&lt;/em&gt; l&amp;rsquo;attacco accade.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Basata su regole&lt;/strong&gt;: pattern di tecniche note, idealmente mappati su &lt;strong&gt;MITRE ATT&amp;amp;CK&lt;/strong&gt; (&amp;ldquo;accesso a
un secret seguito da connessione in uscita insolita&amp;rdquo;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Basata su anomalie&lt;/strong&gt;: deviazioni dal comportamento normale appreso.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Correlazione&lt;/strong&gt;: unire segnali deboli di fonti diverse in un segnale forte — un fallimento di auth
&lt;em&gt;più&lt;/em&gt; un exec nel pod &lt;em&gt;più&lt;/em&gt; una connessione a un IP sconosciuto raccontano una storia che ogni
singolo evento non racconta.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;meno-rumore-più-segnale&#34;&gt;Meno rumore, più segnale
&lt;/h2&gt;&lt;p&gt;Vale qui la legge della &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/runtime-security-falco/&#34; &gt;runtime security&lt;/a&gt;: le allerte
inutili addestrano il team a ignorarle. Una detection va &lt;em&gt;tarata&lt;/em&gt; — soppressione del noto, soglie
sensate, arricchimento con il contesto (quale servizio, quale ambiente, quale owner) — così ogni
allerta che arriva merita di essere guardata. Una detection ignorata è peggio di nessuna, perché dà
l&amp;rsquo;illusione di vedere.&lt;/p&gt;


&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Domanda:&lt;/strong&gt; con l&#39;observability che già abbiamo per il debugging (metriche, log, tracce), perché serve un flusso di logging separato &#34;di sicurezza&#34;? Non sono gli stessi dati?&lt;/summary&gt;
&lt;p&gt;Si sovrappongono in parte, ma hanno requisiti così diversi su tre assi che trattarli come un flusso
solo compromette entrambi gli scopi. Primo asse, l&#39;integrità e la fiducia. L&#39;observability per il
debugging è ottimizzata per comodità e costo: i log vivono vicino ai carichi, sono scrivibili, spesso con
ritenzione breve e accesso ampio perché servono agli sviluppatori per lavorare. I log di sicurezza hanno
il requisito opposto: devono essere a prova di manomissione, perché il loro utente avversario è proprio
chi ha compromesso il sistema e vuole cancellare le tracce. Un log di debug che l&#39;attaccante può alterare
è inutile come prova; un log di sicurezza deve vivere in uno store append-only che il carico compromesso
non può toccare. Secondo asse, il contenuto. L&#39;observability cattura ciò che serve a capire &lt;em&gt;perché il
sistema è lento o rotto&lt;/em&gt;: latenze, code, stack trace. La detection ha bisogno di eventi che il
debugging spesso non raccoglie affatto — chi ha letto quale secret, chi ha fatto exec in quale pod, quali
RBAC sono cambiati, quali eccezioni ai gate sono state usate — e che vanno registrati anche quando tutto
&#34;funziona&#34;, perché un attacco riuscito spesso non rompe nulla. Terzo asse, la ritenzione e la conformità.
Un incidente si scopre in media mesi dopo: i log di sicurezza devono sopravvivere molto più a lungo dei
log operativi, spesso per obblighi normativi, con garanzie di conservazione che l&#39;observability non ha.
Detto questo, non significa costruire due infrastrutture che si ignorano: i dati di observability sono
una &lt;em&gt;fonte&lt;/em&gt; preziosa per la detection (un picco anomalo di errori può essere un attacco), e molte
piattaforme uniscono i pipe di raccolta. Il punto è che i log di sicurezza aggiungono requisiti —
immutabilità, eventi di audit specifici, ritenzione lunga, accesso ristretto — che l&#39;observability da
sola non soddisfa. Puoi condividere la raccolta, non puoi condividere le garanzie: un data lake di debug
riusato come fonte di prova forense ti lascia scoperto esattamente quando l&#39;attaccante ha fatto il suo
lavoro.&lt;/p&gt;
&lt;/details&gt;


&lt;h2 id=&#34;conclusione&#34;&gt;Conclusione
&lt;/h2&gt;&lt;p&gt;Non puoi rispondere a ciò che non vedi: audit log del cluster, log della pipeline, eventi di runtime e
log applicativi, spediti fuori in uno store a prova di manomissione, trasformati in detection
correlate e tarate contro il rumore. Il logging è la memoria, la detection è l&amp;rsquo;allarme. Ma un allarme
senza una procedura di risposta è solo un suono nel vuoto. Cosa fare &lt;em&gt;quando&lt;/em&gt; la detection scatta è la
risposta agli incidenti, prossimo capitolo.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Vulnerability management: dal CVSS al rischio reale</title>
        <link>https://www.matteobianchi.eu/p/vulnerability-management-triage/</link>
        <pubDate>Tue, 25 Aug 2026 09:00:00 +0200</pubDate>
        
        <guid>https://www.matteobianchi.eu/p/vulnerability-management-triage/</guid>
        <description>&lt;img src="https://www.matteobianchi.eu/p/vulnerability-management-triage/cover.png" alt="Featured image of post Vulnerability management: dal CVSS al rischio reale" /&gt;&lt;h2 id=&#34;perché-conta&#34;&gt;Perché conta
&lt;/h2&gt;&lt;p&gt;Il &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/security-gates/&#34; &gt;security gate&lt;/a&gt; deve decidere cosa è &amp;ldquo;rischio alto&amp;rdquo;, e il
&lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/dependency-patch-management/&#34; &gt;patch management&lt;/a&gt; deve decidere cosa patchare
prima. Entrambi si scontrano con lo stesso muro: diecimila CVE aperti, un team con tempo finito.
Patchare tutto è impossibile; patchare a caso è pericoloso. Il &lt;strong&gt;vulnerability management&lt;/strong&gt; è la
disciplina di mettere in ordine ciò che conta — e comincia dal capire perché il punteggio che tutti
usano, da solo, inganna.&lt;/p&gt;
&lt;h2 id=&#34;perché-il-solo-cvss-inganna&#34;&gt;Perché il solo CVSS inganna
&lt;/h2&gt;&lt;p&gt;Il &lt;strong&gt;CVSS&lt;/strong&gt; misura la &lt;em&gt;gravità tecnica&lt;/em&gt; di una vulnerabilità: quanto sarebbe grave &lt;em&gt;se&lt;/em&gt; sfruttata.
Utile, ma risponde alla domanda sbagliata se usato da solo. Un CVE con CVSS 9.8 su una libreria che
non è mai esposta a input ostile, e che nessuno sta sfruttando nel mondo, è meno urgente di un CVSS
7.5 con exploit pubblico e attivo sul tuo servizio internet-facing. Ordinare la coda per solo CVSS
significa lavorare sui numeri grandi, non sui rischi reali.&lt;/p&gt;
&lt;h2 id=&#34;epss-la-probabilità-di-sfruttamento&#34;&gt;EPSS: la probabilità di sfruttamento
&lt;/h2&gt;&lt;p&gt;L&amp;rsquo;&lt;strong&gt;EPSS (Exploit Prediction Scoring System)&lt;/strong&gt; aggiunge la dimensione mancante: la &lt;em&gt;probabilità&lt;/em&gt; che
un CVE venga sfruttato nei prossimi 30 giorni, stimata da un modello su segnali reali (exploit
pubblicati, attività osservata). È un numero tra 0 e 1:&lt;/p&gt;
&lt;p&gt;$$ \text{EPSS}(cve) = P(\text{sfruttamento entro 30 giorni}) \in [0, 1] $$&lt;/p&gt;
&lt;p&gt;Il valore pratico di EPSS è che la stragrande maggioranza dei CVE ha probabilità bassissima di essere
sfruttata: filtrare per EPSS alto riduce una coda di migliaia a una manciata di voci che meritano
attenzione &lt;em&gt;ora&lt;/em&gt;.&lt;/p&gt;
&lt;h2 id=&#34;comporre-il-rischio&#34;&gt;Comporre il rischio
&lt;/h2&gt;&lt;p&gt;Nessun punteggio singolo basta. Il rischio operativo nasce dalla composizione di gravità,
probabilità ed esposizione nel &lt;em&gt;tuo&lt;/em&gt; contesto:&lt;/p&gt;
&lt;p&gt;$$ \text{Rischio} \approx \underbrace{\text{CVSS}}&lt;em&gt;{\text{se sfruttato}} \times \underbrace{\text{EPSS}}&lt;/em&gt;{\text{quanto è probabile}} \times \underbrace{E}_{\text{esposizione}} $$&lt;/p&gt;
&lt;p&gt;dove $E$ cattura il contesto che solo tu conosci: il servizio è esposto a internet? tratta dati
sensibili? la funzione vulnerabile è davvero &lt;em&gt;raggiungibile&lt;/em&gt; dal tuo codice? Una formula del genere
non è una verità esatta, è un modo per &lt;strong&gt;ordinare&lt;/strong&gt; la coda in modo difendibile invece che per numero
grezzo.&lt;/p&gt;
&lt;h2 id=&#34;il-segnale-che-batte-tutto-kev&#34;&gt;Il segnale che batte tutto: KEV
&lt;/h2&gt;&lt;p&gt;C&amp;rsquo;è una scorciatoia che precede ogni calcolo. Se un CVE è nel catalogo &lt;strong&gt;CISA KEV&lt;/strong&gt; (Known Exploited
Vulnerabilities), significa che è sfruttato &lt;em&gt;attivamente, ora, nel mondo reale&lt;/em&gt;. Questi vanno
patchati per primi, sempre, indipendentemente dal CVSS:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Ordine di priorità pratico:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  1. Nel catalogo KEV (sfruttato ORA)           → emergenza, patch immediata
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  2. EPSS alto + esposto + raggiungibile        → questa settimana
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  3. CVSS alto ma EPSS basso / non raggiungibile → finestra pianificata
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  4. Non raggiungibile, non esposto              → debito, quando capita
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;il-ciclo-non-levento&#34;&gt;Il ciclo, non l&amp;rsquo;evento
&lt;/h2&gt;&lt;p&gt;Il vulnerability management non è una scansione una tantum ma un &lt;strong&gt;ciclo&lt;/strong&gt;: scoprire (da
&lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/sca-e-dipendenze/&#34; &gt;SCA&lt;/a&gt;, &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/sbom-trasparenza/&#34; &gt;SBOM&lt;/a&gt;, scanner
runtime), prioritizzare (CVSS × EPSS × contesto, con KEV in cima), rimediare (patch o mitigazione) e
verificare che la correzione sia davvero in produzione. E ricominciare, perché ogni giorno arrivano
CVE nuovi su software che non hai toccato. L&amp;rsquo;obiettivo non è &amp;ldquo;zero vulnerabilità&amp;rdquo; — irraggiungibile —
ma tenere il rischio &lt;em&gt;noto e sotto una soglia accettabile&lt;/em&gt;, con le decisioni tracciate.&lt;/p&gt;


&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Domanda:&lt;/strong&gt; se prioritizzo con EPSS e raggiungibilità, non rischio di rimandare per sempre un CVSS 9.8 &#34;non raggiungibile&#34; che poi diventa sfruttabile dopo un mio cambio di codice?&lt;/summary&gt;
&lt;p&gt;È il rischio corretto da temere, e la risposta non è abbandonare la prioritizzazione — che è l&#39;unica
alternativa al collasso sotto diecimila CVE — ma renderla &lt;em&gt;dinamica&lt;/em&gt; e non un giudizio dato una
volta per sempre. Primo, &#34;non raggiungibile&#34; e &#34;EPSS basso&#34; non significano &#34;ignorato&#34;: significano
&#34;declassato a debito tracciato con una finestra pianificata&#34;. Il CVE resta nell&#39;inventario, resta
visibile, e viene comunque affrontato — solo dopo ciò che è sfruttato attivamente. La differenza tra
&#34;debito pianificato&#34; e &#34;dimenticato&#34; è che il primo è in una lista che qualcuno rivede. Secondo, e qui
sta il punto che sollevi: la prioritizzazione va &lt;em&gt;rivalutata di continuo&lt;/em&gt;, perché i suoi input
cambiano. L&#39;EPSS si aggiorna ogni giorno: un CVE con probabilità bassissima oggi può schizzare quando
viene pubblicato un exploit, e un buon sistema di vulnerability management ri-valuta l&#39;intera coda sui
punteggi aggiornati, così quel 9.8 &#34;dormiente&#34; risale automaticamente in cima nel momento in cui diventa
pericoloso — tipicamente prima che tu venga colpito, perché l&#39;EPSS reagisce alla comparsa dell&#39;exploit,
non all&#39;attacco. La comparsa nel catalogo KEV fa lo stesso in modo ancora più netto. Terzo, la
raggiungibilità è una proprietà del tuo codice &lt;em&gt;attuale&lt;/em&gt;, e hai ragione che un cambio può renderla
vera: per questo la raggiungibilità si ricalcola a ogni build nella SCA, non si congela. Se una pull
request inizia a chiamare la funzione prima irraggiungibile, lo stesso CVE cambia classe e il gate lo
intercetta su quella PR. Quindi il meccanismo che temi — &#34;lo rimando e mi dimentico&#34; — è esattamente ciò
che un vulnerability management fatto a ciclo impedisce: niente è giudicato una volta sola, ogni CVE è
ri-pesato quando cambiano l&#39;EPSS, il KEV o il tuo codice. La prioritizzazione non è &#34;scegliere cosa
ignorare per sempre&#34;, è &#34;scegliere l&#39;ordine, e rivedere l&#39;ordine quando il mondo cambia&#34;. L&#39;unica vera
alternativa — trattare tutti i diecimila CVE come ugualmente urgenti — garantisce che il team si bruci
sui 9.8 teorici mentre il 7.5 con exploit attivo aspetta il suo turno in fondo a una lista ordinata per
numero. Quello sì che è dimenticare ciò che conta.&lt;/p&gt;
&lt;/details&gt;


&lt;h2 id=&#34;conclusione&#34;&gt;Conclusione
&lt;/h2&gt;&lt;p&gt;Il vulnerability management mette ordine nel caos dei CVE: il CVSS misura la gravità ma inganna da
solo, l&amp;rsquo;EPSS aggiunge la probabilità di sfruttamento, il contesto aggiunge l&amp;rsquo;esposizione, e il
catalogo KEV batte ogni calcolo. È un ciclo che ri-pesa tutto quando cambia il mondo, non un giudizio
una tantum. Questo dipende dal &lt;em&gt;sapere&lt;/em&gt; cosa succede — le fonti di segnale. Portare i log e la
detection dentro la pipeline e il runtime è il prossimo capitolo.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Security gates: bloccare senza strangolare</title>
        <link>https://www.matteobianchi.eu/p/security-gates/</link>
        <pubDate>Tue, 18 Aug 2026 09:00:00 +0200</pubDate>
        
        <guid>https://www.matteobianchi.eu/p/security-gates/</guid>
        <description>&lt;img src="https://www.matteobianchi.eu/p/security-gates/cover.png" alt="Featured image of post Security gates: bloccare senza strangolare" /&gt;&lt;h2 id=&#34;perché-conta&#34;&gt;Perché conta
&lt;/h2&gt;&lt;p&gt;Tutti i controlli della serie — &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/sast-analisi-statica/&#34; &gt;SAST&lt;/a&gt;,
&lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/sca-e-dipendenze/&#34; &gt;SCA&lt;/a&gt;, &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/container-image-security/&#34; &gt;scanning immagini&lt;/a&gt;,
&lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/policy-as-code-pipeline/&#34; &gt;policy&lt;/a&gt; — a un certo punto devono decidere: &lt;em&gt;fermo o
no questa build?&lt;/em&gt; Quella decisione è il &lt;strong&gt;security gate&lt;/strong&gt;. Ed è il punto dove DevSecOps vive o muore
nella pratica: un gate progettato male non rende sicuri, rende &lt;em&gt;lenti&lt;/em&gt;, e un team rallentato trova il
modo di disattivarlo. L&amp;rsquo;obiettivo è un cancello che il team &lt;em&gt;non voglia&lt;/em&gt; aggirare.&lt;/p&gt;
&lt;h2 id=&#34;i-due-fallimenti-simmetrici&#34;&gt;I due fallimenti simmetrici
&lt;/h2&gt;&lt;pre class=&#34;mermaid&#34;&gt;
  flowchart TD
    A[Gate troppo severo&amp;lt;br/&amp;gt;blocca su tutto] --&amp;gt; A1[Team frustrato&amp;lt;br/&amp;gt;→ disattiva o ignora&amp;lt;br/&amp;gt;→ sicurezza ZERO]
    B[Gate troppo lasco&amp;lt;br/&amp;gt;non blocca mai] --&amp;gt; B1[Decorativo&amp;lt;br/&amp;gt;→ il rischio passa&amp;lt;br/&amp;gt;→ sicurezza ZERO]
    style A1 fill:#fde2e4,stroke:#e63946
    style B1 fill:#fde2e4,stroke:#e63946
&lt;/pre&gt;

&lt;p&gt;Entrambi gli estremi portano allo stesso posto: zero sicurezza effettiva. Il gate utile vive nel
mezzo, e ci sta grazie a tre principi.&lt;/p&gt;
&lt;h2 id=&#34;1-baseline-blocca-il-nuovo-non-il-vecchio&#34;&gt;1. Baseline: blocca il nuovo, non il vecchio
&lt;/h2&gt;&lt;p&gt;Un repository esistente ha un &lt;em&gt;debito&lt;/em&gt; di problemi preesistenti. Un gate che pretende di azzerarlo
prima di accettare qualsiasi commit blocca tutto il lavoro: inaccettabile. La &lt;strong&gt;baseline&lt;/strong&gt; separa il
debito dalla regressione:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Problemi esistenti (baseline)  →  tracciati, pianificati, NON bloccano
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Problemi NUOVI introdotti dalla PR  →  BLOCCANO
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;# risultato: non peggiori mai, e riduci il debito quando puoi, senza fermare tutto
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Così il gate garantisce che la situazione non peggiori a ogni commit, mentre il debito si riduce in
modo pianificato, non in un big-bang che paralizza.&lt;/p&gt;
&lt;h2 id=&#34;2-severità-e-contesto-non-conteggio&#34;&gt;2. Severità e contesto, non conteggio
&lt;/h2&gt;&lt;p&gt;Bloccare su &amp;ldquo;qualunque finding&amp;rdquo; produce rumore e aggiramento. Si blocca su ciò che conta: severità
&lt;strong&gt;alta/critica&lt;/strong&gt;, raggiungibile, su servizi esposti. La soglia va tarata sul rischio del servizio —
un servizio internet-facing che tratta dati sensibili ha un gate più stretto di un tool interno. Il
&lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/vulnerability-management-triage/&#34; &gt;vulnerability management&lt;/a&gt; dà i criteri per
decidere cosa è &amp;ldquo;alto&amp;rdquo; davvero.&lt;/p&gt;
&lt;h2 id=&#34;3-eccezioni-tracciate-non-aggiramenti-nascosti&#34;&gt;3. Eccezioni tracciate, non aggiramenti nascosti
&lt;/h2&gt;&lt;p&gt;A volte bisogna rilasciare &lt;em&gt;nonostante&lt;/em&gt; un finding: un falso positivo, un rischio accettato
consapevolmente, un&amp;rsquo;urgenza. Se l&amp;rsquo;unico modo è disattivare il gate, prima o poi resta disattivato. Il
gate maturo offre una &lt;strong&gt;via di eccezione esplicita&lt;/strong&gt;: si marca il finding come accettato, con un
responsabile, una motivazione e una scadenza, e resta &lt;em&gt;tracciato&lt;/em&gt;. La differenza tra un&amp;rsquo;eccezione
tracciata e un aggiramento nascosto è tutta: la prima è una decisione di rischio visibile e
revisionabile, la seconda è un buco che nessuno ricorda.&lt;/p&gt;
&lt;h2 id=&#34;fail-closed-o-fail-open&#34;&gt;Fail closed o fail open?
&lt;/h2&gt;&lt;p&gt;Cosa succede se il &lt;em&gt;controllo stesso&lt;/em&gt; fallisce (lo scanner va in errore, il servizio di policy è
giù)? Per i controlli di sicurezza critici, &lt;strong&gt;fail closed&lt;/strong&gt; (blocca) è il default prudente: meglio
una build ferma che un&amp;rsquo;immagine non verificata in produzione. Per i controlli informativi,
&lt;strong&gt;fail open&lt;/strong&gt; (passa con warning) evita che un problema infrastrutturale blocchi tutta la consegna.
La scelta va fatta &lt;em&gt;consapevolmente&lt;/em&gt; per ogni gate, non subita come comportamento accidentale dello
strumento.&lt;/p&gt;


&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Domanda:&lt;/strong&gt; la via di eccezione tracciata non diventa inevitabilmente la scorciatoia che tutti usano per far passare qualsiasi cosa, svuotando il gate dall&#39;interno?&lt;/summary&gt;
&lt;p&gt;Può diventarlo, ma solo se la progetti come un timbro invece che come una decisione — e la differenza
sta in quattro dettagli concreti. Primo, l&#39;eccezione deve costare &lt;em&gt;abbastanza&lt;/em&gt; da non essere la via
di minor resistenza: richiede un&#39;approvazione di qualcuno diverso da chi la chiede (il principio dei
quattro occhi), una motivazione scritta che diventa un record, non un flag silenzioso in un file. Se
accettare un rischio è più scomodo che risolverlo per i casi facili, i casi facili si risolvono. Secondo,
l&#39;eccezione deve &lt;em&gt;scadere&lt;/em&gt;: non &#34;accettato per sempre&#34; ma &#34;accettato fino al 30 del mese prossimo&#34;,
dopodiché il gate torna a bloccare. Questo impedisce al debito di eccezioni di accumularsi
silenziosamente — ogni eccezione è un impegno a tempo, non un condono. Terzo, le eccezioni devono essere
&lt;em&gt;visibili e misurate&lt;/em&gt;: un cruscotto che mostra quante eccezioni attive ci sono, su quali servizi,
chi le ha approvate, quando scadono. Nel momento in cui le eccezioni diventano un numero che qualcuno
guarda — e un trend che cresce è un segnale d&#39;allarme discusso nelle metriche di sicurezza — smettono di
essere invisibili e quindi di essere abusate. Quarto, va distinta l&#39;eccezione (rischio accettato
consapevolmente) dalla soppressione del falso positivo (il finding non è reale): la seconda migliora la
taratura dello strumento ed è sana, la prima è una decisione di rischio che va pesata. Il punto di fondo:
la via di eccezione non è una debolezza del gate, è ciò che lo rende &lt;em&gt;sostenibile&lt;/em&gt; e quindi
mantenuto. Un gate senza via di uscita viene disattivato alla prima emergenza legittima, e una volta
disattivato protegge zero. Un gate con eccezioni tracciate, approvate, a scadenza e misurate rimane
acceso, e il rischio residuo è &lt;em&gt;noto e gestito&lt;/em&gt; invece che nascosto. Preferisci cento eccezioni
che puoi contare e far scadere, o un gate spento di cui nessuno parla più?&lt;/p&gt;
&lt;/details&gt;


&lt;h2 id=&#34;conclusione&#34;&gt;Conclusione
&lt;/h2&gt;&lt;p&gt;Il security gate utile è un equilibrio: blocca il nuovo rischio alto grazie alla baseline, decide per
severità e contesto invece che per conteggio, offre eccezioni tracciate invece di aggiramenti, e
sceglie fail-closed o fail-open consapevolmente. Un gate che il team vuole tenere acceso vale più di
uno perfetto che viene disattivato. Ma &amp;ldquo;rischio alto&amp;rdquo; finora è stato un&amp;rsquo;etichetta: come si misura e si
confronta davvero una vulnerabilità contro le altre? È il vulnerability management, prossimo capitolo.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Patch e dipendenze: il debito che matura</title>
        <link>https://www.matteobianchi.eu/p/dependency-patch-management/</link>
        <pubDate>Tue, 11 Aug 2026 09:00:00 +0200</pubDate>
        
        <guid>https://www.matteobianchi.eu/p/dependency-patch-management/</guid>
        <description>&lt;img src="https://www.matteobianchi.eu/p/dependency-patch-management/cover.png" alt="Featured image of post Patch e dipendenze: il debito che matura" /&gt;&lt;h2 id=&#34;perché-conta&#34;&gt;Perché conta
&lt;/h2&gt;&lt;p&gt;La &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/sca-e-dipendenze/&#34; &gt;SCA&lt;/a&gt; e la &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/sbom-trasparenza/&#34; &gt;SBOM&lt;/a&gt;
dicono &lt;em&gt;cosa&lt;/em&gt; è vulnerabile. Ma trovare non è correggere, e qui comincia il lavoro vero della fase
&lt;em&gt;operate&lt;/em&gt;: un flusso infinito di CVE su software già in produzione. Le dipendenze non aggiornate sono,
anno dopo anno, tra i vettori d&amp;rsquo;ingresso più sfruttati in assoluto — non per sofisticazione, ma per
pigrizia collettiva. Il problema non è tecnico, è di &lt;em&gt;sostenibilità del flusso&lt;/em&gt;.&lt;/p&gt;
&lt;h2 id=&#34;il-debito-che-matura-da-solo&#34;&gt;Il debito che matura da solo
&lt;/h2&gt;&lt;p&gt;Un codice fermo non è un codice sicuro: le vulnerabilità arrivano &lt;em&gt;a lui&lt;/em&gt;, non da lui.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Giorno del rilascio:   0 CVE noti nelle dipendenze
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;3 mesi dopo:           3 CVE scoperti (tu non hai toccato nulla)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;12 mesi dopo:          decine di CVE, e il salto di versione è ormai enorme
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;→ &amp;#34;non aggiorniamo per non rompere&amp;#34; → il costo di aggiornare cresce ogni mese
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Il paradosso: più rimandi, più l&amp;rsquo;aggiornamento diventa rischioso (tre major in un colpo), e più
rimandi ancora. Si esce solo con aggiornamenti &lt;strong&gt;piccoli e frequenti&lt;/strong&gt;, resi indolori
dall&amp;rsquo;automazione.&lt;/p&gt;
&lt;h2 id=&#34;automatizzare-il-flusso&#34;&gt;Automatizzare il flusso
&lt;/h2&gt;&lt;pre class=&#34;mermaid&#34;&gt;
  flowchart LR
    SRC[(Nuova versione&amp;lt;br/&amp;gt;o CVE)] --&amp;gt; BOT[Bot: Renovate /&amp;lt;br/&amp;gt;Dependabot]
    BOT --&amp;gt;|apre PR| CI[CI: build + test&amp;lt;br/&amp;gt;+ SCA]
    CI --&amp;gt;|verde| MERGE[Merge&amp;lt;br/&amp;gt;auto o rapido]
    CI --&amp;gt;|rosso| HUMAN[Revisione umana]
    style BOT fill:#fde2e4,stroke:#e63946
&lt;/pre&gt;

&lt;p&gt;Un bot apre pull request di aggiornamento; la CI le testa; quelle a basso rischio (patch, minor con
test verdi) si possono auto-mergiare, le altre vanno a revisione. Il team non insegue più i CVE a
mano: gestisce un flusso di PR già testate. Questo trasforma il patching da progetto periodico
doloroso a routine continua invisibile.&lt;/p&gt;
&lt;h2 id=&#34;non-tutto-è-urgente-prioritizzare&#34;&gt;Non tutto è urgente: prioritizzare
&lt;/h2&gt;&lt;p&gt;Patchare &lt;em&gt;tutto subito&lt;/em&gt; è impossibile e inutile. Si prioritizza per rischio reale, non per numero:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Sfruttamento attivo&lt;/strong&gt;: un CVE nel catalogo &lt;strong&gt;CISA KEV&lt;/strong&gt; (vulnerabilità sfruttate in natura) va
prima di cento CVE teorici. Chi vi attacca usa quelli.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Esposizione&lt;/strong&gt;: internet-facing e dati sensibili prima dei servizi interni.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Raggiungibilità&lt;/strong&gt;: il CVE in codice che esegui davvero, non in una funzione mai chiamata — il
tema del &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/vulnerability-management-triage/&#34; &gt;vulnerability management&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;le-immagini-base-un-flusso-dedicato&#34;&gt;Le immagini base: un flusso dedicato
&lt;/h2&gt;&lt;p&gt;Le immagini container hanno una dinamica propria: anche se la tua app non cambia, la base accumula CVE
nei pacchetti OS. La pratica è &lt;strong&gt;ricostruire periodicamente&lt;/strong&gt; le immagini dalla base aggiornata (una
pipeline schedulata che ricompila e ridistribuisce), non solo quando cambia il codice. Un&amp;rsquo;immagine
&lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/container-image-security/&#34; &gt;minimale&lt;/a&gt; riduce drasticamente questo flusso, perché
ha meno pacchetti da patchare.&lt;/p&gt;
&lt;h2 id=&#34;patch-virtuale-guadagnare-tempo&#34;&gt;Patch virtuale: guadagnare tempo
&lt;/h2&gt;&lt;p&gt;Quando non si può patchare subito (nessuna fix disponibile, finestra di manutenzione lontana, sistema
legacy), la &lt;strong&gt;patch virtuale&lt;/strong&gt; compra tempo: un WAF o le regole di &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/runtime-security-falco/&#34; &gt;runtime
security&lt;/a&gt; bloccano lo &lt;em&gt;sfruttamento&lt;/em&gt; del CVE mentre la
correzione vera viene pianificata. È una mitigazione, non una cura: riduce il rischio nell&amp;rsquo;immediato,
non elimina la vulnerabilità.&lt;/p&gt;


&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Domanda:&lt;/strong&gt; l&#39;auto-merge degli aggiornamenti non è pericoloso? Un bot che fonde dipendenze da solo è esattamente il vettore di un attacco di supply chain.&lt;/summary&gt;
&lt;p&gt;È una preoccupazione legittima, e la risposta non è &#34;mai auto-merge&#34; né &#34;auto-merge di tutto&#34;, ma
calibrare l&#39;automazione sul rischio e circondarla di controlli — perché l&#39;alternativa, il patching
manuale, ha un tasso di fallimento molto più alto e più silenzioso. Partiamo dal rischio che sollevi: una
release compromessa (account del maintainer violato, pacchetto typosquatting) fusa automaticamente in
produzione. Si mitiga così. Primo, l&#39;auto-merge non va mai dritto in produzione: fonde in un branch che
passa dalla &lt;em&gt;tua&lt;/em&gt; CI completa — build, test, SCA, policy — e poi dalla tua pipeline di deploy con
i suoi gate; non è &#34;il bot spinge in prod&#34;, è &#34;il bot propone, i tuoi controlli decidono&#34;. Secondo, si
auto-mergia solo la classe a basso rischio: patch e minor con changelog pulito e test verdi, non i major,
non le dipendenze critiche di sicurezza, che vanno a revisione umana. Terzo, si impone una
&lt;em&gt;quarantena temporale&lt;/em&gt;: Renovate può aspettare che una versione abbia N giorni di vita prima di
proporla (&lt;code&gt;minimumReleaseAge&lt;/code&gt;), così le release malevole, che di solito vengono scoperte e
ritirate in fretta, non ti raggiungono all&#39;ora zero. Quarto, i lockfile con hash garantiscono che stai
scaricando esattamente l&#39;artefatto atteso, e la verifica di provenienza (SLSA/Sigstore) aggiunge un
controllo sull&#39;origine. Ora il rovescio: non automatizzare significa che gli aggiornamenti si accumulano
perché &#34;non c&#39;è tempo&#34;, il debito matura, e finisci per girare mesi con CVE &lt;em&gt;noti e con exploit
pubblici&lt;/em&gt; — un rischio molto più certo e sfruttato di una release compromessa che la quarantena
intercetta. Il patching manuale fallisce per omissione, in silenzio, ed è il vettore numero uno delle
violazioni reali. L&#39;automazione ben calibrata riduce quel rischio enorme e certo, al prezzo di un rischio
piccolo e gestibile con quarantena, test e provenienza. La domanda giusta non è &#34;mi fido del bot?&#34; ma
&#34;mi fido dei miei controlli automatici più di quanto mi fidi del fatto che qualcuno aggiorni a mano in
tempo?&#34; — e quasi sempre la risposta onesta è sì.&lt;/p&gt;
&lt;/details&gt;


&lt;h2 id=&#34;conclusione&#34;&gt;Conclusione
&lt;/h2&gt;&lt;p&gt;Le dipendenze non aggiornate sono il vettore più sfruttato perché il debito matura da solo: si gestisce
con aggiornamenti piccoli e frequenti automatizzati dai bot, immagini base ricostruite di continuo,
prioritizzazione per sfruttamento reale (KEV) e patch virtuale per guadagnare tempo. Ma decidere &lt;em&gt;cosa&lt;/em&gt;
patchare prima richiede un modo per confrontare migliaia di CVE: metriche, contesto, triage. È il
vulnerability management, prossimo capitolo.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Identità dei workload: dal codice al cloud</title>
        <link>https://www.matteobianchi.eu/p/identita-workload-pipeline/</link>
        <pubDate>Tue, 04 Aug 2026 09:00:00 +0200</pubDate>
        
        <guid>https://www.matteobianchi.eu/p/identita-workload-pipeline/</guid>
        <description>&lt;img src="https://www.matteobianchi.eu/p/identita-workload-pipeline/cover.png" alt="Featured image of post Identità dei workload: dal codice al cloud" /&gt;&lt;h2 id=&#34;perché-conta&#34;&gt;Perché conta
&lt;/h2&gt;&lt;p&gt;Il capitolo sui &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/secrets-in-kubernetes/&#34; &gt;segreti in Kubernetes&lt;/a&gt; si è chiuso con
un&amp;rsquo;idea radicale: il modo più sicuro di gestire un segreto è &lt;strong&gt;non averne uno&lt;/strong&gt;. Invece di consegnare
a un servizio una chiave statica — che va custodita, ruotata, e che se trapela vale finché non la
revochi — gli si dà un&amp;rsquo;&lt;strong&gt;identità&lt;/strong&gt;, e le credenziali si &lt;em&gt;derivano&lt;/em&gt; da quell&amp;rsquo;identità, attestata dalla
piattaforma, a vita breve. È lo stesso principio della firma keyless di
&lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/firma-artefatti-sigstore/&#34; &gt;Sigstore&lt;/a&gt; e dell&amp;rsquo;identità Zero Trust di
&lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/spiffe-e-spire/&#34; &gt;SPIFFE/SPIRE&lt;/a&gt;, portato attraverso tutto il ciclo DevSecOps.&lt;/p&gt;
&lt;h2 id=&#34;il-problema-del-segreto-zero&#34;&gt;Il problema del &amp;ldquo;segreto zero&amp;rdquo;
&lt;/h2&gt;&lt;p&gt;Ogni schema a chiavi statiche ha la stessa ricorsione: per proteggere il segreto serve un altro
segreto. L&amp;rsquo;identità dei workload spezza la catena ancorandosi a qualcosa che la &lt;em&gt;piattaforma
testimonia&lt;/em&gt;.&lt;/p&gt;
&lt;pre class=&#34;mermaid&#34;&gt;
  flowchart LR
    W[Workload&amp;lt;br/&amp;gt;pod / job CI] --&amp;gt;|&amp;#34;sono il SA X&amp;lt;br/&amp;gt;nel namespace Y&amp;#34;| P[Piattaforma&amp;lt;br/&amp;gt;attesta l&amp;#39;identità]
    P --&amp;gt;|token OIDC&amp;lt;br/&amp;gt;firmato| ID[Identità provata]
    ID --&amp;gt;|scambia con| C[Cloud / Vault&amp;lt;br/&amp;gt;IAM]
    C --&amp;gt;|credenziali TEMPORANEE&amp;lt;br/&amp;gt;a vita breve| W
    style C fill:#fde2e4,stroke:#e63946
&lt;/pre&gt;

&lt;p&gt;Il workload non presenta nessuna chiave: prova &lt;em&gt;chi è&lt;/em&gt; (il ServiceAccount, provato dal cluster) e in
cambio riceve credenziali temporanee. Non c&amp;rsquo;è nessun segreto di lunga durata da rubare, perché non
esiste.&lt;/p&gt;
&lt;h2 id=&#34;nella-pipeline-oidc-federation&#34;&gt;Nella pipeline: OIDC federation
&lt;/h2&gt;&lt;p&gt;L&amp;rsquo;abbiamo già incontrato parlando della &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/sicurezza-pipeline-ci-cd/&#34; &gt;pipeline CI/CD&lt;/a&gt;:
la &lt;strong&gt;workload identity federation&lt;/strong&gt; permette alla CI di autenticarsi al cloud &lt;em&gt;senza&lt;/em&gt; chiavi statiche
nei secret. La pipeline presenta un token OIDC che prova &amp;ldquo;sono la build del repo X sul branch main&amp;rdquo;;
il cloud, configurato a fidarsi di quell&amp;rsquo;emittente e di quell&amp;rsquo;identità precisa, rilascia credenziali
temporanee valide per il job.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Prima:  AWS_SECRET_KEY statica nei secret della CI  → se trapela, accesso per sempre
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Dopo:   token OIDC &amp;#34;repo:org/app:ref:main&amp;#34;          → credenziali valide ~1h, legate al job
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;nel-runtime-dal-serviceaccount-al-cloud&#34;&gt;Nel runtime: dal ServiceAccount al cloud
&lt;/h2&gt;&lt;p&gt;Stessa logica dentro il cluster: un pod ha un &lt;strong&gt;ServiceAccount&lt;/strong&gt;, il cui token (proiettato, a vita
breve) il cluster firma. Quel token si federa verso il cloud (IAM Roles for Service Accounts, Workload
Identity, Managed Identity) per ottenere credenziali cloud temporanee, oppure verso un vault per i
segreti applicativi. Per l&amp;rsquo;identità &lt;strong&gt;servizio-a-servizio&lt;/strong&gt;, SPIFFE/SPIRE emette SVID a vita breve per
mTLS, come visto nella serie Zero Trust.&lt;/p&gt;
&lt;h2 id=&#34;perché-è-il-punto-darrivo-naturale&#34;&gt;Perché è il punto d&amp;rsquo;arrivo naturale
&lt;/h2&gt;&lt;p&gt;L&amp;rsquo;identità dei workload chiude il cerchio del &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/least-privilege-e-jit/&#34; &gt;least privilege e del JIT&lt;/a&gt;:
ogni componente ha esattamente l&amp;rsquo;accesso che la sua identità consente, per il tempo in cui serve, senza
credenziali permanenti. È la fine della caccia ai segreti statici: non si tratta più di &lt;em&gt;proteggere&lt;/em&gt;
mille chiavi, ma di &lt;em&gt;eliminarle&lt;/em&gt;, sostituendole con identità verificabili e credenziali effimere. È
anche il legame più diretto tra DevSecOps e Zero Trust.&lt;/p&gt;


&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Domanda:&lt;/strong&gt; se le credenziali si derivano dall&#39;identità &#34;attestata dalla piattaforma&#34;, non abbiamo semplicemente reso la piattaforma (il cluster, il provider OIDC) l&#39;unico segreto che, se compromesso, dà accesso a tutto?&lt;/summary&gt;
&lt;p&gt;Hai individuato dove si concentra la fiducia, ed è giusto guardarci, ma il confronto corretto non è
&#34;identità contro nessun rischio&#34;, è &#34;identità contro mille chiavi statiche sparse&#34; — e su quel confronto
l&#39;identità vince nettamente, per ragioni concrete. Primo, la superficie. Con le chiavi statiche hai N
segreti di lunga durata in N posti: file di config, variabili d&#39;ambiente, secret di CI, backup, laptop,
wiki dimenticate. Ognuno è un punto di fuga indipendente, e statisticamente qualcuno trapela: la maggior
parte delle violazioni cloud nasce esattamente da una chiave finita dove non doveva. Con l&#39;identità dei
workload quei segreti &lt;em&gt;non esistono&lt;/em&gt;: non c&#39;è nulla da trapelare in N posti, c&#39;è un meccanismo di
attestazione in un posto. Hai ridotto N punti fragili a un punto, progettato apposta per essere protetto.
Secondo, la natura di quel punto. Compromettere &#34;la piattaforma&#34; non è come rubare una stringa: richiede
di compromettere il control plane del cluster o il sistema di firma OIDC del provider — componenti
isolati, monitorati, con il proprio hardening — ed è un problema di sicurezza che &lt;em&gt;hai comunque&lt;/em&gt;,
chiavi o no: se un attaccante controlla il tuo cluster, hai già perso, indipendentemente da come gestisci
i segreti. L&#39;identità non crea quel rischio, lo rende semplicemente l&#39;unico che conta, invece di sommarlo
ai mille rischi delle chiavi. Terzo, il tempo e la verificabilità. Le credenziali derivate sono effimere:
anche nel caso peggiore, una credenziale catturata vale minuti, non mesi, e la finestra di attestazione è
vincolata a un&#39;identità precisa (&#34;quel repo, quel branch&#34;, &#34;quel SA, quel namespace&#34;), non a &#34;chiunque
abbia la chiave&#34;. E ogni scambio di token è tracciabile e revocabile centralmente: puoi togliere accesso
a un&#39;identità istantaneamente, cosa impossibile con una chiave statica già copiata altrove. Quindi sì, la
fiducia si concentra — ma si concentra su qualcosa di piccolo, difendibile, monitorato ed effimero,
sottraendola a qualcosa di diffuso, fragile e permanente. Concentrare la fiducia dove puoi difenderla è
una strategia di sicurezza, non un difetto: è lo stesso motivo per cui metti i valori in una cassaforte
invece che sotto mille zerbini.&lt;/p&gt;
&lt;/details&gt;


&lt;h2 id=&#34;conclusione&#34;&gt;Conclusione
&lt;/h2&gt;&lt;p&gt;L&amp;rsquo;identità dei workload sostituisce le chiavi statiche con credenziali effimere derivate da chi è il
servizio, attestato dalla piattaforma: OIDC federation nella pipeline, ServiceAccount e SPIFFE a
runtime. Il segreto più sicuro è quello che non esiste. Con questo chiudiamo i controlli di build e
runtime; resta la parte &lt;em&gt;operate&lt;/em&gt;, dove il software vive nel tempo e le vulnerabilità emergono dopo il
rilascio. Si parte dal tenere aggiornato ciò che gira: patch e dipendenze, prossimo capitolo.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Segreti in Kubernetes senza lacrime</title>
        <link>https://www.matteobianchi.eu/p/secrets-in-kubernetes/</link>
        <pubDate>Tue, 28 Jul 2026 09:00:00 +0200</pubDate>
        
        <guid>https://www.matteobianchi.eu/p/secrets-in-kubernetes/</guid>
        <description>&lt;img src="https://www.matteobianchi.eu/p/secrets-in-kubernetes/cover.png" alt="Featured image of post Segreti in Kubernetes senza lacrime" /&gt;&lt;h2 id=&#34;perché-conta&#34;&gt;Perché conta
&lt;/h2&gt;&lt;p&gt;Abbiamo imparato a non mettere mai i &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/gestione-dei-segreti/&#34; &gt;segreti nel codice&lt;/a&gt;.
Nel cluster il problema torna con una trappola specifica: i &lt;strong&gt;Secret di Kubernetes sono codificati in
base64, non cifrati&lt;/strong&gt;. Chiunque legga l&amp;rsquo;oggetto Secret, o acceda a etcd, li legge in chiaro con un
comando. Sono comodi per &lt;em&gt;consegnare&lt;/em&gt; un segreto a un pod, ma pessimi come &lt;em&gt;deposito&lt;/em&gt;. Questo capitolo
è come usarli bene senza illudersi.&lt;/p&gt;
&lt;h2 id=&#34;base64-non-è-cifratura&#34;&gt;base64 non è cifratura
&lt;/h2&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;kubectl get secret db-pass -o jsonpath=&amp;#39;{.data.password}&amp;#39; | base64 -d
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;# → stampa la password in chiaro.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;# base64 è una CODIFICA, non una protezione: reversibile da chiunque, senza chiave.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Due conseguenze immediate: &lt;strong&gt;cifrare etcd a riposo&lt;/strong&gt; (encryption-at-rest, idealmente con un KMS
esterno) perché altrimenti chi copia etcd ha tutti i segreti; e &lt;strong&gt;restringere con RBAC&lt;/strong&gt; chi può
leggere i Secret, perché il permesso &lt;code&gt;get secrets&lt;/code&gt; equivale ad avere quei segreti.&lt;/p&gt;
&lt;h2 id=&#34;il-problema-del-gitops&#34;&gt;Il problema del GitOps
&lt;/h2&gt;&lt;p&gt;Il GitOps vuole &lt;em&gt;tutto&lt;/em&gt; in git, inclusa la configurazione dei Secret. Ma committare un Secret, anche
base64, è committare il segreto in chiaro nella history. Due soluzioni opposte:&lt;/p&gt;
&lt;pre class=&#34;mermaid&#34;&gt;
  flowchart TD
    subgraph A[External Secrets Operator]
        G1[Git: solo un&amp;lt;br/&amp;gt;RIFERIMENTO al segreto] --&amp;gt; ESO[Operator]
        V[(Vault / cloud&amp;lt;br/&amp;gt;secret manager)] --&amp;gt; ESO
        ESO --&amp;gt;|crea/sincronizza| S1[Secret nel cluster]
    end
    subgraph B[Sealed Secrets]
        G2[Git: segreto&amp;lt;br/&amp;gt;CIFRATO, sicuro da&amp;lt;br/&amp;gt;committare] --&amp;gt; CTRL[Controller]
        CTRL --&amp;gt;|decifra con chiave&amp;lt;br/&amp;gt;solo nel cluster| S2[Secret nel cluster]
    end
    style V fill:#fde2e4,stroke:#e63946
&lt;/pre&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;External Secrets Operator&lt;/strong&gt;: la fonte di verità resta un &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/gestione-dei-segreti/&#34; &gt;vault esterno&lt;/a&gt;;
in git c&amp;rsquo;è solo un &lt;em&gt;riferimento&lt;/em&gt;. L&amp;rsquo;operator sincronizza. Il segreto non tocca mai git.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sealed Secrets&lt;/strong&gt;: il segreto si &lt;em&gt;cifra&lt;/em&gt; con una chiave pubblica; la cifratura è sicura da
committare perché solo il controller nel cluster ha la chiave privata per decifrarla.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;montare-senza-esporre&#34;&gt;Montare senza esporre
&lt;/h2&gt;&lt;p&gt;Il modo in cui il segreto arriva al container conta. Le variabili d&amp;rsquo;ambiente sono comode ma trapelano
facilmente (compaiono nei dump, nei log di errore, nell&amp;rsquo;introspezione del processo). Montare i segreti
come &lt;strong&gt;file&lt;/strong&gt; è più sicuro, e i &lt;strong&gt;CSI Secrets Store driver&lt;/strong&gt; fanno un passo oltre: montano il segreto
dal vault esterno direttamente nel filesystem del pod a runtime, senza nemmeno creare un oggetto
Secret persistente. Il segreto esiste solo finché il pod vive.&lt;/p&gt;
&lt;h2 id=&#34;rotazione-e-vita-breve&#34;&gt;Rotazione e vita breve
&lt;/h2&gt;&lt;p&gt;Vale qui ciò che valeva per i segreti applicativi: meglio &lt;strong&gt;dinamici e a vita breve&lt;/strong&gt; che statici e
rotati a mano. L&amp;rsquo;External Secrets Operator può ri-sincronizzare periodicamente; i vault possono
emettere credenziali effimere. E l&amp;rsquo;approdo naturale è non consegnare affatto un segreto condiviso, ma
dare a ogni workload una &lt;em&gt;identità&lt;/em&gt; da cui derivare le credenziali — il tema del prossimo capitolo.&lt;/p&gt;


&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Domanda:&lt;/strong&gt; se cifro etcd a riposo e restringo l&#39;RBAC, i Secret nativi di Kubernetes non sono già abbastanza sicuri? Perché aggiungere la complessità di vault esterni e operator?&lt;/summary&gt;
&lt;p&gt;Cifrare etcd e stringere l&#39;RBAC sono necessari e vanno fatti comunque, ma risolvono solo una parte del
problema, e la parte che lasciano aperta è spesso quella dove i segreti trapelano davvero. Cosa coprono:
chi ruba una copia di etcd non legge i segreti (cifratura a riposo), e chi non ha i permessi non può fare
&lt;code&gt;get secrets&lt;/code&gt; (RBAC). Cosa &lt;em&gt;non&lt;/em&gt; coprono: primo, il ciclo di vita. Un Secret nativo è
statico — lo crei una volta e resta lì finché qualcuno lo ruota a mano, cosa che in pratica non succede
mai; non c&#39;è rotazione automatica, non c&#39;è scadenza, un segreto trapelato vale finché qualcuno non se ne
accorge. Un vault esterno offre credenziali dinamiche a vita breve, così il valore di un furto crolla.
Secondo, il perimetro di fiducia. Con i Secret nativi, la tua sorgente di verità per i segreti è il
cluster stesso: chiunque comprometta il cluster — o un suo amministratore — ha tutti i segreti. Con un
vault esterno il cluster è solo un consumatore, il vault applica le proprie policy di accesso e audit, e
puoi revocare l&#39;accesso del cluster senza toccare i segreti. Terzo, la frammentazione. Senza un vault,
ogni cluster ha i suoi Secret scollegati; con un vault hai una gestione centralizzata, un audit unico di
chi ha letto cosa, e la stessa credenziale non duplicata in dieci posti. Quarto, il GitOps: i Secret
nativi ti costringono a scegliere tra non mettere i segreti in git (e perdere la riproducibilità) o
committarli in base64 (e bruciarli); External Secrets e Sealed Secrets risolvono esattamente questo. Non
sto dicendo che ti serva sempre tutto l&#39;armamentario: per un cluster piccolo, Secret nativi + etcd
cifrato + RBAC stretto sono un punto di partenza onesto. Ma la complessità del vault non è gratuita per
capriccio: compra rotazione, vita breve, centralizzazione e audit — cioè proprio le proprietà che
trasformano &#34;il segreto è protetto se nessuno sbaglia&#34; in &#34;il segreto vale poco anche se qualcosa va
storto&#34;. La domanda da farsi è quanto vale ciò che quei segreti proteggono.&lt;/p&gt;
&lt;/details&gt;


&lt;h2 id=&#34;conclusione&#34;&gt;Conclusione
&lt;/h2&gt;&lt;p&gt;I Secret di Kubernetes sono un meccanismo di consegna, non una cassaforte: base64 non è cifratura,
quindi servono etcd cifrato e RBAC stretto, e per il GitOps o un vault esterno (External Secrets) o la
cifratura (Sealed Secrets), montando a runtime via CSI quando possibile. Il passo successivo è smettere
di consegnare segreti condivisi e dare a ogni workload la propria identità verificabile, da cui tutto
il resto deriva. È l&amp;rsquo;identità dei workload nella pipeline e nel cluster, prossimo capitolo.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Runtime security: vedere l&#39;attacco mentre accade</title>
        <link>https://www.matteobianchi.eu/p/runtime-security-falco/</link>
        <pubDate>Tue, 21 Jul 2026 09:00:00 +0200</pubDate>
        
        <guid>https://www.matteobianchi.eu/p/runtime-security-falco/</guid>
        <description>&lt;img src="https://www.matteobianchi.eu/p/runtime-security-falco/cover.png" alt="Featured image of post Runtime security: vedere l&#39;attacco mentre accade" /&gt;&lt;h2 id=&#34;perché-conta&#34;&gt;Perché conta
&lt;/h2&gt;&lt;p&gt;Ogni controllo visto finora è &lt;em&gt;preventivo&lt;/em&gt;: cerca di impedire che un difetto nasca o che un carico
non conforme parta. Ma la prevenzione, da sola, è una scommessa che prima o poi si perde: un CVE
zero-day, una configurazione sfuggita, una credenziale rubata. La &lt;strong&gt;runtime security&lt;/strong&gt; accetta questa
realtà e aggiunge l&amp;rsquo;altra metà: &lt;em&gt;osservare il comportamento reale&lt;/em&gt; dei container in esecuzione e
reagire quando qualcosa esce dal normale. Si appoggia a &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/ebpf-network-security/&#34; &gt;eBPF&lt;/a&gt;
per vedere nel kernel senza modificare le app.&lt;/p&gt;
&lt;h2 id=&#34;lidea-il-comportamento-atteso&#34;&gt;L&amp;rsquo;idea: il comportamento atteso
&lt;/h2&gt;&lt;p&gt;Un container ha un comportamento prevedibile e stretto: un server web ascolta su una porta, legge
certi file, parla con certi servizi. Tutto il resto è sospetto.&lt;/p&gt;
&lt;pre class=&#34;mermaid&#34;&gt;
  flowchart TD
    OBS[eBPF osserva nel kernel:&amp;lt;br/&amp;gt;syscall, exec, rete, file] --&amp;gt; ENG[Motore di regole&amp;lt;br/&amp;gt;Falco]
    ENG --&amp;gt; N{Comportamento&amp;lt;br/&amp;gt;atteso?}
    N --&amp;gt;|sì| OK[Normale]
    N --&amp;gt;|no| AL[&amp;#34;ALLERTA:&amp;lt;br/&amp;gt;shell in un container web,&amp;lt;br/&amp;gt;connessione a IP ignoto,&amp;lt;br/&amp;gt;scrittura su /etc&amp;#34;]
    AL --&amp;gt; ACT[Notifica / blocca / isola]
    style AL fill:#fde2e4,stroke:#e63946
&lt;/pre&gt;

&lt;p&gt;A differenza dell&amp;rsquo;antivirus basato su firme, la runtime security moderna ragiona per &lt;strong&gt;comportamento&lt;/strong&gt;:
non &amp;ldquo;riconosco questo malware&amp;rdquo;, ma &amp;ldquo;questo container sta facendo qualcosa che un container di quel tipo
non dovrebbe fare&amp;rdquo;.&lt;/p&gt;
&lt;h2 id=&#34;cosa-rileva-falco&#34;&gt;Cosa rileva Falco
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Falco&lt;/strong&gt;, lo standard CNCF, osserva le syscall via eBPF e le valuta contro regole. Segnali tipici di
compromissione:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Esempi di regole comportamentali:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  - shell avviata dentro un container             ← quasi mai legittimo in prod
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  - processo che legge /etc/shadow                ← tentativo di furto credenziali
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  - connessione in uscita verso IP non previsto   ← possibile C2 / esfiltrazione
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  - scrittura in una directory di sistema         ← tampering del binario
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  - montaggio sospetto o accesso al socket Docker  ← tentativo di escape
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Molti di questi sono proprio ciò che un&amp;rsquo;immagine &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/container-image-security/&#34; &gt;distroless&lt;/a&gt;
rende &lt;em&gt;impossibile&lt;/em&gt; (niente shell) o che l&amp;rsquo;&lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/kubernetes-hardening/&#34; &gt;hardening&lt;/a&gt;
rende &lt;em&gt;difficile&lt;/em&gt; — la prevenzione riduce ciò che Falco deve vedere, e Falco cattura ciò che la
prevenzione non ha fermato. Difesa in profondità.&lt;/p&gt;
&lt;h2 id=&#34;allertare-o-bloccare&#34;&gt;Allertare o bloccare?
&lt;/h2&gt;&lt;p&gt;Due modalità, con un compromesso:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Detect (allerta)&lt;/strong&gt;: segnala l&amp;rsquo;anomalia a chi risponde. Nessun rischio di bloccare traffico
legittimo, ma richiede qualcuno (o un&amp;rsquo;automazione) che reagisca in fretta.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enforce (blocca/isola)&lt;/strong&gt;: ferma il processo o isola il pod automaticamente. Reazione immediata,
ma un falso positivo può interrompere un servizio.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;La pratica comune: partire in detect per &lt;em&gt;imparare&lt;/em&gt; il comportamento normale e tarare le regole,
riducendo i falsi positivi, e passare a enforce solo sulle anomalie ad alta confidenza. Le allerte
alimentano la &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/siem-log-correlation/&#34; &gt;detection e il SIEM&lt;/a&gt; e innescano la
&lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/incident-response-devsecops/&#34; &gt;risposta agli incidenti&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;il-rumore-è-il-vero-nemico&#34;&gt;Il rumore è il vero nemico
&lt;/h2&gt;&lt;p&gt;Come ogni detection, la runtime security vive o muore sui falsi positivi. Mille allerte al giorno
equivalgono a zero allerte: nessuno le guarda. Il lavoro vero non è installare Falco, è &lt;em&gt;tarare&lt;/em&gt; le
regole sul comportamento reale dei propri carichi, sopprimere il rumore noto e mantenere solo i
segnali azionabili. Una detection ignorata è peggio di nessuna detection, perché dà un falso senso di
copertura.&lt;/p&gt;


&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Domanda:&lt;/strong&gt; se ho già fatto prevenzione seria — immagini distroless, hardening, admission control, network policy — cosa mi aggiunge davvero la runtime security? Non dovrebbe essere già tutto bloccato?&lt;/summary&gt;
&lt;p&gt;La prevenzione risponde alla domanda &#34;può succedere?&#34; e tu l&#39;hai ridotta tanto; la runtime security
risponde a una domanda diversa, &#34;&lt;em&gt;sta&lt;/em&gt; succedendo?&#34;, e nessuna quantità di prevenzione la rende
superflua, per tre ragioni. Primo, la prevenzione ha un orizzonte: conosce i difetti e le configurazioni
sbagliate &lt;em&gt;note oggi&lt;/em&gt;. Uno zero-day nella tua applicazione, una catena di exploit che nessuna
policy prevedeva, una credenziale legittima rubata e usata in modo legittimo-ma-malevolo — tutto questo
passa i controlli preventivi proprio perché non viola nessuna regola conosciuta. La runtime security non
chiede &#34;questo è permesso?&#34; ma &#34;questo è &lt;em&gt;normale&lt;/em&gt; per questo container?&#34;, e un comportamento
anomalo è anomalo anche se tecnicamente permesso. Secondo, la prevenzione può avere buchi che non sai di
avere: una policy di admission con un&#39;eccezione dimenticata, un namespace legacy non ancora hardened, un
workload con una deroga temporanea diventata permanente. La runtime security è la rete che vede cosa
succede &lt;em&gt;davvero&lt;/em&gt;, indipendentemente da cosa credevi di aver bloccato — e spesso è lì che scopri
che un controllo preventivo non era attivo dove pensavi. Terzo, e decisivo: la prevenzione non lascia
&lt;em&gt;testimonianza&lt;/em&gt;. Se un attacco riesce nonostante tutto, senza osservazione a runtime non lo sai —
non hai allerta, non hai timeline, non hai le prove per capire cosa è stato toccato. La runtime security
è ciò che trasforma una compromissione silenziosa e indefinita in un incidente rilevato, delimitato e
investigabile. Il punto non è che la prevenzione sia debole: più è forte, meno rumore deve gestire la
detection e più ogni allerta è significativa. I due lavorano insieme — la prevenzione riduce la
superficie e il volume, la detection copre l&#39;inevitabile residuo e ti dà occhi su ciò che la prevenzione
non ha visto. La sicurezza seria non sceglie tra &#34;impedire&#34; e &#34;rilevare&#34;: fa entrambi perché falliscono
in modi diversi.&lt;/p&gt;
&lt;/details&gt;


&lt;h2 id=&#34;conclusione&#34;&gt;Conclusione
&lt;/h2&gt;&lt;p&gt;La runtime security accetta che la prevenzione prima o poi ceda: osserva il comportamento reale via
eBPF, segnala la shell inattesa e la connessione sospetta, allerta o blocca, e dà la testimonianza
che la prevenzione non lascia. Vive e muore sulla taratura dei falsi positivi. Tra i comportamenti più
sensibili c&amp;rsquo;è l&amp;rsquo;accesso ai segreti: come i container ottengono le credenziali in un cluster, senza
lasciarle in chiaro, è il prossimo capitolo.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Admission control: il buttafuori del cluster</title>
        <link>https://www.matteobianchi.eu/p/admission-control/</link>
        <pubDate>Tue, 14 Jul 2026 09:00:00 +0200</pubDate>
        
        <guid>https://www.matteobianchi.eu/p/admission-control/</guid>
        <description>&lt;img src="https://www.matteobianchi.eu/p/admission-control/cover.png" alt="Featured image of post Admission control: il buttafuori del cluster" /&gt;&lt;h2 id=&#34;perché-conta&#34;&gt;Perché conta
&lt;/h2&gt;&lt;p&gt;L&amp;rsquo;&lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/kubernetes-hardening/&#34; &gt;hardening&lt;/a&gt; definisce &lt;em&gt;come&lt;/em&gt; dovrebbe girare un pod. Ma
chi impedisce che qualcuno applichi comunque un manifest che viola quelle regole? L&amp;rsquo;&lt;strong&gt;admission
control&lt;/strong&gt; è la risposta: il punto, lungo il percorso di ogni richiesta all&amp;rsquo;API server, in cui si può
&lt;em&gt;rifiutare&lt;/em&gt; o &lt;em&gt;modificare&lt;/em&gt; un oggetto &lt;strong&gt;prima&lt;/strong&gt; che venga persistito e schedulato. È l&amp;rsquo;ultima porta —
e la più efficace, perché agisce su &lt;em&gt;tutto&lt;/em&gt; ciò che entra nel cluster, da qualunque fonte.&lt;/p&gt;
&lt;h2 id=&#34;dove-si-inserisce&#34;&gt;Dove si inserisce
&lt;/h2&gt;&lt;pre class=&#34;mermaid&#34;&gt;
  flowchart LR
    U[kubectl / CI / operator] --&amp;gt;|crea pod| API[API server]
    API --&amp;gt; AUTH[AuthN/AuthZ&amp;lt;br/&amp;gt;RBAC]
    AUTH --&amp;gt; MUT[Mutating&amp;lt;br/&amp;gt;webhook]
    MUT --&amp;gt; VAL[Validating&amp;lt;br/&amp;gt;webhook&amp;lt;br/&amp;gt;= PEP]
    VAL --&amp;gt;|conforme| ETCD[(etcd → schedulato)]
    VAL -.non conforme.-&amp;gt; REJ[RIFIUTATO&amp;lt;br/&amp;gt;con motivazione]
    style VAL fill:#fde2e4,stroke:#e63946
&lt;/pre&gt;

&lt;p&gt;Dopo l&amp;rsquo;autenticazione e RBAC, la richiesta passa da due tipi di webhook:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Mutating&lt;/strong&gt;: &lt;em&gt;modifica&lt;/em&gt; l&amp;rsquo;oggetto. Es. inietta automaticamente un security context sicuro, aggiunge
label, imposta limiti di risorse di default.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Validating&lt;/strong&gt;: &lt;em&gt;accetta o rifiuta&lt;/em&gt;. È il &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/pdp-pep-il-motore-delle-policy/&#34; &gt;PEP&lt;/a&gt;
del cluster: valuta l&amp;rsquo;oggetto contro le policy e, se viola, lo blocca con un messaggio.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;cosa-si-applica-qui&#34;&gt;Cosa si applica qui
&lt;/h2&gt;&lt;p&gt;L&amp;rsquo;admission control è dove le promesse dei capitoli precedenti diventano enforcement reale:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Rifiuta se:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  - immagine NON firmata da identità attesa   (verifica Sigstore/cosign)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  - immagine con CVE critici o senza SBOM
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  - container privilegiato / runAsRoot / hostPath pericolosi
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  - manca il limite di risorse, usa tag :latest, namespace sbagliato
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Muta per imposizione:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  - aggiungi securityContext sicuro di default, label owner, networkpolicy
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;La verifica della firma è l&amp;rsquo;esempio più nitido: la &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/firma-artefatti-sigstore/&#34; &gt;firma&lt;/a&gt;
diventa un &lt;em&gt;controllo d&amp;rsquo;accesso&lt;/em&gt; solo quando un validating webhook la verifica e rifiuta ciò che non
proviene dall&amp;rsquo;identità attesa. Senza admission control, firmare è teatro.&lt;/p&gt;
&lt;h2 id=&#34;kyverno-e-opa-gatekeeper&#34;&gt;Kyverno e OPA Gatekeeper
&lt;/h2&gt;&lt;p&gt;Due approcci allo stesso ruolo di PEP:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Kyverno&lt;/strong&gt;: le policy sono risorse Kubernetes in YAML, native per chi già conosce i manifest.
Nessun linguaggio nuovo da imparare; fa anche mutazione e generazione di risorse.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OPA Gatekeeper&lt;/strong&gt;: porta &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/policy-as-code-pipeline/&#34; &gt;OPA e Rego&lt;/a&gt; nel cluster.
Più potente ed espressivo, a costo di imparare Rego, e con il vantaggio di condividere lo &lt;em&gt;stesso&lt;/em&gt;
linguaggio di policy tra pipeline e cluster.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;pipeline-e-cluster-due-reti-non-una&#34;&gt;Pipeline e cluster: due reti, non una
&lt;/h2&gt;&lt;p&gt;L&amp;rsquo;admission control e il controllo in pipeline si rafforzano a vicenda. La pipeline cattura presto e
dà feedback allo sviluppatore (shift-left); l&amp;rsquo;admission control cattura &lt;em&gt;tutto&lt;/em&gt; ciò che arriva
all&amp;rsquo;API, incluso ciò che bypassa la pipeline — un &lt;code&gt;kubectl apply&lt;/code&gt; manuale, un operator, un attaccante
con credenziali. Fare entrambi significa feedback precoce &lt;strong&gt;e&lt;/strong&gt; enforcement inaggirabile.&lt;/p&gt;


&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Domanda:&lt;/strong&gt; se già controllo tutto in pipeline — scansione immagini, firma, policy Rego — perché aggiungere l&#39;admission control nel cluster? Non è controllare due volte la stessa cosa?&lt;/summary&gt;
&lt;p&gt;È controllare la stessa &lt;em&gt;regola&lt;/em&gt; in due punti con garanzie diverse, e la differenza è tutta in
ciò che ciascun punto può garantire. La pipeline ha un presupposto fatale come unico controllo: che ogni
cosa che arriva nel cluster sia passata &lt;em&gt;dalla&lt;/em&gt; pipeline. Nella realtà non è così. Un operatore
sotto incidente fa un &lt;code&gt;kubectl apply&lt;/code&gt; a mano per &#34;sistemare al volo&#34;; un operator o un
controller crea pod dinamicamente senza passare da nessuna CI; un Helm chart di terze parti installa
risorse che la tua pipeline non ha mai visto; un attaccante che ha ottenuto credenziali valide parla
direttamente con l&#39;API server — e nessuno di questi percorsi tocca la pipeline. Tutto ciò che la pipeline
verifica diventa irrilevante per qualunque oggetto che entra da una porta diversa. L&#39;admission control
chiude proprio questo: sta sull&#39;API server, quindi vede &lt;em&gt;ogni&lt;/em&gt; richiesta di creazione o modifica,
da qualunque fonte, e applica la policy lì, nell&#39;unico collo di bottiglia che nessuno può aggirare senza
compromettere l&#39;API stessa. Questo non rende inutile la pipeline, anzi: i due hanno scopi complementari.
La pipeline è veloce, dà feedback allo sviluppatore riga per riga sulla pull request, fa fallire la build
quando il contesto è fresco — è prevenzione e insegnamento (shift-left). L&#39;admission control è tardivo e
muto per lo sviluppatore ma &lt;em&gt;inaggirabile&lt;/em&gt; — è enforcement. Il modello corretto è lo stesso
principio (&#34;solo immagini firmate&#34;) espresso una volta e applicato in due punti: in pipeline per fermare
presto e bene, all&#39;ammissione per fermare comunque. Togliere la pipeline ti lascia l&#39;enforcement senza
feedback precoce; togliere l&#39;admission control ti lascia il feedback con un enforcement pieno di buchi.
Li vuoi entrambi perché difendono da fallimenti diversi.&lt;/p&gt;
&lt;/details&gt;


&lt;h2 id=&#34;conclusione&#34;&gt;Conclusione
&lt;/h2&gt;&lt;p&gt;L&amp;rsquo;admission control è il buttafuori del cluster: mutating webhook che impongono default sicuri,
validating webhook che rifiutano ciò che viola le policy — immagini non firmate, container
privilegiati, configurazioni fuori norma. È dove firma e policy diventano enforcement inaggirabile, a
complemento della pipeline. Ma tutti i controlli visti finora sono &lt;em&gt;preventivi&lt;/em&gt;: agiscono prima che il
codice giri. Qualcosa passerà comunque, e allora serve vedere e reagire a ciò che accade &lt;em&gt;mentre&lt;/em&gt;
succede. È la runtime security, prossimo capitolo.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Hardening di Kubernetes</title>
        <link>https://www.matteobianchi.eu/p/kubernetes-hardening/</link>
        <pubDate>Tue, 07 Jul 2026 09:00:00 +0200</pubDate>
        
        <guid>https://www.matteobianchi.eu/p/kubernetes-hardening/</guid>
        <description>&lt;img src="https://www.matteobianchi.eu/p/kubernetes-hardening/cover.png" alt="Featured image of post Hardening di Kubernetes" /&gt;&lt;h2 id=&#34;perché-conta&#34;&gt;Perché conta
&lt;/h2&gt;&lt;p&gt;Abbiamo &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/container-image-security/&#34; &gt;immagini minimali&lt;/a&gt;; ora girano in un
cluster. E un cluster Kubernetes di default è progettato per &lt;em&gt;funzionare facilmente&lt;/em&gt;, non per essere
sicuro: permessi ampi, nessuna restrizione di rete, pod che possono girare come root. L&amp;rsquo;hardening è il
lavoro di restringere questi default senza rompere i carichi. Si appoggia al
&lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/kubernetes-networking-model/&#34; &gt;modello di rete di Kubernetes&lt;/a&gt; già visto, e ne
chiude i margini.&lt;/p&gt;
&lt;h2 id=&#34;le-quattro-leve-principali&#34;&gt;Le quattro leve principali
&lt;/h2&gt;&lt;pre class=&#34;mermaid&#34;&gt;
  flowchart TD
    RBAC[RBAC&amp;lt;br/&amp;gt;chi può fare cosa&amp;lt;br/&amp;gt;sull&amp;#39;API] 
    SC[Security Context&amp;lt;br/&amp;gt;come gira il pod]
    NP[Network Policy&amp;lt;br/&amp;gt;chi parla con chi]
    PSS[Pod Security&amp;lt;br/&amp;gt;Standards&amp;lt;br/&amp;gt;cosa è ammesso]
    RBAC --- SC --- NP --- PSS --- RBAC
    style RBAC fill:#fde2e4,stroke:#e63946
&lt;/pre&gt;

&lt;h3 id=&#34;1-rbac-a-privilegio-minimo&#34;&gt;1. RBAC a privilegio minimo
&lt;/h3&gt;&lt;p&gt;Il controllo d&amp;rsquo;accesso all&amp;rsquo;API è la prima linea. L&amp;rsquo;errore classico è concedere &lt;code&gt;cluster-admin&lt;/code&gt; &amp;ldquo;per
non avere problemi&amp;rdquo;. Ogni ServiceAccount e ogni utente deve potere &lt;em&gt;solo&lt;/em&gt; ciò che serve. Attenzione
speciale ai permessi che consentono l&amp;rsquo;escalation: creare pod, leggere i secret, modificare i
RoleBinding sono poteri che equivalgono quasi al controllo del cluster.&lt;/p&gt;
&lt;h3 id=&#34;2-security-context-del-pod&#34;&gt;2. Security context del pod
&lt;/h3&gt;&lt;p&gt;Come abbiamo indurito l&amp;rsquo;immagine, induriamo l&amp;rsquo;esecuzione:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;securityContext&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;runAsNonRoot&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# mai root nel container&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;readOnlyRootFilesystem&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# niente scrittura sul filesystem del container&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;allowPrivilegeEscalation&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;capabilities&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;{&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;drop&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;ALL&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;}&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# togli tutte le capability Linux, riaggiungi solo il minimo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Queste quattro righe eliminano le vie più comuni di escape e di movimento. Un container che non può
diventare root, non può scrivere su disco e non ha capability è molto meno utile a un attaccante.&lt;/p&gt;
&lt;h3 id=&#34;3-network-policy-di-default-deny&#34;&gt;3. Network policy di default-deny
&lt;/h3&gt;&lt;p&gt;Di default, in Kubernetes &lt;em&gt;ogni pod parla con ogni pod&lt;/em&gt;. È l&amp;rsquo;opposto dello Zero Trust. Una
&lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/microsegmentazione-nello-zero-trust/&#34; &gt;microsegmentazione&lt;/a&gt; con network policy di
&lt;strong&gt;default-deny&lt;/strong&gt; chiude tutto il traffico est-ovest e riapre solo i flussi necessari. Così un pod
compromesso non può raggiungere liberamente il resto del cluster.&lt;/p&gt;
&lt;h3 id=&#34;4-pod-security-standards&#34;&gt;4. Pod Security Standards
&lt;/h3&gt;&lt;p&gt;I &lt;strong&gt;Pod Security Standards&lt;/strong&gt; (Restricted, Baseline, Privileged) definiscono cosa un pod può chiedere.
Applicati a livello di namespace tramite il Pod Security Admission, impediscono che venga schedulato
un pod privilegiato o con host mount pericolosi — un controllo &lt;em&gt;all&amp;rsquo;ammissione&lt;/em&gt;, che è il ponte verso
il prossimo capitolo.&lt;/p&gt;
&lt;h2 id=&#34;lisolamento-dei-nodi-e-il-resto&#34;&gt;L&amp;rsquo;isolamento dei nodi e il resto
&lt;/h2&gt;&lt;p&gt;Oltre ai pod: proteggere l&amp;rsquo;accesso all&amp;rsquo;&lt;strong&gt;etcd&lt;/strong&gt; (contiene tutti i segreti del cluster, in chiaro se
non cifrato a riposo), limitare l&amp;rsquo;accesso all&amp;rsquo;API server, isolare i nodi, e trattare i carichi
multi-tenant con namespace separati e, per i casi più sensibili, sandbox di runtime (gVisor,
Kata). L&amp;rsquo;hardening non è una checklist una tantum: è un confronto periodico con il CIS Benchmark.&lt;/p&gt;


&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Domanda:&lt;/strong&gt; se applico RBAC stretto, readOnlyRootFilesystem, drop di tutte le capability e default-deny di rete, non rischio di rompere metà dei miei workload che oggi funzionano?&lt;/summary&gt;
&lt;p&gt;Il rischio di rottura è reale, ma rivela una verità scomoda: se un workload smette di funzionare quando
gli togli root, la scrittura sul filesystem, le capability e la rete libera, vuol dire che oggi sta
&lt;em&gt;usando&lt;/em&gt; privilegi che non dovrebbe avere, e quello è precisamente il problema di sicurezza che stai
cercando di chiudere. L&#39;hardening non va fatto a martellate su tutto il cluster in un giorno, va fatto
come una migrazione guidata. Prima &lt;em&gt;osservi&lt;/em&gt;: molti di questi controlli hanno una modalità non
bloccante — i Pod Security Standards si applicano per namespace con livelli &lt;code&gt;warn&lt;/code&gt; e
&lt;code&gt;audit&lt;/code&gt; prima di &lt;code&gt;enforce&lt;/code&gt;, così vedi quali pod violerebbero la policy senza
fermarli; per le network policy usi strumenti che registrano il traffico reale prima di passare al
default-deny, così sai quali flussi riaprire. Poi correggi alla fonte: un&#39;app che vuole scrivere lo fa su
un volume emptyDir montato apposta, non sul root filesystem; una che crede di aver bisogno di root quasi
sempre non ne ha bisogno davvero una volta sistemati i permessi dei file; le capability si riaggiungono
una per una, solo quelle effettivamente necessarie (spesso zero). Poi procedi per gradi: un namespace non
critico prima, i default stretti sui nuovi workload subito (è molto più facile nascere conformi che
diventarlo), e i workload legacy migrati uno alla volta con una deroga tracciata dove serve tempo.
Infine, imposti i default sicuri a livello di piattaforma, così il prossimo team parte già hardened senza
doverci pensare. Il punto è che la rottura non è un effetto collaterale dell&#39;hardening: è la diagnosi. Ti
dice esattamente dove i tuoi workload sono sovra-privilegiati, che è l&#39;informazione che ti serviva per
renderli difendibili.&lt;/p&gt;
&lt;/details&gt;


&lt;h2 id=&#34;conclusione&#34;&gt;Conclusione
&lt;/h2&gt;&lt;p&gt;Un cluster sicuro è un cluster ristretto: RBAC a privilegio minimo, security context che impediscono
root e scrittura, network policy di default-deny, Pod Security Standards per namespace, più etcd
cifrato e API protetta. Molti di questi controlli si fanno rispettare &lt;em&gt;al momento dell&amp;rsquo;ammissione&lt;/em&gt; di
un pod — il meccanismo che permette di dire &amp;ldquo;no&amp;rdquo; prima ancora che qualcosa parta. È l&amp;rsquo;admission
control, prossimo capitolo.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Sicurezza delle immagini container</title>
        <link>https://www.matteobianchi.eu/p/container-image-security/</link>
        <pubDate>Tue, 30 Jun 2026 09:00:00 +0200</pubDate>
        
        <guid>https://www.matteobianchi.eu/p/container-image-security/</guid>
        <description>&lt;img src="https://www.matteobianchi.eu/p/container-image-security/cover.png" alt="Featured image of post Sicurezza delle immagini container" /&gt;&lt;h2 id=&#34;perché-conta&#34;&gt;Perché conta
&lt;/h2&gt;&lt;p&gt;Gli artefatti verificabili dei capitoli precedenti, nel mondo cloud-native, sono quasi sempre
&lt;strong&gt;immagini container&lt;/strong&gt;. E un&amp;rsquo;immagine non è solo la tua app: è la tua app &lt;em&gt;più&lt;/em&gt; un sistema operativo,
librerie, utility. Ogni pacchetto incluso è codice che può avere vulnerabilità e che un attaccante può
sfruttare una volta dentro. La regola guida è semplice: &lt;strong&gt;meno c&amp;rsquo;è nell&amp;rsquo;immagine, meno c&amp;rsquo;è da
attaccare&lt;/strong&gt;. Questo poggia sul modello di &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/container-networking/&#34; &gt;networking dei container&lt;/a&gt;
già visto; qui ci concentriamo sull&amp;rsquo;immagine come superficie.&lt;/p&gt;
&lt;h2 id=&#34;il-peso-dellimmagine-di-base&#34;&gt;Il peso dell&amp;rsquo;immagine di base
&lt;/h2&gt;&lt;pre class=&#34;mermaid&#34;&gt;
  flowchart TD
    A[&amp;#34;FROM ubuntu&amp;lt;br/&amp;gt;~400 pacchetti, shell,&amp;lt;br/&amp;gt;package manager&amp;#34;] --&amp;gt; A1[Grande superficie:&amp;lt;br/&amp;gt;molti CVE, strumenti&amp;lt;br/&amp;gt;utili all&amp;#39;attaccante]
    B[&amp;#34;FROM distroless/static&amp;lt;br/&amp;gt;solo libc + la tua app&amp;#34;] --&amp;gt; B1[Superficie minima:&amp;lt;br/&amp;gt;niente shell,&amp;lt;br/&amp;gt;pochi/zero CVE OS]
    style A1 fill:#fde2e4,stroke:#e63946
    style B1 fill:#e8f0fe,stroke:#4361ee
&lt;/pre&gt;

&lt;p&gt;Un&amp;rsquo;immagine basata su una distribuzione completa porta centinaia di pacchetti che l&amp;rsquo;app non usa — ma
che l&amp;rsquo;attaccante sì: una shell per muoversi, &lt;code&gt;curl&lt;/code&gt; per scaricare payload, un package manager per
installare strumenti. Un&amp;rsquo;immagine &lt;strong&gt;distroless&lt;/strong&gt; (o &lt;code&gt;scratch&lt;/code&gt; per i binari statici) contiene solo
l&amp;rsquo;app e lo stretto indispensabile: niente shell significa niente &lt;code&gt;kubectl exec&lt;/code&gt; in una shell, molto
meno con cui lavorare dopo una compromissione.&lt;/p&gt;
&lt;h2 id=&#34;il-multi-stage-build&#34;&gt;Il multi-stage build
&lt;/h2&gt;&lt;p&gt;Lo strumento che rende tutto questo pratico: compilare in un&amp;rsquo;immagine ricca, spedire in una minimale.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-dockerfile&#34; data-lang=&#34;dockerfile&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;# stage di build: ha compilatore, strumenti, dipendenze di sviluppo&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;s&#34;&gt; golang:1.23 AS build&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;WORKDIR&lt;/span&gt;&lt;span class=&#34;s&#34;&gt; /src&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;COPY&lt;/span&gt; . .&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;RUN&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;CGO_ENABLED&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; go build -o /app ./cmd/server&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# stage finale: SOLO il binario, su base minimale, utente non-root&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;s&#34;&gt; gcr.io/distroless/static:nonroot&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;COPY&lt;/span&gt; --from&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;build /app /app&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;USER&lt;/span&gt;&lt;span class=&#34;s&#34;&gt; nonroot&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ENTRYPOINT&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;/app&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Le righe evidenziate sono il punto: gli strumenti di build restano nello stage &lt;code&gt;build&lt;/code&gt; e non arrivano
in produzione; l&amp;rsquo;immagine finale ha solo il binario, gira come utente &lt;strong&gt;non-root&lt;/strong&gt;, e non ha né shell
né package manager da sfruttare.&lt;/p&gt;
&lt;h2 id=&#34;scansione-delle-vulnerabilità-dellimmagine&#34;&gt;Scansione delle vulnerabilità dell&amp;rsquo;immagine
&lt;/h2&gt;&lt;p&gt;Oltre a minimizzare, si scansiona. Uno scanner (Trivy, Grype) ispeziona i layer e trova i CVE nei
pacchetti OS e nelle dipendenze applicative — è la &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/sca-e-dipendenze/&#34; &gt;SCA&lt;/a&gt;
applicata all&amp;rsquo;immagine assemblata, non solo al manifest. Si colloca:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;In pipeline&lt;/strong&gt;, come gate dopo la build: blocca il nuovo rischio critico.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Nel registry&lt;/strong&gt;, in continuo: un CVE nuovo può colpire un&amp;rsquo;immagine già pubblicata, come per la SBOM.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;le-altre-regole-doro&#34;&gt;Le altre regole d&amp;rsquo;oro
&lt;/h2&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;USER non-root        → mai processi come root nel container
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;tag immutabili       → riferire per digest (sha256), non per :latest mutabile
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;niente segreti       → mai chiavi nei layer (restano nella history dell&amp;#39;immagine!)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;filesystem read-only → l&amp;#39;app non deve scrivere sulla propria immagine
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;.dockerignore        → non copiare .git, .env, chiavi nel contesto di build
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Nota il parallelo con i segreti: un segreto copiato in un layer resta nell&amp;rsquo;immagine &lt;em&gt;per sempre&lt;/em&gt;, come
nella history di Git. L&amp;rsquo;immagine va trattata con la stessa cautela del repository.&lt;/p&gt;


&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Domanda:&lt;/strong&gt; le immagini distroless senza shell non rendono un incubo il debug in produzione? Quando qualcosa va storto non posso nemmeno aprire una shell nel container.&lt;/summary&gt;
&lt;p&gt;È lo scambio reale, e la risposta è che la cosa che rende il debug scomodo per te è esattamente ciò che
rende la vita difficile all&#39;attaccante — ma oggi non devi più scegliere tra le due. Partiamo dal perché
l&#39;assenza di shell è un bene: la stragrande maggioranza delle tecniche post-exploitation presuppone di
avere, dentro il container, una shell per esplorare, `curl`/`wget` per scaricare lo stadio successivo, un
package manager per installare strumenti. Toglierli non ferma un attaccante determinato, ma alza
nettamente il costo e il rumore di ogni suo movimento, e neutralizza del tutto gli automatismi che
contano sulla presenza di `/bin/sh`. Rinunciarci per comodità di debug significa lasciare armi in casa.
Detto questo, il debug non è compromesso: i runtime moderni offrono i &lt;em&gt;debug container effimeri&lt;/em&gt;
(in Kubernetes &lt;code&gt;kubectl debug&lt;/code&gt; con &lt;code&gt;ephemeral containers&lt;/code&gt;), che attaccano un
container temporaneo pieno di strumenti al pod in esecuzione, condividendone namespace e filesystem, senza
che quegli strumenti vivano mai nell&#39;immagine di produzione. Hai la shell quando ti serve, dove ti serve,
e sparisce quando hai finito — l&#39;immagine resta minimale. In aggiunta, la disciplina distroless spinge
verso un debug migliore a monte: logging strutturato, metriche ed endpoint di health invece dell&#39;ispezione
manuale via shell, che è comunque il modo in cui si opera un sistema a scala. Quindi: sì, cambi abitudine,
ma non perdi capacità — sposti gli strumenti di debug fuori dall&#39;immagine e li porti dentro solo quando
servono, ottenendo insieme operabilità e una superficie d&#39;attacco minima.&lt;/p&gt;
&lt;/details&gt;


&lt;h2 id=&#34;conclusione&#34;&gt;Conclusione
&lt;/h2&gt;&lt;p&gt;Un&amp;rsquo;immagine sicura è piccola per principio: distroless o scratch via multi-stage build, utente
non-root, niente segreti nei layer, riferita per digest, scansionata in pipeline e nel registry. Meno
contiene, meno offre all&amp;rsquo;attaccante. Ma l&amp;rsquo;immagine è solo metà della storia: una volta in esecuzione
nel cluster, conta &lt;em&gt;come&lt;/em&gt; gira. L&amp;rsquo;hardening di Kubernetes, prossimo capitolo.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Policy as code nella pipeline</title>
        <link>https://www.matteobianchi.eu/p/policy-as-code-pipeline/</link>
        <pubDate>Tue, 23 Jun 2026 09:00:00 +0200</pubDate>
        
        <guid>https://www.matteobianchi.eu/p/policy-as-code-pipeline/</guid>
        <description>&lt;img src="https://www.matteobianchi.eu/p/policy-as-code-pipeline/cover.png" alt="Featured image of post Policy as code nella pipeline" /&gt;&lt;h2 id=&#34;perché-conta&#34;&gt;Perché conta
&lt;/h2&gt;&lt;p&gt;Lo &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/iac-security/&#34; &gt;scanning dell&amp;rsquo;IaC&lt;/a&gt; applica regole &lt;em&gt;predefinite&lt;/em&gt;. Ma ogni
organizzazione ha regole &lt;em&gt;proprie&lt;/em&gt;: &amp;ldquo;solo immagini da registry approvati&amp;rdquo;, &amp;ldquo;ogni risorsa deve avere un
tag owner&amp;rdquo;, &amp;ldquo;niente security group aperti al mondo in produzione&amp;rdquo;. Scritte in una wiki, queste regole
non si applicano da sole: si violano per distrazione o per fretta. Il &lt;strong&gt;policy as code&lt;/strong&gt; le trasforma
in codice versionato, testabile e applicato automaticamente. È il tema generale di cui avevamo già
parlato con &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/policy-as-code-con-opa/&#34; &gt;OPA&lt;/a&gt;; qui lo mettiamo al lavoro nella
pipeline.&lt;/p&gt;
&lt;h2 id=&#34;il-pattern-pdppep-di-nuovo&#34;&gt;Il pattern PDP/PEP, di nuovo
&lt;/h2&gt;&lt;p&gt;Il policy as code è lo stesso schema &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/pdp-pep-il-motore-delle-policy/&#34; &gt;PDP/PEP&lt;/a&gt;
dello Zero Trust, applicato agli artefatti e alle configurazioni invece che agli accessi di rete:&lt;/p&gt;
&lt;pre class=&#34;mermaid&#34;&gt;
  flowchart LR
    CI[Step pipeline&amp;lt;br/&amp;gt;PEP] --&amp;gt;|&amp;#34;questo manifest/&amp;lt;br/&amp;gt;immagine è conforme?&amp;#34;| OPA[OPA&amp;lt;br/&amp;gt;PDP]
    POL[(Policy in Rego&amp;lt;br/&amp;gt;versionate in git)] --&amp;gt; OPA
    OPA --&amp;gt;|consenti / nega&amp;lt;br/&amp;gt;+ motivazione| CI
    CI --&amp;gt;|se nega| STOP[Build fallita&amp;lt;br/&amp;gt;con messaggio chiaro]
    style OPA fill:#fde2e4,stroke:#e63946
&lt;/pre&gt;

&lt;p&gt;La pipeline è il &lt;strong&gt;PEP&lt;/strong&gt; (chiede e applica); OPA è il &lt;strong&gt;PDP&lt;/strong&gt; (decide in base alle policy). Le policy
vivono in git: revisionate con pull request, testate, con una history di chi le ha cambiate e perché.&lt;/p&gt;
&lt;h2 id=&#34;rego-la-regola-come-codice&#34;&gt;Rego: la regola come codice
&lt;/h2&gt;&lt;p&gt;OPA usa &lt;strong&gt;Rego&lt;/strong&gt;, un linguaggio dichiarativo. Una policy nega finché una condizione non è soddisfatta:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-rego&#34; data-lang=&#34;rego&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;package&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;pipeline&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# nega qualunque immagine non firmata o da registry non approvato&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;deny&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;msg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;not&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;input&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;signed&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;msg&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;sprintf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;immagine %v non firmata&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;input&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ref&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Il risultato non è un booleano muto ma un &lt;strong&gt;messaggio azionabile&lt;/strong&gt;: lo sviluppatore legge &lt;em&gt;perché&lt;/em&gt; la
build è fallita e &lt;em&gt;come&lt;/em&gt; rimediare. Questo distingue un guardrail utile da un cancello frustrante.&lt;/p&gt;
&lt;h2 id=&#34;cosa-si-esprime-come-policy&#34;&gt;Cosa si esprime come policy
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Sugli artefatti&lt;/strong&gt;: solo immagini firmate (&lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/firma-artefatti-sigstore/&#34; &gt;Sigstore&lt;/a&gt;),
con SBOM presente, senza CVE critici, da basi approvate.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sui manifest Kubernetes&lt;/strong&gt;: niente container privilegiati, niente &lt;code&gt;latest&lt;/code&gt;, limiti di risorse
obbligatori, nessun segreto in chiaro.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sull&amp;rsquo;IaC&lt;/strong&gt;: le regole su misura che lo scanner generico non conosce (le &lt;em&gt;tue&lt;/em&gt; convenzioni di tag,
di naming, di rete).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Strumenti come &lt;strong&gt;Conftest&lt;/strong&gt; valutano file di configurazione (YAML, JSON, HCL, Dockerfile) contro
policy Rego direttamente in pipeline, con un comando.&lt;/p&gt;
&lt;h2 id=&#34;testare-le-policy&#34;&gt;Testare le policy
&lt;/h2&gt;&lt;p&gt;Il vantaggio decisivo del policy as code è che le policy stesse sono &lt;em&gt;testabili&lt;/em&gt;. Si scrivono casi —
&amp;ldquo;questo manifest deve passare&amp;rdquo;, &amp;ldquo;quest&amp;rsquo;altro deve essere rifiutato&amp;rdquo; — e si eseguono in CI. Una policy
senza test è fragile quanto codice senza test: può diventare troppo permissiva senza che nessuno se ne
accorga.&lt;/p&gt;
&lt;h2 id=&#34;un-motore-molti-punti-di-applicazione&#34;&gt;Un motore, molti punti di applicazione
&lt;/h2&gt;&lt;p&gt;La stessa policy (&amp;ldquo;solo immagini firmate&amp;rdquo;) può valere nella pipeline &lt;em&gt;e&lt;/em&gt; all&amp;rsquo;ingresso del cluster via
&lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/admission-control/&#34; &gt;admission control&lt;/a&gt;. Un solo linguaggio, un solo repository di
regole, più punti di enforcement: è la coerenza che rende governabile la sicurezza su scala, invece di
regole scollegate ripetute in dieci posti.&lt;/p&gt;


&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Domanda:&lt;/strong&gt; se la policy as code può bloccare le build, chi impedisce che una regola troppo severa (o un bug in una policy) fermi tutti i deploy dell&#39;azienda?&lt;/summary&gt;
&lt;p&gt;È un rischio concreto — una policy è codice con potere di veto sulla consegna — e si gestisce con le
stesse pratiche che rendono sicuro qualunque altro codice critico, più alcune specifiche. Primo: le policy
si trattano come software, non come configurazione sacra. Vivono in git, passano da pull request con
revisione, e hanno &lt;em&gt;test propri&lt;/em&gt;: casi che devono passare e casi che devono essere rifiutati,
eseguiti in CI a ogni modifica della policy stessa. Una regola troppo severa si manifesta come un test
rosso prima di arrivare in produzione, esattamente come una regressione in un servizio. Secondo: le policy
si rilasciano in modo graduale. Una regola nuova parte in modalità &lt;em&gt;warn&lt;/em&gt; (segnala ma non blocca),
si osserva quanto e cosa catturerebbe sui deploy reali per un periodo, e solo quando i falsi positivi sono
sotto controllo si promuove a &lt;em&gt;enforce&lt;/em&gt;. Questo evita il blocco a sorpresa dell&#39;intera azienda al
primo giorno. Terzo: serve una via di emergenza esplicita e tracciata — un meccanismo di eccezione o di
break-glass che permetta, con approvazione e audit, di scavalcare una policy quando è palesemente lei a
sbagliare durante un incidente, invece di lasciare l&#39;unica scelta tra &#34;bloccati tutti&#34; e &#34;disattiviamo
tutto&#34;. Quarto, la scelta del comportamento di default per fase: in pipeline spesso conviene fail-closed
sulle regole di sicurezza critiche (meglio una build bloccata che un&#39;immagine non firmata in produzione),
ma la decisione va presa consapevolmente regola per regola, non subita. Il punto di fondo: il potere di
bloccare è esattamente ciò che rende la policy utile — una regola che non può fermare nulla non è un
controllo, è un suggerimento — quindi la risposta non è togliere il potere, è circondarlo di test, rollout
graduale e vie di fuga, come si fa con ogni cosa che può rompere la produzione.&lt;/p&gt;
&lt;/details&gt;


&lt;h2 id=&#34;conclusione&#34;&gt;Conclusione
&lt;/h2&gt;&lt;p&gt;Il policy as code trasforma le regole dell&amp;rsquo;organizzazione in codice versionato, testato e applicato:
lo schema PDP/PEP portato nella pipeline, con messaggi azionabili e un solo repository di regole per
più punti di enforcement. Abbiamo blindato codice, artefatti e pipeline. Ora quegli artefatti devono
girare, e il primo è quasi sempre un container: la sicurezza delle immagini, prossimo capitolo.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Sicurezza dell&#39;Infrastructure as Code</title>
        <link>https://www.matteobianchi.eu/p/iac-security/</link>
        <pubDate>Tue, 16 Jun 2026 09:00:00 +0200</pubDate>
        
        <guid>https://www.matteobianchi.eu/p/iac-security/</guid>
        <description>&lt;img src="https://www.matteobianchi.eu/p/iac-security/cover.png" alt="Featured image of post Sicurezza dell&#39;Infrastructure as Code" /&gt;&lt;h2 id=&#34;perché-conta&#34;&gt;Perché conta
&lt;/h2&gt;&lt;p&gt;La &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/sicurezza-pipeline-ci-cd/&#34; &gt;pipeline&lt;/a&gt; non costruisce solo applicazioni:
costruisce anche l&amp;rsquo;&lt;strong&gt;infrastruttura&lt;/strong&gt;, ormai definita come codice — Terraform, CloudFormation,
Pulumi, manifest Kubernetes. È una grande notizia per la sicurezza: se l&amp;rsquo;infrastruttura è codice,
possiamo analizzarla come codice, &lt;em&gt;prima&lt;/em&gt; del deploy. È anche un rischio nuovo: un errore in un
modulo riusato si replica identico su ogni ambiente, trasformando un singolo sbaglio in una falla
sistemica.&lt;/p&gt;
&lt;h2 id=&#34;lerrore-si-moltiplica&#34;&gt;L&amp;rsquo;errore si moltiplica
&lt;/h2&gt;&lt;pre class=&#34;mermaid&#34;&gt;
  flowchart TD
    M[&amp;#34;modulo-storage.tf&amp;lt;br/&amp;gt;(acl = public-read)&amp;#34;] --&amp;gt; A[Ambiente dev]
    M --&amp;gt; B[Ambiente staging]
    M --&amp;gt; C[Ambiente prod]
    A --&amp;gt; X1[Bucket pubblico]
    B --&amp;gt; X2[Bucket pubblico]
    C --&amp;gt; X3[Bucket pubblico&amp;lt;br/&amp;gt;con dati reali]
    style X3 fill:#fde2e4,stroke:#e63946
&lt;/pre&gt;

&lt;p&gt;Un bucket reso pubblico in un modulo condiviso diventa &lt;em&gt;tre&lt;/em&gt; bucket pubblici. Il lato positivo è
speculare: correggere il modulo e ripassare lo scanner mette in sicurezza tutti gli ambienti in un
colpo. L&amp;rsquo;IaC amplifica sia gli errori sia le correzioni.&lt;/p&gt;
&lt;h2 id=&#34;cosa-trova-lo-scanning-delliac&#34;&gt;Cosa trova lo scanning dell&amp;rsquo;IaC
&lt;/h2&gt;&lt;p&gt;Gli scanner statici (Checkov, tfsec, Terrascan, KICS) applicano centinaia di regole, spesso allineate
ai &lt;strong&gt;CIS Benchmark&lt;/strong&gt;, cercando le configurazioni pericolose più comuni:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-hcl&#34; data-lang=&#34;hcl&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;resource&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;aws_s3_bucket_public_access_block&amp;#34; &amp;#34;ex&amp;#34;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;  bucket&lt;/span&gt;                  &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;aws_s3_bucket&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;  block_public_acls&lt;/span&gt;       &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;   # ← lo scanner segnala: accesso pubblico possibile
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;  restrict_public_buckets&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;   # ← idem
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Difetti tipici: storage pubblico, security group con &lt;code&gt;0.0.0.0/0&lt;/code&gt; su porte di gestione, cifratura a
riposo disattivata, log disabilitati, ruoli IAM troppo ampi, assenza di tag. Sono &lt;em&gt;misconfiguration&lt;/em&gt;,
non bug di codice: il SAST non le vede, perché il &amp;ldquo;codice&amp;rdquo; qui descrive infrastruttura, non logica.&lt;/p&gt;
&lt;h2 id=&#34;dove-collocarlo&#34;&gt;Dove collocarlo
&lt;/h2&gt;&lt;p&gt;Come il SAST, l&amp;rsquo;IaC scanning dà il meglio presto e in modo incrementale:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Pre-commit / IDE&lt;/strong&gt;: feedback immediato mentre si scrive il Terraform.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pull request&lt;/strong&gt;: gate che blocca il &lt;em&gt;nuovo&lt;/em&gt; rischio alto, con baseline sul debito esistente.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pre-apply nella pipeline&lt;/strong&gt;: ultimo controllo prima di toccare l&amp;rsquo;infrastruttura reale, idealmente
anche sul &lt;em&gt;piano&lt;/em&gt; (&lt;code&gt;terraform plan&lt;/code&gt;) per vedere l&amp;rsquo;effetto concreto, non solo il sorgente.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;il-problema-spesso-dimenticato-lo-state&#34;&gt;Il problema spesso dimenticato: lo state
&lt;/h2&gt;&lt;p&gt;Il file di &lt;strong&gt;state&lt;/strong&gt; di Terraform contiene spesso dati sensibili in chiaro: password generate,
chiavi, output. Va trattato come un segreto: backend remoto cifrato, accesso ristretto, mai
committato nel repository. È l&amp;rsquo;errore IaC meno appariscente e più comune, perché non riguarda una
risorsa ma il &lt;em&gt;meccanismo stesso&lt;/em&gt; che le gestisce.&lt;/p&gt;
&lt;h2 id=&#34;il-limite-lo-statico-non-vede-il-reale&#34;&gt;Il limite: lo statico non vede il reale
&lt;/h2&gt;&lt;p&gt;Lo scanning dell&amp;rsquo;IaC vede ciò che il codice &lt;em&gt;dichiara&lt;/em&gt;, non ciò che esiste davvero nel cloud. Le
modifiche manuali (il famigerato &amp;ldquo;clic in console&amp;rdquo;) creano &lt;strong&gt;drift&lt;/strong&gt;: la realtà diverge dal codice, e
lo scanner, che legge solo il codice, non se ne accorge. Servono controlli a runtime sul cloud (CSPM)
e la disciplina di non modificare mai l&amp;rsquo;infrastruttura fuori dall&amp;rsquo;IaC. Il &amp;ldquo;cosa è dichiarato pericoloso&amp;rdquo;
è però esprimibile come regola generale, e questo apre il tema del prossimo capitolo: le policy as code.&lt;/p&gt;


&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Domanda:&lt;/strong&gt; se lo scanner IaC non vede il drift e le modifiche manuali, posso fidarmi che un &#34;piano pulito&#34; significhi infrastruttura sicura?&lt;/summary&gt;
&lt;p&gt;No, e confondere le due cose è una delle illusioni di sicurezza più comuni con l&#39;IaC. Uno scanner che
passa sul tuo Terraform dimostra una cosa precisa e limitata: che &lt;em&gt;ciò che il codice descrive&lt;/em&gt; non
contiene le misconfigurazioni note alle sue regole. Non dimostra che l&#39;infrastruttura &lt;em&gt;reale&lt;/em&gt; sia
in quello stato, per tre motivi. Primo, il drift: qualcuno apre la console cloud e modifica a mano un
security group per &#34;sbloccare al volo&#34; un incidente, e non lo riporta mai nel codice; il tuo Terraform
resta pulito, il cloud no, e il prossimo apply potrebbe persino non toccare quella risorsa. Secondo, la
copertura: quasi nessuna infrastruttura è gestita al 100% da IaC — ci sono risorse create prima
dell&#39;adozione, risorse di altri team, cose fatte a mano &#34;temporaneamente&#34; tre anni fa; tutto ciò che non è
nel codice è invisibile allo scanner per definizione. Terzo, le regole hanno punti ciechi: lo scanner
trova le misconfigurazioni che conosce, non la logica di autorizzazione sbagliata o la combinazione
insolita di risorse che crea un percorso d&#39;attacco non previsto da nessuna singola regola. La risposta
corretta è usare due lenti complementari: lo scanning statico dell&#39;IaC come controllo &lt;em&gt;preventivo&lt;/em&gt;
sul codice prima del deploy (economico, precoce, ferma l&#39;errore prima che esista), e un controllo
&lt;em&gt;a runtime&lt;/em&gt; sul cloud reale — un CSPM che interroga le API del provider e confronta lo stato
effettivo con le policy — come rete che cattura drift, risorse fuori IaC e deviazioni. Più la disciplina
organizzativa di vietare le modifiche manuali e far passare ogni cambiamento dall&#39;IaC, così il drift
tende a zero. Un piano pulito è una condizione necessaria, non sufficiente: ti dice che non stai
&lt;em&gt;introducendo&lt;/em&gt; un problema noto, non che non ne hai già uno in produzione.&lt;/p&gt;
&lt;/details&gt;


&lt;h2 id=&#34;conclusione&#34;&gt;Conclusione
&lt;/h2&gt;&lt;p&gt;L&amp;rsquo;IaC rende l&amp;rsquo;infrastruttura analizzabile prima del deploy: gli scanner trovano bucket pubblici,
security group aperti e cifratura mancante, e una correzione al modulo mette in sicurezza ogni
ambiente. Ma lo statico non vede il drift, e le regole predefinite non conoscono le &lt;em&gt;tue&lt;/em&gt; policy. Per
esprimere ed applicare regole su misura — nella pipeline e nel cluster — serve un motore di policy
generale. È il policy as code, prossimo capitolo.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Sicurezza della pipeline CI/CD</title>
        <link>https://www.matteobianchi.eu/p/sicurezza-pipeline-ci-cd/</link>
        <pubDate>Tue, 09 Jun 2026 09:00:00 +0200</pubDate>
        
        <guid>https://www.matteobianchi.eu/p/sicurezza-pipeline-ci-cd/</guid>
        <description>&lt;img src="https://www.matteobianchi.eu/p/sicurezza-pipeline-ci-cd/cover.png" alt="Featured image of post Sicurezza della pipeline CI/CD" /&gt;&lt;h2 id=&#34;perché-conta&#34;&gt;Perché conta
&lt;/h2&gt;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/supply-chain-slsa/&#34; &gt;SLSA&lt;/a&gt; e &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/firma-artefatti-sigstore/&#34; &gt;Sigstore&lt;/a&gt;
rendono la build verificabile, ma restano un presupposto: che la pipeline stessa non sia già
compromessa. Ed è un bersaglio ideale. La CI/CD legge il codice sorgente, custodisce i segreti di
produzione, e ha il diritto di &lt;strong&gt;deployare&lt;/strong&gt;. Chi controlla la pipeline non ha bisogno di bucare la
produzione: ci arriva passando dalla porta principale. Eppure è spesso l&amp;rsquo;ambiente meno indurito di
tutti.&lt;/p&gt;
&lt;h2 id=&#34;perché-è-un-bersaglio-così-ricco&#34;&gt;Perché è un bersaglio così ricco
&lt;/h2&gt;&lt;pre class=&#34;mermaid&#34;&gt;
  flowchart TD
    P[Pipeline CI/CD] --&amp;gt; C[Accesso a TUTTO&amp;lt;br/&amp;gt;il codice sorgente]
    P --&amp;gt; S[Segreti di produzione:&amp;lt;br/&amp;gt;cloud, registry, DB]
    P --&amp;gt; D[Diritto di DEPLOY&amp;lt;br/&amp;gt;in produzione]
    P --&amp;gt; X[Esegue codice&amp;lt;br/&amp;gt;da PR non fidate]
    style P fill:#fde2e4,stroke:#e63946
&lt;/pre&gt;

&lt;p&gt;Un solo ambiente concentra accesso al codice, segreti potenti e privilegi di deploy. E in più esegue
codice fornito da altri: un contributo esterno, una dipendenza di build, uno script in un workflow.
Questa combinazione — alti privilegi &lt;em&gt;ed&lt;/em&gt; esecuzione di codice non fidato — è esattamente ciò che si
evita in ogni altro sistema.&lt;/p&gt;
&lt;h2 id=&#34;i-controlli-che-contano&#34;&gt;I controlli che contano
&lt;/h2&gt;&lt;h3 id=&#34;1-runner-effimeri&#34;&gt;1. Runner effimeri
&lt;/h3&gt;&lt;p&gt;Un runner persistente accumula stato tra una build e l&amp;rsquo;altra: segreti in cache, file lasciati,
processi. Un job malevolo può lasciare una backdoor che colpisce i job successivi. I &lt;strong&gt;runner
effimeri&lt;/strong&gt; nascono puliti per ogni job e muoiono subito dopo: niente stato da avvelenare. È anche un
requisito per i livelli alti di SLSA.&lt;/p&gt;
&lt;h3 id=&#34;2-minimo-privilegio-dei-token&#34;&gt;2. Minimo privilegio dei token
&lt;/h3&gt;&lt;p&gt;Il token di un job dovrebbe potere &lt;em&gt;esattamente&lt;/em&gt; ciò che serve a quel job e nulla più:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;# GitHub Actions: permessi espliciti e minimi per job&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;permissions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;contents&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;read     &lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# legge il codice, non lo scrive&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;id-token&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;write    &lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# per OIDC (firma / deploy), niente segreti statici&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# tutto il resto: negato di default&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Il default di molte pipeline è l&amp;rsquo;opposto: un token onnipotente usato da ogni job. Restringere per job
limita il danno di un singolo step compromesso.&lt;/p&gt;
&lt;h3 id=&#34;3-oidc-invece-di-chiavi-statiche&#34;&gt;3. OIDC invece di chiavi statiche
&lt;/h3&gt;&lt;p&gt;Mettere le chiavi cloud di lungo termine nei secret della CI è un rischio permanente. Con &lt;strong&gt;OIDC&lt;/strong&gt; la
pipeline prova la propria identità al cloud provider e riceve credenziali &lt;em&gt;temporanee&lt;/em&gt; per quel job:
niente chiave statica da rubare, stesso principio della firma keyless di Sigstore.&lt;/p&gt;
&lt;h3 id=&#34;4-difesa-dai-workflow-da-pr-non-fidate&#34;&gt;4. Difesa dai workflow da PR non fidate
&lt;/h3&gt;&lt;p&gt;Le pull request da fork sono codice ostile potenziale. Regole essenziali: non dare i segreti ai
workflow innescati da PR esterne, richiedere l&amp;rsquo;approvazione manuale prima di eseguirli, e &lt;strong&gt;fissare le
action a un hash&lt;/strong&gt; (&lt;code&gt;uses: actions/checkout@&amp;lt;sha&amp;gt;&lt;/code&gt;), non a un tag mutabile che un attaccante potrebbe
spostare.&lt;/p&gt;
&lt;h2 id=&#34;la-disciplina-delle-action-di-terze-parti&#34;&gt;La disciplina delle action di terze parti
&lt;/h2&gt;&lt;p&gt;Ogni &lt;code&gt;uses:&lt;/code&gt; nella pipeline è codice di terzi con l&amp;rsquo;accesso del job. Un tag come &lt;code&gt;@v3&lt;/code&gt; può essere
ri-puntato dall&amp;rsquo;autore (o da chi lo compromette) a codice diverso. Fissare all&amp;rsquo;hash del commit rende
immutabile ciò che gira, e va trattato come una dipendenza qualsiasi: inventariato, aggiornato con
giudizio, verificato.&lt;/p&gt;


&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Domanda:&lt;/strong&gt; fissare ogni action a un hash e dare permessi minimi a ogni job sembra tanta frizione; con decine di repository, non diventa ingestibile?&lt;/summary&gt;
&lt;p&gt;La frizione è reale ma è un costo di configurazione una tantum, mentre il rischio che elimina è
permanente e si realizza nel modo peggiore — e la soluzione alla scala non è rinunciarvi, è
automatizzarlo. Prendi il pinning all&#39;hash: sì, un tag è più comodo di uno sha, ma un tag è
&lt;em&gt;mutabile&lt;/em&gt;, e la storia recente è piena di action e pacchetti il cui tag è stato ripuntato a codice
malevolo dopo che migliaia di pipeline lo usavano già — con l&#39;accesso completo del job, inclusi i segreti.
Il pinning trasforma &#34;eseguo qualunque cosa ci sia dietro v3 oggi&#34; in &#34;eseguo esattamente questo commit
che ho verificato&#34;. Alla scala di decine di repo non lo fai a mano: lo fai con gli stessi strumenti che
già usi per le dipendenze — Renovate o Dependabot aggiornano gli hash con pull request testate, esattamente
come fanno con le librerie, così resti aggiornato senza fidarti ciecamente di un tag. Lo stesso per i
permessi minimi: non li scrivi repo per repo, li imponi con una policy organizzativa — permessi di default
a sola lettura a livello di org, template di workflow condivisi, e un controllo in pipeline (anche OPA)
che segnala i job con permessi eccessivi. Il punto è che la pipeline è l&#39;ambiente a più alto privilegio
che hai: concentra codice, segreti e diritto di deploy. È esattamente il posto dove la frizione di
configurazione è giustificata, perché un singolo step compromesso qui non è un bug in un servizio, è
l&#39;accesso a tutti i servizi. La domanda da ribaltare è: con decine di repository che possono deployare in
produzione, puoi permetterti che &lt;em&gt;non&lt;/em&gt; siano induriti?&lt;/p&gt;
&lt;/details&gt;


&lt;h2 id=&#34;conclusione&#34;&gt;Conclusione
&lt;/h2&gt;&lt;p&gt;La pipeline concentra codice, segreti e diritto di deploy, ed esegue codice non fidato: va trattata
come l&amp;rsquo;ambiente più critico, non il più trascurato. Runner effimeri, token a privilegio minimo, OIDC
al posto delle chiavi statiche e action fissate all&amp;rsquo;hash sono i controlli base. Una classe di
protezione merita un capitolo a sé, perché gran parte dell&amp;rsquo;infrastruttura oggi nasce da codice:
l&amp;rsquo;Infrastructure as Code e i suoi rischi, prossimo capitolo.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Firmare gli artefatti con Sigstore</title>
        <link>https://www.matteobianchi.eu/p/firma-artefatti-sigstore/</link>
        <pubDate>Tue, 02 Jun 2026 09:00:00 +0200</pubDate>
        
        <guid>https://www.matteobianchi.eu/p/firma-artefatti-sigstore/</guid>
        <description>&lt;img src="https://www.matteobianchi.eu/p/firma-artefatti-sigstore/cover.png" alt="Featured image of post Firmare gli artefatti con Sigstore" /&gt;&lt;h2 id=&#34;perché-conta&#34;&gt;Perché conta
&lt;/h2&gt;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/supply-chain-slsa/&#34; &gt;SLSA&lt;/a&gt; richiede provenienza &lt;em&gt;firmata&lt;/em&gt;, e la
&lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/sbom-trasparenza/&#34; &gt;SBOM&lt;/a&gt; vale di più se firmata e legata all&amp;rsquo;artefatto. Ma la
firma crittografica aveva un problema pratico che l&amp;rsquo;ha resa rara: per firmare serve una chiave
privata, e custodire chiavi a lungo termine (rotazione, revoca, HSM, il rischio che trapelino) è un
onere che quasi nessun team si assumeva. &lt;strong&gt;Sigstore&lt;/strong&gt; elimina proprio quell&amp;rsquo;onere.&lt;/p&gt;
&lt;h2 id=&#34;lidea-firma-keyless&#34;&gt;L&amp;rsquo;idea: firma keyless
&lt;/h2&gt;&lt;p&gt;Sigstore permette di firmare &lt;em&gt;senza gestire una chiave privata a lungo termine&lt;/em&gt;. Il meccanismo:&lt;/p&gt;
&lt;pre class=&#34;mermaid&#34;&gt;
  flowchart TD
    CI[Pipeline CI&amp;lt;br/&amp;gt;identità OIDC] --&amp;gt;|provami chi sei| F[Fulcio&amp;lt;br/&amp;gt;CA]
    F --&amp;gt;|certificato a vita&amp;lt;br/&amp;gt;brevissima ~minuti| CI
    CI --&amp;gt;|firma l&amp;#39;artefatto&amp;lt;br/&amp;gt;con quel cert| SIG[Firma]
    SIG --&amp;gt;|registra firma+cert| R[Rekor&amp;lt;br/&amp;gt;log pubblico&amp;lt;br/&amp;gt;a prova di manomissione]
    R --&amp;gt; V[Chiunque può&amp;lt;br/&amp;gt;verificare dopo]
    style R fill:#fde2e4,stroke:#e63946
&lt;/pre&gt;

&lt;ol&gt;
&lt;li&gt;La pipeline prova la propria identità via &lt;strong&gt;OIDC&lt;/strong&gt; (es. &amp;ldquo;sono la GitHub Action del repo X&amp;rdquo;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Fulcio&lt;/strong&gt;, una CA, emette un certificato a vita &lt;em&gt;brevissima&lt;/em&gt; (minuti) legato a quell&amp;rsquo;identità.&lt;/li&gt;
&lt;li&gt;Si firma l&amp;rsquo;artefatto con quel certificato effimero; la chiave privata sparisce subito dopo.&lt;/li&gt;
&lt;li&gt;La firma e il certificato vengono registrati in &lt;strong&gt;Rekor&lt;/strong&gt;, un log pubblico, append-only, a prova
di manomissione (lo stesso principio del transparency log).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Nessuna chiave da custodire: l&amp;rsquo;identità sostituisce la chiave a lungo termine, e il certificato vive
troppo poco per valere la pena di rubarlo.&lt;/p&gt;
&lt;h2 id=&#34;firmare-e-verificare-con-cosign&#34;&gt;Firmare e verificare con cosign
&lt;/h2&gt;&lt;p&gt;In pratica, dalla pipeline:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# firma keyless: l&amp;#39;identità OIDC della CI diventa il firmatario&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;cosign sign --yes registry.io/app@sha256:abc...
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# verifica: accetta solo artefatti firmati dall&amp;#39;identità attesa&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;cosign verify registry.io/app@sha256:abc... &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;  --certificate-identity &lt;span class=&#34;s2&#34;&gt;&amp;#34;https://github.com/org/repo/.github/workflows/release.yml@refs/heads/main&amp;#34;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;  --certificate-oidc-issuer &lt;span class=&#34;s2&#34;&gt;&amp;#34;https://token.actions.githubusercontent.com&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;La verifica è il punto che conta: non &amp;ldquo;è firmato?&amp;rdquo; ma &amp;ldquo;è firmato &lt;strong&gt;dall&amp;rsquo;identità che mi aspetto&lt;/strong&gt;?&amp;rdquo;.
Un artefatto firmato da un&amp;rsquo;identità sconosciuta va rifiutato esattamente come uno non firmato. cosign
firma e verifica allo stesso modo anche le &lt;strong&gt;SBOM&lt;/strong&gt; e le &lt;strong&gt;attestazioni&lt;/strong&gt; di provenienza SLSA,
allegandole all&amp;rsquo;immagine nel registry.&lt;/p&gt;
&lt;h2 id=&#34;dove-si-applica-nel-ciclo&#34;&gt;Dove si applica nel ciclo
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Al rilascio&lt;/strong&gt;: la pipeline firma l&amp;rsquo;immagine, la SBOM e la provenienza subito dopo la build.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;All&amp;rsquo;ingresso&lt;/strong&gt;: l&amp;rsquo;&lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/admission-control/&#34; &gt;admission control&lt;/a&gt; del cluster
verifica la firma e rifiuta ciò che non proviene dall&amp;rsquo;identità attesa. È qui che la firma smette di
essere decorativa e diventa un controllo di accesso.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;il-limite-la-firma-attesta-lorigine-non-la-bontà&#34;&gt;Il limite: la firma attesta l&amp;rsquo;origine, non la bontà
&lt;/h2&gt;&lt;p&gt;Una firma valida dice &amp;ldquo;questo artefatto viene davvero da chi dice&amp;rdquo; — non &amp;ldquo;questo artefatto è privo di
vulnerabilità&amp;rdquo;. Si può firmare perfettamente un&amp;rsquo;immagine piena di CVE. La firma risolve &lt;em&gt;autenticità e
integrità&lt;/em&gt;, non &lt;em&gt;qualità&lt;/em&gt;: va combinata con SCA, SBOM e policy, non le sostituisce.&lt;/p&gt;


&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Domanda:&lt;/strong&gt; se la firma usa l&#39;identità OIDC della pipeline invece di una chiave che custodisco io, non sto solo spostando la fiducia su GitHub/Fulcio/Rekor? Cosa impedisce a chi li compromette di firmare qualunque cosa?&lt;/summary&gt;
&lt;p&gt;Stai spostando la fiducia, sì, ma verso componenti progettati per essere difendibili e — soprattutto —
&lt;em&gt;osservabili&lt;/em&gt;, il che cambia la natura del rischio. Primo: la fiducia nell&#39;identità OIDC non è
peggiore di prima, è migliore. Con una chiave privata a lungo termine il rischio era una stringa che
poteva trapelare da un file di config, un backup, un laptop, e restare valida per mesi senza che nessuno
se ne accorgesse; con la firma keyless non esiste nessun segreto persistente da rubare, e il certificato
vive minuti. Un attaccante dovrebbe compromettere l&#39;identità della pipeline &lt;em&gt;nel momento&lt;/em&gt; della
build — il che è un problema di sicurezza della CI/CD che hai comunque, firma o no. Secondo, ed è il punto
di Rekor: ogni firma finisce in un log pubblico, append-only, a prova di manomissione. Se qualcuno
riuscisse a firmare un artefatto malevolo con la tua identità, quella firma sarebbe &lt;em&gt;pubblicamente
registrata&lt;/em&gt;, con l&#39;identità e l&#39;istante, visibile a te e a chiunque monitori il log — un attacco non
ripudiabile e rilevabile, non un furto silenzioso di chiave che scopri sei mesi dopo. Terzo, la verifica
è vincolata: non accetti &#34;una firma qualsiasi&#34;, accetti solo l&#39;identità esatta (quel repo, quel workflow,
quel branch), quindi compromettere &#34;GitHub in generale&#34; non basta, serve proprio la tua identità precisa.
Resta vero che Fulcio e Rekor sono radici di fiducia: se vengono compromessi a livello di infrastruttura,
il modello vacilla — ma sono gestiti come infrastruttura critica, replicati e monitorati, e puoi anche
operarne istanze tue. Il confronto corretto non è &#34;fiducia zero contro fiducia in Sigstore&#34;, è &#34;una chiave
privata fragile e silenziosa che custodisci male contro un&#39;identità effimera registrata pubblicamente&#34;:
la seconda sposta la fiducia su qualcosa di più piccolo, più breve nel tempo e, decisivo, verificabile a
posteriori da tutti.&lt;/p&gt;
&lt;/details&gt;


&lt;h2 id=&#34;conclusione&#34;&gt;Conclusione
&lt;/h2&gt;&lt;p&gt;Sigstore rende la firma pratica eliminando le chiavi da custodire: identità effimera via Fulcio, log
pubblico via Rekor, firma e verifica di immagini, SBOM e provenienza con cosign. La firma attesta
l&amp;rsquo;origine, non la qualità, e diventa un controllo solo quando qualcuno la &lt;em&gt;verifica&lt;/em&gt; all&amp;rsquo;ingresso. Con
artefatti verificabili in mano, il tema si sposta su dove tutto questo si orchestra e dove un
attaccante punterebbe per primo: la pipeline CI/CD stessa, prossimo capitolo.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Supply chain e SLSA: fidarsi della build</title>
        <link>https://www.matteobianchi.eu/p/supply-chain-slsa/</link>
        <pubDate>Tue, 26 May 2026 09:00:00 +0200</pubDate>
        
        <guid>https://www.matteobianchi.eu/p/supply-chain-slsa/</guid>
        <description>&lt;img src="https://www.matteobianchi.eu/p/supply-chain-slsa/cover.png" alt="Featured image of post Supply chain e SLSA: fidarsi della build" /&gt;&lt;h2 id=&#34;perché-conta&#34;&gt;Perché conta
&lt;/h2&gt;&lt;p&gt;La &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/sbom-trasparenza/&#34; &gt;SBOM&lt;/a&gt; dice &lt;em&gt;cosa&lt;/em&gt; c&amp;rsquo;è in un artefatto. Ma un attaccante
sofisticato non ha bisogno di inserire una dipendenza vulnerabile: gli basta compromettere la
&lt;strong&gt;pipeline&lt;/strong&gt; che costruisce l&amp;rsquo;artefatto, iniettando codice &lt;em&gt;dopo&lt;/em&gt; il sorgente pulito e &lt;em&gt;prima&lt;/em&gt;
dell&amp;rsquo;immagine finale. SolarWinds ha funzionato così: codice benigno nel repository, backdoor inserita
durante la build. &lt;strong&gt;SLSA&lt;/strong&gt; (Supply-chain Levels for Software Artifacts) esiste per rendere la build
stessa verificabile.&lt;/p&gt;
&lt;h2 id=&#34;la-superficie-dattacco-della-supply-chain&#34;&gt;La superficie d&amp;rsquo;attacco della supply chain
&lt;/h2&gt;&lt;p&gt;Ogni anello tra il codice di uno sviluppatore e l&amp;rsquo;artefatto in produzione è un bersaglio:&lt;/p&gt;
&lt;pre class=&#34;mermaid&#34;&gt;
  flowchart LR
    DEV[Sviluppatore] --&amp;gt;|1. commit&amp;lt;br/&amp;gt;compromesso| SRC[(Sorgente)]
    SRC --&amp;gt;|2. dipendenza&amp;lt;br/&amp;gt;malevola| BUILD[Sistema di build]
    BUILD --&amp;gt;|3. build&amp;lt;br/&amp;gt;compromessa| ART[Artefatto]
    ART --&amp;gt;|4. artefatto&amp;lt;br/&amp;gt;sostituito| REG[(Registry)]
    REG --&amp;gt;|5. deploy di&amp;lt;br/&amp;gt;un&amp;#39;immagine falsa| PROD[Produzione]
    style BUILD fill:#fde2e4,stroke:#e63946
&lt;/pre&gt;

&lt;p&gt;I controlli visti finora proteggono soprattutto l&amp;rsquo;anello 1-2 (il codice e le dipendenze). SLSA si
concentra sull&amp;rsquo;anello &lt;strong&gt;3-4&lt;/strong&gt;: garantire che l&amp;rsquo;artefatto in produzione sia &lt;em&gt;esattamente&lt;/em&gt; quello
prodotto dalla build attesa, a partire dal sorgente atteso, senza manomissioni intermedie.&lt;/p&gt;
&lt;h2 id=&#34;la-provenienza-il-documento-chiave&#34;&gt;La provenienza: il documento chiave
&lt;/h2&gt;&lt;p&gt;Il concetto centrale di SLSA è la &lt;strong&gt;provenance&lt;/strong&gt;: un documento, generato &lt;em&gt;dal sistema di build stesso&lt;/em&gt;
e firmato, che attesta &amp;ldquo;io, questa build, ho prodotto questo artefatto (hash X), da questo sorgente
(commit Y), con questi parametri&amp;rdquo;. Verificare la provenienza prima del deploy significa rifiutare
qualsiasi artefatto che non possa dimostrare la propria origine.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Provenance (semplificata):
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  artefatto:  sha256:abc...        ← cosa
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  sorgente:   git@...#commit def   ← da dove
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  builder:    github-actions@...   ← chi l&amp;#39;ha costruito
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  firmata dal builder → non falsificabile da chi non controlla il builder
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;i-livelli-di-slsa&#34;&gt;I livelli di SLSA
&lt;/h2&gt;&lt;p&gt;SLSA non è tutto-o-niente: è una scala che alza progressivamente le garanzie.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Livello 1 — provenienza presente&lt;/strong&gt;: la build genera la provenienza. Non ancora a prova di
manomissione, ma esiste e dà trasparenza.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Livello 2 — provenienza firmata&lt;/strong&gt;: generata da un servizio di build ospitato e &lt;em&gt;firmata&lt;/em&gt;, quindi
verificabile e non banalmente falsificabile.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Livello 3 — build indurita&lt;/strong&gt;: il sistema di build è isolato, le sorgenti e i parametri sono
verificati, la provenienza è &lt;em&gt;non falsificabile&lt;/em&gt; anche da chi ha accesso al progetto. È il livello
che avrebbe reso molto più difficile un attacco in stile SolarWinds.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;(Le revisioni del framework rinumerano e articolano i livelli, ma la direzione è costante: da &amp;ldquo;la
provenienza esiste&amp;rdquo; a &amp;ldquo;la provenienza è inattaccabile&amp;rdquo;.)&lt;/p&gt;
&lt;h2 id=&#34;cosa-significa-in-pratica&#34;&gt;Cosa significa in pratica
&lt;/h2&gt;&lt;p&gt;Salire di livello è soprattutto &lt;em&gt;disciplina di pipeline&lt;/em&gt;: build effimere e isolate (niente runner
persistenti che accumulano stato), nessuna modifica manuale all&amp;rsquo;artefatto, provenienza generata
automaticamente, deploy che &lt;em&gt;verifica&lt;/em&gt; la provenienza come gate. Molto di questo si appoggia alla
firma crittografica, il tassello del prossimo capitolo.&lt;/p&gt;


&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Domanda:&lt;/strong&gt; ho già SAST, SCA, code review e secret scanning sul mio codice; se il mio sorgente è pulito e controllato, perché dovrei preoccuparmi di SLSA e della build?&lt;/summary&gt;
&lt;p&gt;Perché tutti i controlli che hai elencato verificano il &lt;em&gt;sorgente&lt;/em&gt;, e la lezione di SolarWinds è
esattamente che il sorgente può essere immacolato mentre l&#39;artefatto spedito è compromesso. Tra il commit
che hai revisionato e l&#39;immagine che gira in produzione c&#39;è un intero sistema — il runner della CI, gli
script di build, la cache delle dipendenze, i plugin, le credenziali che pubblicano sul registry — e nulla
di ciò che fai sul sorgente lo protegge. Un attaccante che ottiene l&#39;accesso al sistema di build non ha
bisogno di toccare il tuo repository: inietta la backdoor &lt;em&gt;durante&lt;/em&gt; la compilazione, l&#39;artefatto
finale contiene codice che non comparirà mai in nessuna code review perché non è mai stato nel sorgente, e
la tua SBOM lo elencherà come se fosse legittimo. Lo stesso vale per l&#39;anello successivo: qualcuno che
compromette il registry può sostituire la tua immagine con un&#39;altra, e senza verifica della provenienza il
cluster la deploierà fiducioso. SLSA chiude proprio questo divario, ortogonale ai controlli sul codice: la
provenienza firmata lega l&#39;artefatto al commit esatto e alla build esatta, così al momento del deploy puoi
&lt;em&gt;rifiutare&lt;/em&gt; qualunque cosa non dimostri di essere nata dal tuo sorgente pulito attraverso la tua
build attesa. Non sostituisce SAST o SCA — quelli garantiscono che il sorgente sia buono — ma garantisce
che ciò che spedisci sia davvero quel sorgente e non qualcosa che gli somiglia. Senza, hai verificato
accuratamente l&#39;ingresso di un tubo di cui non controlli l&#39;uscita.&lt;/p&gt;
&lt;/details&gt;


&lt;h2 id=&#34;conclusione&#34;&gt;Conclusione
&lt;/h2&gt;&lt;p&gt;SLSA sposta la fiducia dal solo sorgente all&amp;rsquo;intera build: la provenienza firmata attesta cosa è stato
costruito, da dove e da chi, e i livelli alzano progressivamente le garanzie fino a renderla
inattaccabile. Ma &amp;ldquo;firmata&amp;rdquo; presuppone un sistema di firma che non richieda a ognuno di gestire chiavi
private — storicamente il motivo per cui quasi nessuno firmava. Sigstore risolve questo, prossimo
capitolo.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>SBOM: la distinta base del software</title>
        <link>https://www.matteobianchi.eu/p/sbom-trasparenza/</link>
        <pubDate>Tue, 19 May 2026 09:00:00 +0200</pubDate>
        
        <guid>https://www.matteobianchi.eu/p/sbom-trasparenza/</guid>
        <description>&lt;img src="https://www.matteobianchi.eu/p/sbom-trasparenza/cover.png" alt="Featured image of post SBOM: la distinta base del software" /&gt;&lt;h2 id=&#34;perché-conta&#34;&gt;Perché conta
&lt;/h2&gt;&lt;p&gt;Quando è uscito Log4Shell, la domanda che ha paralizzato migliaia di aziende non era &amp;ldquo;come si
corregge?&amp;rdquo; ma &amp;ldquo;&lt;strong&gt;dove ce l&amp;rsquo;ho?&lt;/strong&gt;&amp;rdquo;. Senza un inventario, rispondere ha richiesto settimane di caccia
manuale. La &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/sca-e-dipendenze/&#34; &gt;SCA&lt;/a&gt; trova i CVE nelle dipendenze, ma presuppone
di sapere &lt;em&gt;cosa&lt;/em&gt; gira in produzione. La &lt;strong&gt;SBOM (Software Bill of Materials)&lt;/strong&gt; è quell&amp;rsquo;inventario: la
distinta base di ogni componente di ciò che spedisci.&lt;/p&gt;
&lt;h2 id=&#34;cosè-concretamente&#34;&gt;Cos&amp;rsquo;è, concretamente
&lt;/h2&gt;&lt;p&gt;Una SBOM è un documento strutturato e leggibile da una macchina che elenca, per ogni artefatto:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Per ogni componente:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  - nome e VERSIONE esatta        ← la chiave per matchare i CVE
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  - identificatore univoco (PURL) ← pkg:npm/lodash@4.17.21
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  - hash / checksum               ← integrità
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  - licenza                       ← anche compliance legale
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  - relazioni (chi dipende da chi)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Due standard dominano: &lt;strong&gt;SPDX&lt;/strong&gt; (ISO, nato attorno alla compliance delle licenze) e &lt;strong&gt;CycloneDX&lt;/strong&gt;
(OWASP, nato con la sicurezza in mente). Entrambi vanno bene; l&amp;rsquo;importante è generarla in un formato
standard, non in un foglio di calcolo fatto a mano.&lt;/p&gt;
&lt;h2 id=&#34;dove-e-come-generarla&#34;&gt;Dove e come generarla
&lt;/h2&gt;&lt;p&gt;La SBOM si genera &lt;strong&gt;nella pipeline&lt;/strong&gt;, al momento della build, quando si conosce esattamente cosa
finisce nell&amp;rsquo;artefatto. Generarla dopo, a posteriori, significa indovinare.&lt;/p&gt;
&lt;pre class=&#34;mermaid&#34;&gt;
  flowchart LR
    SRC[Sorgente + lockfile] --&amp;gt; BUILD[Build nella CI]
    BUILD --&amp;gt; ART[Artefatto&amp;lt;br/&amp;gt;container / binario]
    BUILD --&amp;gt; GEN[Generatore SBOM&amp;lt;br/&amp;gt;es. Syft]
    GEN --&amp;gt; SBOM[SBOM&amp;lt;br/&amp;gt;CycloneDX/SPDX]
    SBOM --&amp;gt;|firmata e allegata&amp;lt;br/&amp;gt;all&amp;#39;artefatto| REG[(Registry)]
    ART --&amp;gt; REG
    style SBOM fill:#fde2e4,stroke:#e63946
&lt;/pre&gt;

&lt;p&gt;Punto chiave: la SBOM va &lt;strong&gt;allegata all&amp;rsquo;artefatto e firmata&lt;/strong&gt;, così viaggia con esso ed è
verificabile (lo vedremo con &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/firma-artefatti-sigstore/&#34; &gt;Sigstore&lt;/a&gt;). Una SBOM
che vive in una cartella scollegata dall&amp;rsquo;artefatto che descrive perde metà del valore.&lt;/p&gt;
&lt;h2 id=&#34;usarla-davvero&#34;&gt;Usarla davvero
&lt;/h2&gt;&lt;p&gt;Una SBOM archiviata e mai consultata è teatro della conformità. Il valore sta nell&amp;rsquo;uso:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Risposta ai CVE&lt;/strong&gt;: esce una vulnerabilità su &lt;code&gt;libxyz 1.4&lt;/code&gt;? Una query sulle SBOM archiviate dice
in minuti &lt;em&gt;quali&lt;/em&gt; servizi la contengono. La caccia di Log4Shell diventa un filtro.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Policy di ingresso&lt;/strong&gt;: l&amp;rsquo;admission control può rifiutare un&amp;rsquo;immagine &lt;em&gt;senza&lt;/em&gt; SBOM o con componenti
vietati (licenze incompatibili, pacchetti in blocklist).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Monitoraggio continuo&lt;/strong&gt;: le SBOM si ri-scansionano contro i database aggiornati, così si scoprono
CVE &lt;em&gt;nuovi&lt;/em&gt; su software già in produzione da mesi.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;il-limite-onesto-profondità&#34;&gt;Il limite onesto: profondità
&lt;/h2&gt;&lt;p&gt;Una SBOM è buona quanto il generatore che la produce. Alcuni componenti sfuggono: binari statici,
dipendenze incluse a mano, codice generato. La SBOM non è una verità magica, è una &lt;em&gt;misura&lt;/em&gt; della tua
visibilità — e il primo passo per migliorarla è vedere dove è incompleta.&lt;/p&gt;


&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Domanda:&lt;/strong&gt; se la SCA già scansiona le dipendenze e trova i CVE, perché serve anche produrre e archiviare una SBOM? Non è informazione duplicata?&lt;/summary&gt;
&lt;p&gt;Si sovrappongono sull&#39;input — entrambe partono dall&#39;elenco dei componenti — ma rispondono a due domande
diverse in due momenti diversi, e averne una sola lascia scoperto l&#39;altro. La SCA è un&#39;analisi che fai
&lt;em&gt;ora&lt;/em&gt;, nella pipeline, e ti dice &#34;questo artefatto, oggi, contiene questi CVE noti&#34;: è puntuale e
legata al momento della build. La SBOM è un &lt;em&gt;inventario persistente e interrogabile&lt;/em&gt; che
sopravvive alla build e viaggia con l&#39;artefatto in produzione. La differenza si vede nel caso che conta di
più: un CVE che &lt;em&gt;non esisteva&lt;/em&gt; quando hai fatto la build. La SCA di allora non poteva trovarlo,
perché il database non lo conosceva ancora. Sei mesi dopo esce il nuovo Log4Shell: con la sola SCA dovresti
ricostruire o re-scansionare ogni artefatto per sapere chi è colpito, ammesso di sapere ancora
esattamente cosa gira dove. Con le SBOM archiviate e indicizzate, invece, fai una query — &#34;chi contiene
libxyz sotto la 1.5?&#34; — e hai la lista in minuti, senza toccare le build. In più la SBOM serve a cose che
la SCA non copre: la verifica all&#39;ingresso (l&#39;admission control rifiuta ciò che non ha una SBOM o ha
componenti vietati), la conformità delle licenze, e la provenienza. Il modo giusto di vederle: la SCA è
l&#39;&lt;em&gt;azione&lt;/em&gt; di cercare vulnerabilità, la SBOM è il &lt;em&gt;dato&lt;/em&gt; che rende quella ricerca possibile
per sempre, anche sui CVE che non erano ancora stati scoperti. Si alimentano a vicenda.&lt;/p&gt;
&lt;/details&gt;


&lt;h2 id=&#34;conclusione&#34;&gt;Conclusione
&lt;/h2&gt;&lt;p&gt;La SBOM è la distinta base del software: sai cosa spedisci, quindi sai in minuti se un nuovo CVE ti
riguarda. Si genera nella build, si firma, viaggia con l&amp;rsquo;artefatto e si interroga nel tempo. Ma sapere
&lt;em&gt;cosa&lt;/em&gt; c&amp;rsquo;è dentro un artefatto non basta se non possiamo fidarci di &lt;em&gt;come&lt;/em&gt; è stato costruito. Un
attaccante che compromette la pipeline può iniettare codice senza toccare il sorgente. Difendere la
catena di costruzione è il prossimo tema: SLSA, prossimo capitolo.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Fuzzing: trovare i bug che non hai immaginato</title>
        <link>https://www.matteobianchi.eu/p/fuzzing/</link>
        <pubDate>Tue, 12 May 2026 09:00:00 +0200</pubDate>
        
        <guid>https://www.matteobianchi.eu/p/fuzzing/</guid>
        <description>&lt;img src="https://www.matteobianchi.eu/p/fuzzing/cover.png" alt="Featured image of post Fuzzing: trovare i bug che non hai immaginato" /&gt;&lt;h2 id=&#34;perché-conta&#34;&gt;Perché conta
&lt;/h2&gt;&lt;p&gt;Ogni controllo visto finora — &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/sast-analisi-statica/&#34; &gt;SAST&lt;/a&gt;,
&lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/dast-analisi-dinamica/&#34; &gt;DAST&lt;/a&gt;, &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/iast-e-rasp/&#34; &gt;IAST&lt;/a&gt; — cerca
problemi che sappiamo descrivere. I test unitari verificano i casi che &lt;em&gt;immaginiamo&lt;/em&gt;. Ma gli
attaccanti vivono nei casi che &lt;em&gt;non&lt;/em&gt; abbiamo immaginato: l&amp;rsquo;input malformato, la lunghezza assurda, la
sequenza impossibile. Il &lt;strong&gt;fuzzing&lt;/strong&gt; esplora proprio quello spazio, generando input anomali a milioni
e osservando cosa rompe.&lt;/p&gt;
&lt;h2 id=&#34;dallinput-casuale-alla-copertura-guidata&#34;&gt;Dall&amp;rsquo;input casuale alla copertura guidata
&lt;/h2&gt;&lt;p&gt;Il fuzzing ingenuo lancia byte casuali e spera in un crash: inefficiente, perché quasi tutti gli
input vengono rifiutati subito dal parsing. Il salto di qualità è il &lt;strong&gt;coverage-guided fuzzing&lt;/strong&gt;: il
fuzzer osserva &lt;em&gt;quali rami di codice&lt;/em&gt; ogni input attiva e tiene gli input che esplorano codice nuovo,
mutandoli per andare più in profondità.&lt;/p&gt;
&lt;pre class=&#34;mermaid&#34;&gt;
  flowchart LR
    SEED[Corpus iniziale&amp;lt;br/&amp;gt;input validi] --&amp;gt; MUT[Muta l&amp;#39;input&amp;lt;br/&amp;gt;bit flip, splice]
    MUT --&amp;gt; RUN[Esegue la funzione&amp;lt;br/&amp;gt;sotto test]
    RUN --&amp;gt; COV{Copre codice&amp;lt;br/&amp;gt;nuovo?}
    COV --&amp;gt;|sì| KEEP[Aggiungi al corpus&amp;lt;br/&amp;gt;→ base per altre mutazioni]
    COV --&amp;gt;|no| DROP[Scarta]
    RUN --&amp;gt;|crash / hang| BUG[Salva l&amp;#39;input:&amp;lt;br/&amp;gt;bug riproducibile]
    KEEP --&amp;gt; MUT
    style BUG fill:#fde2e4,stroke:#e63946
&lt;/pre&gt;

&lt;p&gt;Guidato dalla copertura, il fuzzer &amp;ldquo;impara&amp;rdquo; a superare i controlli di validazione e a penetrare in
profondità nel codice, trovando in ore ciò che input casuali non troverebbero in anni.&lt;/p&gt;
&lt;h2 id=&#34;cosa-trova&#34;&gt;Cosa trova
&lt;/h2&gt;&lt;p&gt;Il fuzzing eccelle sul codice che &lt;em&gt;interpreta input non fidati&lt;/em&gt;: parser, decoder, deserializzatori,
protocolli di rete, elaborazione di file. Scopre:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Crash&lt;/strong&gt;: dereferenze null, buffer overflow (in C/C++), eccezioni non gestite.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Corruzioni di memoria&lt;/strong&gt;: potenti vettori di exploit, rilevate se si combina il fuzzing con i
&lt;em&gt;sanitizer&lt;/em&gt; (ASan, UBSan) che rendono visibile una corruzione altrimenti silenziosa.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hang e consumo di risorse&lt;/strong&gt;: input che mandano l&amp;rsquo;app in loop o esauriscono la memoria (DoS).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;il-fuzz-target&#34;&gt;Il fuzz target
&lt;/h2&gt;&lt;p&gt;Il cuore pratico è scrivere una piccola funzione che riceve i byte del fuzzer e li passa al codice da
testare:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;LLVMFuzzerTestOneInput&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;uint8_t&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;size_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// il fuzzer fornisce &amp;#39;data&amp;#39;; noi lo passiamo al parser sotto test
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;nf&#34;&gt;parse_config&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;   &lt;span class=&#34;c1&#34;&gt;// ← se crasha, abbiamo un bug riproducibile
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;La riga evidenziata è tutto: dai l&amp;rsquo;input non fidato alla funzione critica e lasci che il fuzzer trovi
l&amp;rsquo;input che la rompe. Lo stesso pattern esiste per i linguaggi gestiti (Go &lt;code&gt;testing.F&lt;/code&gt;, Jazzer per la
JVM, Atheris per Python).&lt;/p&gt;
&lt;h2 id=&#34;continuo-non-una-tantum&#34;&gt;Continuo, non una tantum
&lt;/h2&gt;&lt;p&gt;Il fuzzing dà di più col tempo: più gira, più in profondità arriva. Per questo in DevSecOps è
&lt;strong&gt;continuo&lt;/strong&gt; — gira in background su un corpus che cresce, non in un singolo passaggio di pipeline che
deve finire in cinque minuti. Progetti come OSS-Fuzz dimostrano il modello: fuzzing 24/7, con i bug
che aprono automaticamente ticket. Nella CI si esegue un fuzzing &lt;em&gt;breve&lt;/em&gt; di regressione sul corpus
noto (per non reintrodurre crash già risolti) e si lascia il fuzzing profondo all&amp;rsquo;infrastruttura
dedicata.&lt;/p&gt;


&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Domanda:&lt;/strong&gt; il fuzzing sembra utile solo per codice in C/C++ che fa parsing di basso livello; ha senso per una tipica app web in un linguaggio gestito?&lt;/summary&gt;
&lt;p&gt;Ha senso, ma cambia cosa trova e dove conviene puntarlo. È vero che il raccolto più ricco del fuzzing —
corruzioni di memoria sfruttabili — vive in C/C++, dove un buffer overflow diventa un exploit; in un
linguaggio gestito la memoria è protetta dal runtime, quindi quella classe sparisce. Ma non sparisce il
resto: eccezioni non gestite che diventano DoS o errori 500 informativi, loop e allocazioni che esauriscono
le risorse (una &#34;zip bomb&#34; o un input che fa esplodere un parser in tempo quadratico), bug logici nei
deserializzatori, differenze di parsing tra due librerie che portano a confusione di tipo o a bypass di
validazione. E soprattutto conta &lt;em&gt;dove&lt;/em&gt; lo punti: non sulla logica di business, ma su ogni punto in
cui l&#39;app ingoia input non fidato e lo struttura — l&#39;endpoint che accetta JSON o XML, il decoder di
immagini, il parser di un formato proprietario, il layer che gestisce upload di file. Lì il fuzzing
coverage-guided trova casi limite che nessun test scritto a mano copre, perché nessuno pensa a un JSON
annidato diecimila livelli o a un campo numerico con un valore che fa overflow in una conversione. In più
le dipendenze native sotto a un&#39;app gestita (una libreria di compressione, un codec) sono spesso C/C++
sotto mentite spoglie, e lì il raccolto classico torna. La regola pratica: se un componente parsa qualcosa
che arriva dall&#39;esterno, è un candidato al fuzzing, qualunque sia il linguaggio.&lt;/p&gt;
&lt;/details&gt;


&lt;h2 id=&#34;conclusione&#34;&gt;Conclusione
&lt;/h2&gt;&lt;p&gt;Il fuzzing esplora lo spazio degli input che non abbiamo immaginato; guidato dalla copertura, impara a
penetrare in profondità e trova crash e corruzioni riproducibili, specie nei parser di input non
fidato. È continuo per natura. Con questo chiudiamo i controlli sul codice e sul comportamento. Ma il
software che spediamo non è solo codice: è un &lt;em&gt;artefatto&lt;/em&gt; costruito da una catena di strumenti, e di
quella catena dobbiamo poterci fidare. Comincia la parte sulla supply chain, con l&amp;rsquo;inventario di ciò
che spediamo: la SBOM, prossimo capitolo.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>IAST e RASP: sicurezza dall&#39;interno</title>
        <link>https://www.matteobianchi.eu/p/iast-e-rasp/</link>
        <pubDate>Tue, 05 May 2026 09:00:00 +0200</pubDate>
        
        <guid>https://www.matteobianchi.eu/p/iast-e-rasp/</guid>
        <description>&lt;img src="https://www.matteobianchi.eu/p/iast-e-rasp/cover.png" alt="Featured image of post IAST e RASP: sicurezza dall&#39;interno" /&gt;&lt;h2 id=&#34;perché-conta&#34;&gt;Perché conta
&lt;/h2&gt;&lt;p&gt;Il &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/sast-analisi-statica/&#34; &gt;SAST&lt;/a&gt; vede il codice ma non il runtime; il
&lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/dast-analisi-dinamica/&#34; &gt;DAST&lt;/a&gt; vede il runtime ma non il codice. &lt;strong&gt;IAST&lt;/strong&gt; e
&lt;strong&gt;RASP&lt;/strong&gt; colmano il divario strumentando l&amp;rsquo;applicazione &lt;em&gt;dall&amp;rsquo;interno&lt;/em&gt;: un agent gira dentro il
processo, osserva il flusso reale dei dati nel codice mentre l&amp;rsquo;app riceve richieste vere. Uniscono la
localizzazione precisa del SAST al realismo del DAST.&lt;/p&gt;
&lt;h2 id=&#34;iast-osservare-durante-i-test&#34;&gt;IAST: osservare durante i test
&lt;/h2&gt;&lt;p&gt;L&amp;rsquo;&lt;strong&gt;IAST (Interactive AST)&lt;/strong&gt; è un agent attivo &lt;em&gt;durante i test&lt;/em&gt; (funzionali, DAST, QA). Mentre il
traffico di test attraversa l&amp;rsquo;app, l&amp;rsquo;agent vede dall&amp;rsquo;interno se un input contaminato raggiunge un
sink pericoloso — ma stavolta nel codice reale in esecuzione, non per inferenza.&lt;/p&gt;
&lt;pre class=&#34;mermaid&#34;&gt;
  flowchart LR
    T[Test / DAST&amp;lt;br/&amp;gt;generano traffico] --&amp;gt; APP
    subgraph APP[App strumentata]
        AG[Agent IAST&amp;lt;br/&amp;gt;osserva dall&amp;#39;interno]
    end
    APP --&amp;gt; AG
    AG --&amp;gt; F[&amp;#34;Finding preciso:&amp;lt;br/&amp;gt;riga + percorso dati&amp;lt;br/&amp;gt;+ richiesta che l&amp;#39;ha innescato&amp;#34;]
    style F fill:#fde2e4,stroke:#e63946
&lt;/pre&gt;

&lt;p&gt;Il risultato è il meglio dei due mondi: pochi falsi positivi (l&amp;rsquo;ha &lt;em&gt;visto&lt;/em&gt; accadere) &lt;strong&gt;e&lt;/strong&gt;
localizzazione esatta (riga di codice, non solo URL). Lo svantaggio: copre solo ciò che i test
esercitano — se non c&amp;rsquo;è traffico di test su un percorso, l&amp;rsquo;IAST non vede nulla lì.&lt;/p&gt;
&lt;h2 id=&#34;rasp-difendere-in-produzione&#34;&gt;RASP: difendere in produzione
&lt;/h2&gt;&lt;p&gt;Il &lt;strong&gt;RASP (Runtime Application Self-Protection)&lt;/strong&gt; è lo stesso principio spostato in &lt;strong&gt;produzione&lt;/strong&gt; e
con un ruolo diverso: non osservare, ma &lt;em&gt;bloccare&lt;/em&gt;. L&amp;rsquo;agent, dentro l&amp;rsquo;app, intercetta le operazioni
pericolose a runtime e le ferma quando vede uno sfruttamento in corso.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Richiesta → entra nell&amp;#39;app → RASP osserva l&amp;#39;operazione reale
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  query SQL che contiene la struttura di un&amp;#39;injection?   → blocca
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  tentativo di leggere /etc/passwd via path traversal?   → blocca
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  → decide sul COMPORTAMENTO reale, non su firme di pattern come un WAF
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;La differenza con un WAF: il WAF sta &lt;em&gt;fuori&lt;/em&gt; e indovina dalle richieste; il RASP sta &lt;em&gt;dentro&lt;/em&gt; e vede
cosa l&amp;rsquo;app sta effettivamente per fare con quell&amp;rsquo;input. Meno falsi positivi, ma al prezzo di vivere
nel processo.&lt;/p&gt;
&lt;h2 id=&#34;il-costo-prestazioni-e-accoppiamento&#34;&gt;Il costo: prestazioni e accoppiamento
&lt;/h2&gt;&lt;p&gt;Niente è gratis. Un agent nel processo aggiunge overhead (CPU, latenza) e si accoppia al runtime
specifico (JVM, .NET, Node): va mantenuto, aggiornato, testato a ogni upgrade del linguaggio. Il RASP
in produzione aggiunge anche un rischio di stabilità: un agent difettoso può degradare o far cadere
l&amp;rsquo;app che dovrebbe proteggere. Per questo non sono controlli &amp;ldquo;di default&amp;rdquo; ma scelte mirate, su
applicazioni ad alto valore dove il beneficio giustifica il peso.&lt;/p&gt;


&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Domanda:&lt;/strong&gt; se il RASP vede e blocca gli attacchi dall&#39;interno dell&#39;app, non rende superflui WAF, SAST e DAST?&lt;/summary&gt;
&lt;p&gt;No, e pensarlo porta a un unico punto di difesa, che è l&#39;opposto della sicurezza a strati. Il RASP ha
un difetto strutturale che gli altri controlli non hanno: &lt;em&gt;protegge l&#39;app solo se l&#39;attacco arriva fino
all&#39;app&lt;/em&gt;, e lo fa consumando risorse dell&#39;app stessa. Un WAF davanti assorbe il rumore di fondo — le
scansioni automatiche, i payload banali, i picchi volumetrici — prima che tocchino il processo, così il
RASP si occupa solo di ciò che passa; toglierlo significa far arrivare ogni tentativo fin dentro la JVM.
Il SAST e il DAST agiscono &lt;em&gt;prima&lt;/em&gt; del rilascio: il loro scopo è che la vulnerabilità non esista
in produzione, non difenderla una volta che c&#39;è. Affidarsi al solo RASP equivale a dire &#34;lasciamo pure i
difetti nel codice, tanto li blocca a runtime&#34; — ma il RASP può fallire, può essere aggirato, può essere
disattivato per un problema di prestazioni, e nel frattempo la falla è lì. C&#39;è anche il rischio di
stabilità già citato: il RASP vive nel processo, un suo bug degrada l&#39;app. Il modello corretto è difesa
in profondità: eliminare i difetti a sinistra con SAST/DAST, filtrare il grosso con il WAF, e tenere il
RASP come ultima rete interna per lo sfruttamento che supera tutto il resto — non come sostituto di
nessuno di essi.&lt;/p&gt;
&lt;/details&gt;


&lt;h2 id=&#34;conclusione&#34;&gt;Conclusione
&lt;/h2&gt;&lt;p&gt;IAST e RASP strumentano l&amp;rsquo;app dall&amp;rsquo;interno: l&amp;rsquo;IAST unisce precisione e realismo durante i test, il
RASP blocca lo sfruttamento in produzione. Pagano in prestazioni e accoppiamento, quindi si scelgono
per i servizi ad alto valore, non ovunque. Finora abbiamo testato ciò che immaginiamo possa andare
storto; manca un metodo per scoprire i difetti che &lt;em&gt;non&lt;/em&gt; abbiamo immaginato, bombardando l&amp;rsquo;app di
input imprevisti. È il fuzzing, prossimo capitolo.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>DAST: testare l&#39;applicazione viva</title>
        <link>https://www.matteobianchi.eu/p/dast-analisi-dinamica/</link>
        <pubDate>Tue, 28 Apr 2026 09:00:00 +0200</pubDate>
        
        <guid>https://www.matteobianchi.eu/p/dast-analisi-dinamica/</guid>
        <description>&lt;img src="https://www.matteobianchi.eu/p/dast-analisi-dinamica/cover.png" alt="Featured image of post DAST: testare l&#39;applicazione viva" /&gt;&lt;h2 id=&#34;perché-conta&#34;&gt;Perché conta
&lt;/h2&gt;&lt;p&gt;Il &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/sast-analisi-statica/&#34; &gt;SAST&lt;/a&gt; e la &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/sca-e-dipendenze/&#34; &gt;SCA&lt;/a&gt;
guardano il codice fermo. Ma un&amp;rsquo;applicazione in esecuzione è più della somma del suo sorgente: ha una
configurazione, un web server, header HTTP, sessioni, un ambiente. Il &lt;strong&gt;DAST (Dynamic Application
Security Testing)&lt;/strong&gt; la testa &lt;em&gt;viva&lt;/em&gt;, attaccandola dall&amp;rsquo;esterno come farebbe un avversario, senza
vedere il codice. Trova ciò che esiste solo a runtime.&lt;/p&gt;
&lt;h2 id=&#34;black-box-la-prospettiva-dellattaccante&#34;&gt;Black box: la prospettiva dell&amp;rsquo;attaccante
&lt;/h2&gt;&lt;p&gt;Il DAST non sa nulla del codice: manda richieste, osserva le risposte, deduce.&lt;/p&gt;
&lt;pre class=&#34;mermaid&#34;&gt;
  flowchart LR
    Z[Scanner DAST] --&amp;gt;|crawl: scopre&amp;lt;br/&amp;gt;URL e form| APP[App in esecuzione&amp;lt;br/&amp;gt;staging]
    Z --&amp;gt;|payload malevoli:&amp;lt;br/&amp;gt;&amp;#39;, &amp;lt; script &amp;gt;, ../| APP
    APP --&amp;gt;|risposte,&amp;lt;br/&amp;gt;codici, errori| Z
    Z --&amp;gt; R[Report:&amp;lt;br/&amp;gt;XSS, injection,&amp;lt;br/&amp;gt;header mancanti,&amp;lt;br/&amp;gt;config errata]
    style R fill:#fde2e4,stroke:#e63946
&lt;/pre&gt;

&lt;p&gt;Prima &lt;em&gt;esplora&lt;/em&gt; (crawl) per scoprire URL, parametri e form; poi &lt;em&gt;attacca&lt;/em&gt; iniettando payload e
osservando se l&amp;rsquo;app reagisce in modo rivelatore. Trova:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Configurazioni errate&lt;/strong&gt;: header di sicurezza assenti, cookie senza flag, pagine di errore
troppo verbose, metodi HTTP pericolosi abilitati.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Vulnerabilità confermate a runtime&lt;/strong&gt;: una XSS che si attiva davvero, un&amp;rsquo;injection che restituisce
dati, un redirect aperto.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Problemi di sessione e autenticazione&lt;/strong&gt; osservabili dall&amp;rsquo;esterno.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;il-vantaggio-pochi-falsi-positivi&#34;&gt;Il vantaggio: pochi falsi positivi
&lt;/h2&gt;&lt;p&gt;Dove il SAST dice &amp;ldquo;questo &lt;em&gt;potrebbe&lt;/em&gt; essere sfruttabile&amp;rdquo;, il DAST spesso &lt;em&gt;dimostra&lt;/em&gt; lo sfruttamento:
ha inviato il payload e ha visto la risposta. Un finding DAST confermato è quasi sempre reale, perché
riproduce l&amp;rsquo;attacco. Questo lo rende prezioso come controprova dei sospetti del SAST.&lt;/p&gt;
&lt;h2 id=&#34;i-limiti-da-conoscere&#34;&gt;I limiti, da conoscere
&lt;/h2&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Limiti strutturali del DAST:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  - Copertura parziale: testa solo i percorsi che riesce a RAGGIUNGERE
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  - Lento: una scansione completa può durare ore
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  - Non localizza: dice &amp;#34;c&amp;#39;è una XSS qui&amp;#34;, non &amp;#34;riga 42 del file X&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  - Richiede un ambiente in esecuzione, simile a produzione
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;La copertura è il limite più sottile: se lo scanner non riesce a navigare un flusso complesso (un
wizard multi-step, un&amp;rsquo;area dietro login), non lo testa. Per questo si fornisce al DAST
l&amp;rsquo;autenticazione e, idealmente, la mappa degli endpoint (una definizione OpenAPI), così attacca anche
le API, non solo le pagine che riesce a cliccare.&lt;/p&gt;
&lt;h2 id=&#34;nel-flusso-di-lavoro&#34;&gt;Nel flusso di lavoro
&lt;/h2&gt;&lt;p&gt;La lentezza impone una collocazione diversa dal SAST:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Scansione &amp;ldquo;baseline&amp;rdquo; veloce&lt;/strong&gt; su ogni deploy in staging: pochi minuti, solo i controlli passivi e
rapidi, come gate leggero.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Scansione completa&lt;/strong&gt; notturna o settimanale, fuori dal percorso critico della pipeline.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mai in produzione senza cautela&lt;/strong&gt;: il DAST invia payload reali; girarlo su produzione può creare
dati spazzatura o, peggio, innescare azioni. Si usa uno staging fedele.&lt;/li&gt;
&lt;/ul&gt;


&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Domanda:&lt;/strong&gt; se il DAST trova vulnerabilità confermate e con pochi falsi positivi, non è semplicemente migliore del SAST? Perché tenere entrambi?&lt;/summary&gt;
&lt;p&gt;&#34;Migliore&#34; dipende da cosa misuri, e sulle due metriche che contano di più i due si invertono. Il DAST
vince su &lt;em&gt;precisione&lt;/em&gt; (i suoi finding sono spesso dimostrati) e su &lt;em&gt;realismo&lt;/em&gt; (vede l&#39;app
come un attaccante, con la sua configurazione e il suo ambiente). Ma perde su &lt;em&gt;copertura&lt;/em&gt; e
&lt;em&gt;tempismo&lt;/em&gt;, che per un difetto grave contano quanto la precisione. Copertura: il DAST testa solo i
percorsi che riesce a raggiungere navigando; un ramo di codice che si attiva solo con un input raro non
verrà mai esercitato, mentre il SAST lo legge comunque. Tempismo: il DAST richiede un&#39;app in esecuzione in
staging, quindi arriva a codice già scritto e integrato, mentre il SAST dà feedback sulla pull request,
riga per riga, quando correggere costa un commento invece di un ciclo di rilascio. E c&#39;è una classe di
difetti che il DAST non localizza: ti dice &#34;c&#39;è una XSS raggiungendo questo URL&#34;, non &#34;nasce da questa
funzione&#34; — per il fix serve comunque risalire al codice. Il modello mentale giusto non è una gara ma una
pipeline di reti progressivamente più fini e più tardive: SAST e SCA ampi e precoci sul codice, DAST
realistico e confermante sull&#39;app viva, poi i controlli di runtime in produzione. Scartarne uno non ti dà
più precisione, ti dà un buco in un punto preciso della timeline.&lt;/p&gt;
&lt;/details&gt;


&lt;h2 id=&#34;conclusione&#34;&gt;Conclusione
&lt;/h2&gt;&lt;p&gt;Il DAST attacca l&amp;rsquo;applicazione viva dall&amp;rsquo;esterno: trova configurazioni errate e difetti di runtime
che il codice fermo nasconde, con pochi falsi positivi ma copertura parziale e tempi lunghi. SAST e
DAST insieme coprono codice e comportamento. Esiste però un terzo punto di vista, ibrido: strumentare
l&amp;rsquo;app &lt;em&gt;dall&amp;rsquo;interno&lt;/em&gt; mentre viene testata, per unire visibilità sul codice e realismo del runtime.
Sono IAST e RASP, prossimo capitolo.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>SCA: il codice che non hai scritto</title>
        <link>https://www.matteobianchi.eu/p/sca-e-dipendenze/</link>
        <pubDate>Tue, 21 Apr 2026 09:00:00 +0200</pubDate>
        
        <guid>https://www.matteobianchi.eu/p/sca-e-dipendenze/</guid>
        <description>&lt;img src="https://www.matteobianchi.eu/p/sca-e-dipendenze/cover.png" alt="Featured image of post SCA: il codice che non hai scritto" /&gt;&lt;h2 id=&#34;perché-conta&#34;&gt;Perché conta
&lt;/h2&gt;&lt;p&gt;Il &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/sast-analisi-statica/&#34; &gt;SAST&lt;/a&gt; analizza il codice che scriviamo. Ma in
un&amp;rsquo;applicazione moderna quel codice è una frazione del totale: il resto sono &lt;strong&gt;dipendenze&lt;/strong&gt; — librerie
open source, transitivamente centinaia di pacchetti che non abbiamo mai letto. La &lt;strong&gt;SCA (Software
Composition Analysis)&lt;/strong&gt; si occupa di questo codice: trova le vulnerabilità &lt;em&gt;note&lt;/em&gt; (CVE) nelle librerie
che importiamo. Log4Shell ci ha insegnato quanto possa pesare una sola riga in un &lt;code&gt;pom.xml&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;lalbero-delle-dipendenze-transitive&#34;&gt;L&amp;rsquo;albero delle dipendenze transitive
&lt;/h2&gt;&lt;p&gt;Il punto chiave: non si importano le librerie dichiarate, si importa il loro intero albero.&lt;/p&gt;
&lt;pre class=&#34;mermaid&#34;&gt;
  flowchart TD
    APP[La tua app] --&amp;gt; A[libreria-web]
    APP --&amp;gt; B[client-http]
    A --&amp;gt; C[parser-json v1.2]
    B --&amp;gt; C
    B --&amp;gt; D[logging-lib v2.0&amp;lt;br/&amp;gt;CVE-2024-XXXX]
    style D fill:#fde2e4,stroke:#e63946
&lt;/pre&gt;

&lt;p&gt;Hai dichiarato &lt;code&gt;client-http&lt;/code&gt;, ma ti ritrovi &lt;code&gt;logging-lib v2.0&lt;/code&gt; vulnerabile &lt;em&gt;senza averla mai scritta&lt;/em&gt;
nel tuo manifest. La SCA risolve l&amp;rsquo;intero albero e confronta ogni nodo con i database di
vulnerabilità. La maggior parte dei CVE che ti colpiscono vive nelle dipendenze &lt;strong&gt;transitive&lt;/strong&gt;, quelle
che non hai scelto consapevolmente.&lt;/p&gt;
&lt;h2 id=&#34;non-tutti-i-cve-ti-riguardano&#34;&gt;Non tutti i CVE ti riguardano
&lt;/h2&gt;&lt;p&gt;Il tranello della SCA è il diluvio di avvisi. Un CVE in una libreria &lt;em&gt;non significa&lt;/em&gt; che la tua app
sia vulnerabile. Due domande filtrano il rumore:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Per ogni CVE segnalato:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  1. Uso davvero la funzione vulnerabile?   (reachability)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  2. Il percorso è esposto a input ostile?  (exploitability nel mio contesto)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Se entrambe NO → rischio basso, patch pianificata, non emergenza.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Gli strumenti più avanzati fanno &lt;strong&gt;reachability analysis&lt;/strong&gt;: controllano se il tuo codice chiama
davvero la funzione vulnerabile. Un CVE in un metodo che non invochi mai è rumore a bassa priorità;
uno nel percorso di autenticazione esposto a internet è un&amp;rsquo;emergenza. Prioritizzare per contesto, non
per numero di avvisi, è ciò che tiene il team sano — lo vedremo meglio nel capitolo sul
&lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/vulnerability-management-triage/&#34; &gt;vulnerability management&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;aggiornare-senza-rompere&#34;&gt;Aggiornare senza rompere
&lt;/h2&gt;&lt;p&gt;La SCA non serve a nulla se poi non si aggiorna. Le pratiche che funzionano:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Bot di aggiornamento&lt;/strong&gt; (Dependabot, Renovate) che aprono pull request automatiche per le nuove
versioni, testate dalla CI.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Lockfile&lt;/strong&gt; committati: la build è riproducibile, si sa esattamente quale versione gira.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Aggiornamenti piccoli e frequenti&lt;/strong&gt; invece del salto di tre major ogni due anni, che nessuno osa
fare perché romperebbe tutto.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;nel-flusso-di-lavoro&#34;&gt;Nel flusso di lavoro
&lt;/h2&gt;&lt;p&gt;La SCA sta nella CI (su ogni pull request, analizzando il manifest e il lockfile) e come scansione
periodica del codice già in produzione: un CVE nuovo può emergere su una dipendenza che non tocchi da
mesi. Questo richiede di sapere &lt;em&gt;cosa&lt;/em&gt; gira davvero in produzione — l&amp;rsquo;inventario degli artefatti, che
è il tema della SBOM, tra pochi capitoli.&lt;/p&gt;


&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Domanda:&lt;/strong&gt; se continuo ad aggiornare le dipendenze a ogni CVE, non introduco instabilità e rischio di supply chain (una versione nuova compromessa) peggiore del CVE stesso?&lt;/summary&gt;
&lt;p&gt;È una tensione reale e va gestita, non ignorata in nessuna delle due direzioni. Aggiornare alla cieca
a ogni avviso è sbagliato quanto non aggiornare mai: una nuova versione può introdurre regressioni, o —
caso raro ma grave — essere una release compromessa, come negli attacchi di supply chain dove l&#39;account
di un maintainer viene violato. La risposta non è scegliere tra &#34;sempre&#34; e &#34;mai&#34;, è &lt;em&gt;prioritizzare e
verificare&lt;/em&gt;. Prioritizzare: non tutti i CVE sono emergenze, la reachability analysis e il contesto
dicono quali patchare subito e quali possono attendere una finestra pianificata, così non sei in
aggiornamento perpetuo. Verificare: l&#39;aggiornamento passa dalla CI con i tuoi test, non va dritto in
produzione; aggiorni a versioni che hanno qualche giorno di vita, non all&#39;ora zero; usi il lockfile con
gli hash così sai che stai scaricando esattamente l&#39;artefatto atteso; e, per i rischi di supply chain
veri, ti appoggi alla verifica della provenienza e delle firme (SLSA, Sigstore — i prossimi capitoli)
invece di fidarti del solo numero di versione. Il rischio di una dipendenza vulnerabile nota, con exploit
pubblico, è quasi sempre più alto e più certo del rischio ipotetico di una release compromessa che i
controlli di provenienza intercettano. Aggiornare in modo disciplinato riduce entrambi; non aggiornare
ne elimina uno solo e ti lascia l&#39;altro, che è anche il più sfruttato.&lt;/p&gt;
&lt;/details&gt;


&lt;h2 id=&#34;conclusione&#34;&gt;Conclusione
&lt;/h2&gt;&lt;p&gt;La SCA illumina il codice che non hai scritto: risolve l&amp;rsquo;albero transitivo, trova i CVE noti e — se
fatta bene — li prioritizza per reachability invece che per conteggio. Insieme al SAST copre il
codice, nostro e altrui, in modo statico. Ma entrambi guardano il codice &lt;em&gt;fermo&lt;/em&gt;. Alcuni difetti si
vedono solo quando l&amp;rsquo;applicazione gira e risponde a richieste reali: è il turno dell&amp;rsquo;analisi dinamica,
prossimo capitolo.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>SAST: analizzare il codice senza eseguirlo</title>
        <link>https://www.matteobianchi.eu/p/sast-analisi-statica/</link>
        <pubDate>Tue, 14 Apr 2026 09:00:00 +0200</pubDate>
        
        <guid>https://www.matteobianchi.eu/p/sast-analisi-statica/</guid>
        <description>&lt;img src="https://www.matteobianchi.eu/p/sast-analisi-statica/cover.png" alt="Featured image of post SAST: analizzare il codice senza eseguirlo" /&gt;&lt;h2 id=&#34;perché-conta&#34;&gt;Perché conta
&lt;/h2&gt;&lt;p&gt;Tolti i &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/gestione-dei-segreti/&#34; &gt;segreti dal codice&lt;/a&gt;, possiamo analizzare il
codice stesso. Il &lt;strong&gt;SAST (Static Application Security Testing)&lt;/strong&gt; legge il sorgente — senza eseguirlo —
cercando pattern che portano a vulnerabilità. È il primo controllo che tocca la logica di ciò che
scriviamo, e si attiva prima ancora della compilazione, nel punto più a sinistra possibile dopo il
threat modeling.&lt;/p&gt;
&lt;h2 id=&#34;cosa-trova-e-cosa-no&#34;&gt;Cosa trova (e cosa no)
&lt;/h2&gt;&lt;p&gt;Il SAST eccelle sui difetti &lt;em&gt;locali e riconoscibili nel codice&lt;/em&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Injection&lt;/strong&gt; (SQL, comandi, LDAP): input non sanitizzato che finisce in una query o in una shell.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Path traversal&lt;/strong&gt;, &lt;strong&gt;XSS&lt;/strong&gt;, deserializzazione insicura.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Crypto debole&lt;/strong&gt;: MD5 per le password, algoritmi deprecati, chiavi hardcoded.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pattern pericolosi&lt;/strong&gt;: &lt;code&gt;eval&lt;/code&gt;, formattazione di stringhe in query.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Non vede i difetti che emergono solo a runtime o dalla &lt;em&gt;configurazione&lt;/em&gt;: un bucket pubblico, un
header mancante, una logica di autorizzazione sbagliata che il codice esprime &amp;ldquo;correttamente&amp;rdquo;. Per
quelli servono DAST e analisi di configurazione, capitoli successivi.&lt;/p&gt;
&lt;h2 id=&#34;come-funziona-la-taint-analysis&#34;&gt;Come funziona: la taint analysis
&lt;/h2&gt;&lt;p&gt;Il cuore del SAST moderno è l&amp;rsquo;analisi del &lt;em&gt;flusso dei dati contaminati&lt;/em&gt; (taint): segue un dato da una
&lt;strong&gt;sorgente&lt;/strong&gt; non fidata (input utente) fino a un &lt;strong&gt;sink&lt;/strong&gt; pericoloso (una query), controllando se
passa per un &lt;em&gt;sanitizer&lt;/em&gt;.&lt;/p&gt;
&lt;pre class=&#34;mermaid&#34;&gt;
  flowchart LR
    SRC[&amp;#34;Source&amp;lt;br/&amp;gt;request.getParameter()&amp;#34;] --&amp;gt;|dato contaminato| F[Flusso nel codice]
    F --&amp;gt; SAN{&amp;#34;Passa da un&amp;lt;br/&amp;gt;sanitizer?&amp;#34;}
    SAN --&amp;gt;|no| SINK[&amp;#34;Sink&amp;lt;br/&amp;gt;db.execute(sql)&amp;#34;]
    SAN --&amp;gt;|sì| OK[Sicuro]
    SINK --&amp;gt; V[VULNERABILITÀ:&amp;lt;br/&amp;gt;SQL injection]
    style V fill:#fde2e4,stroke:#e63946
&lt;/pre&gt;

&lt;p&gt;Se un dato arriva dalla sorgente al sink senza sanitizzazione, lo strumento segnala. Questo spiega
sia la potenza (trova catene non ovvie) sia i limiti (non sa che una certa funzione &lt;em&gt;è&lt;/em&gt; un sanitizer
se non gliel&amp;rsquo;hai detto → falso positivo).&lt;/p&gt;
&lt;h2 id=&#34;il-problema-dei-falsi-positivi&#34;&gt;Il problema dei falsi positivi
&lt;/h2&gt;&lt;p&gt;Il SAST ingenuo è famoso per il rumore. Un tool che segnala 500 problemi di cui 480 irrilevanti
viene disattivato in una settimana. Le contromisure in una pipeline sana:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;# esempio di gate SAST ragionevole nella CI&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;sast&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;fail_on&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;high         &lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# blocca solo su severità alta, non su tutto&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;diff_aware&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# analizza solo il codice cambiato nella PR&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;baseline&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# ignora il debito preesistente, blocca il NUOVO&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;suppress_with&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;comment&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# i falsi positivi si marcano, tracciati e revisionati&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Le righe evidenziate sono ciò che rende il SAST sopportabile: &lt;strong&gt;blocca solo il nuovo rischio alto&lt;/strong&gt;,
non tutto il debito storico, e lascia una via esplicita (tracciata) per i falsi positivi.&lt;/p&gt;
&lt;h2 id=&#34;nel-flusso-di-lavoro&#34;&gt;Nel flusso di lavoro
&lt;/h2&gt;&lt;p&gt;Il posto giusto è la &lt;strong&gt;pull request&lt;/strong&gt;: il feedback arriva come commento in linea, nel contesto, a chi
ha appena scritto quel codice. Molti team aggiungono il SAST anche nell&amp;rsquo;IDE (feedback in tempo reale)
e un passaggio nella CI come gate. Regole personalizzate (Semgrep rende questo semplice) codificano
gli &lt;em&gt;abuse case&lt;/em&gt; del threat model: la minaccia diventa una regola che fallisce se la falla ritorna.&lt;/p&gt;


&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Domanda:&lt;/strong&gt; se il SAST ha tanti falsi positivi e non vede i difetti di runtime, perché non affidarsi solo al DAST che testa l&#39;app reale?&lt;/summary&gt;
&lt;p&gt;Perché vedono cose diverse e in momenti diversi, e scartarne uno lascia un buco. Il SAST ha una
visibilità totale sul codice — ogni ramo, ogni percorso, anche quelli che un test dinamico non
raggiungerebbe mai senza l&#39;input giusto — e dà feedback sulla singola riga, in fase di scrittura, quando
correggere costa un minuto. Il DAST vede l&#39;applicazione viva, quindi trova i difetti di configurazione e
di ambiente che il SAST ignora, ma solo sui percorsi che riesce effettivamente a esercitare, e arriva
tardi, in staging, quando il codice è già scritto e il contesto mentale perso. Non sono ridondanti, sono
complementari: il SAST è la copertura ampia e precoce con il prezzo del rumore, il DAST è la conferma
realistica ma tardiva e parziale. La risposta ai falsi positivi non è eliminare il SAST, è configurarlo
bene — diff-aware, baseline, gate solo su severità alta, regole tarate sul tuo codice — così il segnale
emerge dal rumore. Un difetto di injection trovato dal SAST sulla pull request costa un commento; lo
stesso difetto trovato dal DAST in staging costa un ticket; trovato in produzione costa un incidente.
Vuoi entrambe le reti, non la più comoda.&lt;/p&gt;
&lt;/details&gt;


&lt;h2 id=&#34;conclusione&#34;&gt;Conclusione
&lt;/h2&gt;&lt;p&gt;Il SAST legge il codice senza eseguirlo e segue i dati contaminati dalla sorgente al sink: ampio,
precoce, ma rumoroso se non tarato su diff, baseline e severità. Cattura però solo il codice che
&lt;em&gt;scriviamo noi&lt;/em&gt;. La maggior parte di un&amp;rsquo;applicazione moderna, però, è codice che non abbiamo scritto:
le dipendenze. Analizzarle è un problema diverso — la Software Composition Analysis, prossimo capitolo.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Gestione dei segreti: mai nel codice</title>
        <link>https://www.matteobianchi.eu/p/gestione-dei-segreti/</link>
        <pubDate>Tue, 07 Apr 2026 09:00:00 +0200</pubDate>
        
        <guid>https://www.matteobianchi.eu/p/gestione-dei-segreti/</guid>
        <description>&lt;img src="https://www.matteobianchi.eu/p/gestione-dei-segreti/cover.png" alt="Featured image of post Gestione dei segreti: mai nel codice" /&gt;&lt;h2 id=&#34;perché-conta&#34;&gt;Perché conta
&lt;/h2&gt;&lt;p&gt;Il &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/threat-modeling-nel-ciclo/&#34; &gt;threat modeling&lt;/a&gt; identifica dove i dati
attraversano confini di fiducia; i &lt;strong&gt;segreti&lt;/strong&gt; — chiavi, token, password — sono proprio ciò che
protegge quei confini. Lasciarli nel codice è l&amp;rsquo;errore più banale e più diffuso: una chiave AWS in
un commit, un token in un file &lt;code&gt;.env&lt;/code&gt; versionato, e un repository anche privato diventa una bomba a
orologeria. È il primo difetto concreto da eliminare nel flusso di sviluppo.&lt;/p&gt;
&lt;h2 id=&#34;il-problema-della-history-di-git&#34;&gt;Il problema della history di Git
&lt;/h2&gt;&lt;p&gt;Il tranello peggiore: rimuovere un segreto con un commit successivo &lt;strong&gt;non lo elimina&lt;/strong&gt;. Resta
nell&amp;rsquo;intera history, recuperabile da chiunque abbia accesso al repository.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git add config.py        # contiene AWS_SECRET=...
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git commit -m &amp;#34;config&amp;#34;   # il segreto è ora NELLA history, per sempre
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git rm config.py         # lo toglie dalla HEAD, NON dalla history
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;# → il segreto va considerato COMPROMESSO: ruotalo subito
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Regola d&amp;rsquo;oro: &lt;strong&gt;un segreto committato è un segreto bruciato&lt;/strong&gt;. Non basta rimuoverlo, va &lt;em&gt;ruotato&lt;/em&gt;
(invalidato e rigenerato). La pulizia della history (con strumenti come &lt;code&gt;git filter-repo&lt;/code&gt;) serve a
non ripetere l&amp;rsquo;incidente, non a &amp;ldquo;annullarlo&amp;rdquo;.&lt;/p&gt;
&lt;h2 id=&#34;i-tre-livelli-di-difesa&#34;&gt;I tre livelli di difesa
&lt;/h2&gt;&lt;pre class=&#34;mermaid&#34;&gt;
  flowchart TD
    A[1. Prevenzione&amp;lt;br/&amp;gt;secret scanning&amp;lt;br/&amp;gt;pre-commit] --&amp;gt; B[2. Centralizzazione&amp;lt;br/&amp;gt;secret manager&amp;lt;br/&amp;gt;niente segreti nel codice]
    B --&amp;gt; C[3. Riduzione del danno&amp;lt;br/&amp;gt;segreti dinamici&amp;lt;br/&amp;gt;a vita breve]
    style C fill:#fde2e4,stroke:#e63946
&lt;/pre&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Prevenzione&lt;/strong&gt;: uno scanner (gitleaks, trufflehog) come hook di pre-commit e nella pipeline
blocca il segreto &lt;em&gt;prima&lt;/em&gt; che entri nella history.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Centralizzazione&lt;/strong&gt;: un &lt;strong&gt;secret manager&lt;/strong&gt; (Vault, AWS Secrets Manager, cloud KMS) custodisce i
segreti; l&amp;rsquo;applicazione li recupera a runtime con una propria identità, non li porta nel codice.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Riduzione del danno&lt;/strong&gt;: i &lt;strong&gt;segreti dinamici&lt;/strong&gt; — credenziali generate su richiesta e valide
pochi minuti — fanno sì che un segreto trapelato valga quasi nulla, perché scade subito.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;segreti-dinamici-il-salto-di-qualità&#34;&gt;Segreti dinamici: il salto di qualità
&lt;/h2&gt;&lt;p&gt;Un segreto statico vive per mesi: se trapela, l&amp;rsquo;attaccante ha mesi. Vault può invece generare al
volo una credenziale di database valida un&amp;rsquo;ora, legata al servizio che l&amp;rsquo;ha chiesta. Il furto
diventa una finestra di minuti, non un accesso permanente. È lo stesso principio dei certificati a
vita breve che vedremo per l&amp;rsquo;&lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/identita-dei-workload-mtls/&#34; &gt;identità dei workload&lt;/a&gt;:
ridurre il valore nel tempo di ogni credenziale.&lt;/p&gt;
&lt;h2 id=&#34;nel-flusso-di-lavoro&#34;&gt;Nel flusso di lavoro
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Pre-commit&lt;/strong&gt;: hook locale che rifiuta il commit con un segreto.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CI&lt;/strong&gt;: scansione del diff e, periodicamente, dell&amp;rsquo;intera history.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Runtime&lt;/strong&gt;: l&amp;rsquo;app chiede il segreto al manager con la sua identità; nessun segreto nel container
image né nelle variabili d&amp;rsquo;ambiente scritte a mano.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rotazione&lt;/strong&gt;: automatica e regolare, non &amp;ldquo;quando ci ricordiamo&amp;rdquo;.&lt;/li&gt;
&lt;/ul&gt;


&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Domanda:&lt;/strong&gt; se l&#39;app recupera i segreti da Vault, le serve comunque una credenziale per autenticarsi a Vault — non abbiamo solo spostato il problema?&lt;/summary&gt;
&lt;p&gt;È la domanda giusta, ed è il classico &#34;problema del segreto zero&#34; — lo stesso che SPIFFE/SPIRE risolve
per i workload. Sì, serve una credenziale iniziale per parlare con Vault, ma la si è spostata da &#34;mille
segreti sparsi in mille repository e file di config&#34; a &#34;un solo punto di bootstrap, progettato apposta per
essere protetto&#34;. E quel bootstrap non deve essere a sua volta un segreto statico scritto da qualche parte:
i metodi di auth di Vault sfruttano un&#39;identità che la piattaforma &lt;em&gt;attesta&lt;/em&gt;, non una stringa
consegnata. In Kubernetes l&#39;app si autentica con il suo ServiceAccount token, che il cluster emette e
verifica; in cloud con l&#39;identità dell&#39;istanza (IAM role, managed identity), provata dal provider; con
SPIFFE, con lo SVID emesso per attestazione. In tutti i casi la fiducia iniziale poggia su qualcosa che
l&#39;ambiente testimonia — &#34;sei il pod X nel namespace Y sul nodo Z&#34; — non su una chiave che qualcuno deve
custodire per prima. Il problema non è &#34;spostato&#34; in circolo: è ridotto da N segreti fragili a un unico
punto radicato nell&#39;identità della piattaforma, molto più difendibile e monitorabile.&lt;/p&gt;
&lt;/details&gt;


&lt;h2 id=&#34;conclusione&#34;&gt;Conclusione
&lt;/h2&gt;&lt;p&gt;I segreti non stanno mai nel codice: si previene con lo scanning, si centralizza con un secret
manager, si riduce il danno con segreti dinamici a vita breve. E un segreto committato è un segreto
da ruotare, non da nascondere. Con i segreti fuori dal codice, possiamo guardare il codice stesso:
il primo controllo automatico che lo ispeziona mentre viene scritto è l&amp;rsquo;analisi statica, prossimo
capitolo.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Threat modeling nel ciclo di sviluppo</title>
        <link>https://www.matteobianchi.eu/p/threat-modeling-nel-ciclo/</link>
        <pubDate>Tue, 31 Mar 2026 09:00:00 +0200</pubDate>
        
        <guid>https://www.matteobianchi.eu/p/threat-modeling-nel-ciclo/</guid>
        <description>&lt;img src="https://www.matteobianchi.eu/p/threat-modeling-nel-ciclo/cover.png" alt="Featured image of post Threat modeling nel ciclo di sviluppo" /&gt;&lt;h2 id=&#34;perché-conta&#34;&gt;Perché conta
&lt;/h2&gt;&lt;p&gt;Il &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/secure-sdlc/&#34; &gt;Secure SDLC&lt;/a&gt; colloca il threat modeling nel design, la fase
più economica in assoluto: qui un difetto costa una gomma su una lavagna. Lo stesso ragionamento
l&amp;rsquo;abbiamo già applicato alle reti nel post sul &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/threat-modeling-networks/&#34; &gt;threat modeling delle reti&lt;/a&gt;;
qui lo portiamo dentro il ciclo di sviluppo del software, dove diventa un&amp;rsquo;abitudine ricorrente e non
un documento scritto una volta e mai più aperto.&lt;/p&gt;
&lt;h2 id=&#34;i-quattro-passi&#34;&gt;I quattro passi
&lt;/h2&gt;&lt;p&gt;Il threat modeling risponde a quattro domande, nell&amp;rsquo;ordine:&lt;/p&gt;
&lt;pre class=&#34;mermaid&#34;&gt;
  flowchart LR
    Q1[&amp;#34;1. Cosa stiamo&amp;lt;br/&amp;gt;costruendo?&amp;#34;] --&amp;gt; Q2[&amp;#34;2. Cosa può&amp;lt;br/&amp;gt;andare storto?&amp;#34;]
    Q2 --&amp;gt; Q3[&amp;#34;3. Cosa facciamo&amp;lt;br/&amp;gt;al riguardo?&amp;#34;]
    Q3 --&amp;gt; Q4[&amp;#34;4. Abbiamo fatto&amp;lt;br/&amp;gt;un buon lavoro?&amp;#34;]
    Q4 -.rivaluta a ogni&amp;lt;br/&amp;gt;cambio di design.-&amp;gt; Q1
    style Q2 fill:#fde2e4,stroke:#e63946
&lt;/pre&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Cosa costruiamo&lt;/strong&gt;: un diagramma di flusso dei dati (DFD) con i confini di fiducia — dove i dati
attraversano una frontiera tra componenti con privilegi diversi.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cosa può andare storto&lt;/strong&gt;: si enumerano le minacce, tipicamente con STRIDE.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cosa facciamo&lt;/strong&gt;: per ogni minaccia una mitigazione, un rischio accettato o un trasferimento.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Com&amp;rsquo;è andata&lt;/strong&gt;: si verifica che le mitigazioni esistano davvero nel codice e nei test.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;stride-una-lente-per-le-minacce&#34;&gt;STRIDE: una lente per le minacce
&lt;/h2&gt;&lt;p&gt;STRIDE è una checklist mnemonica per non dimenticare categorie di minaccia:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;S  Spoofing        → identità falsificata        → autenticazione
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;T  Tampering       → dati/codice alterati        → integrità, firme
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;R  Repudiation     → &amp;#34;non sono stato io&amp;#34;         → log a prova di manomissione
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;I  Info disclosure → fuga di dati                → cifratura, controllo accessi
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;D  Denial of svc   → risorsa resa indisponibile  → rate limit, quote
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;E  Elevation       → privilegi oltre il dovuto   → least privilege, validazione
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Si scorre ogni elemento del DFD e, per ciascuno, si chiede: può essere vittima di spoofing? di
tampering? e così via. La forza non è la completezza teorica, ma il fatto che &lt;em&gt;struttura&lt;/em&gt; una
conversazione che altrimenti dipende da chi è il più paranoico nella stanza.&lt;/p&gt;
&lt;h2 id=&#34;renderlo-leggero-e-continuo&#34;&gt;Renderlo leggero e continuo
&lt;/h2&gt;&lt;p&gt;Il threat modeling fallisce quando diventa un rito pesante: un documento di 40 pagine, redatto una
volta da un consulente, ignorato da chi scrive il codice. Le pratiche che funzionano in DevSecOps:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Incrementale&lt;/strong&gt;: si modella la &lt;em&gt;modifica&lt;/em&gt;, non tutto il sistema, a ogni design significativo.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Di squadra&lt;/strong&gt;: chi costruisce partecipa; il modello vive nelle loro teste, non in un PDF.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tracciato come codice&lt;/strong&gt;: le minacce diventano issue e test, così &amp;ldquo;l&amp;rsquo;abbiamo mitigata&amp;rdquo; è
verificabile e non un&amp;rsquo;affermazione.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;dallabuse-case-al-test&#34;&gt;Dall&amp;rsquo;abuse case al test
&lt;/h2&gt;&lt;p&gt;Ogni minaccia identificata dovrebbe generare qualcosa di eseguibile: un &lt;em&gt;abuse case&lt;/em&gt; (&amp;ldquo;un utente non
autenticato tenta di leggere l&amp;rsquo;ordine di un altro&amp;rdquo;) che diventa un test di sicurezza automatico. Così
il modello non invecchia in silenzio: se qualcuno reintroduce la falla, il test fallisce. È il ponte
tra il design e i controlli di build dei prossimi capitoli.&lt;/p&gt;


&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Domanda:&lt;/strong&gt; con pipeline che rilasciano dieci volte al giorno, come si fa threat modeling senza bloccare ogni deploy?&lt;/summary&gt;
&lt;p&gt;Non si modella ogni deploy: si modella ogni &lt;em&gt;decisione di design&lt;/em&gt;, che è molto più rara di un
deploy. La maggior parte dei rilasci sono cambi incrementali dentro un&#39;architettura già modellata — una
nuova colonna, un fix, un endpoint in più su un pattern esistente — e non spostano confini di fiducia:
non richiedono nulla. Il trigger non è il tempo né il commit, è il &lt;em&gt;cambio strutturale&lt;/em&gt;: un nuovo
componente, un nuovo flusso di dati verso l&#39;esterno, una nuova integrazione di terze parti, un cambio nel
modello di autenticazione. Quando succede, un threat model leggero di trenta minuti sulla sola modifica
basta, e si fa in fase di design, giorni prima del deploy, non nel percorso critico della pipeline. Alcuni
team lo agganciano alla pull request con una checklist automatica (&#34;questo cambio tocca autenticazione,
dati personali, confini di rete?&#34;): se tutte le risposte sono no, non serve una sessione; se una è sì,
si convoca. Così il controllo pesa solo quando il rischio c&#39;è davvero, e i dieci deploy al giorno di
routine non vengono toccati.&lt;/p&gt;
&lt;/details&gt;


&lt;h2 id=&#34;conclusione&#34;&gt;Conclusione
&lt;/h2&gt;&lt;p&gt;Il threat modeling è il controllo più economico perché agisce prima della prima riga di codice:
quattro domande, la lente STRIDE, e minacce trasformate in test che non invecchiano. Ma il design
sicuro vale poco se poi il codice lascia una chiave API in chiaro nel repository. Il primo difetto
concreto da eliminare nel flusso di sviluppo è proprio questo: la gestione dei segreti, prossimo
capitolo.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Il Secure SDLC: un controllo per ogni fase</title>
        <link>https://www.matteobianchi.eu/p/secure-sdlc/</link>
        <pubDate>Tue, 24 Mar 2026 09:00:00 +0200</pubDate>
        
        <guid>https://www.matteobianchi.eu/p/secure-sdlc/</guid>
        <description>&lt;img src="https://www.matteobianchi.eu/p/secure-sdlc/cover.png" alt="Featured image of post Il Secure SDLC: un controllo per ogni fase" /&gt;&lt;h2 id=&#34;perché-conta&#34;&gt;Perché conta
&lt;/h2&gt;&lt;p&gt;Nel capitolo precedente abbiamo stabilito il &lt;em&gt;perché&lt;/em&gt; dello &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/cos-e-devsecops/&#34; &gt;shift left&lt;/a&gt;.
Ora il &lt;em&gt;dove&lt;/em&gt;: quali attività di sicurezza appartengono a quale fase. Senza una cornice, ogni team
reinventa un insieme casuale di controlli, dimentica interi domini (la gestione dei segreti, la
supply chain) e non sa dire se sta migliorando. Il &lt;strong&gt;Secure SDLC&lt;/strong&gt; è quella cornice.&lt;/p&gt;
&lt;h2 id=&#34;le-fasi-e-i-loro-controlli&#34;&gt;Le fasi e i loro controlli
&lt;/h2&gt;&lt;pre class=&#34;mermaid&#34;&gt;
  flowchart LR
    REQ[Requisiti&amp;lt;br/&amp;gt;abuse case,&amp;lt;br/&amp;gt;requisiti di sicurezza] --&amp;gt; DES[Design&amp;lt;br/&amp;gt;threat modeling]
    DES --&amp;gt; DEV[Sviluppo&amp;lt;br/&amp;gt;SAST, SCA,&amp;lt;br/&amp;gt;secret scanning]
    DEV --&amp;gt; TST[Test&amp;lt;br/&amp;gt;DAST, fuzzing,&amp;lt;br/&amp;gt;security gate]
    TST --&amp;gt; REL[Rilascio&amp;lt;br/&amp;gt;SBOM, firma,&amp;lt;br/&amp;gt;hardening]
    REL --&amp;gt; OPS[Operate&amp;lt;br/&amp;gt;runtime, patch,&amp;lt;br/&amp;gt;detection, IR]
    style DES fill:#fde2e4,stroke:#e63946
&lt;/pre&gt;

&lt;p&gt;Ogni fase ha un controllo &lt;em&gt;naturale&lt;/em&gt;: il momento in cui quel tipo di difetto è più economico da
prevenire. Mettere il threat modeling nel design evita di scrivere codice su un&amp;rsquo;architettura
sbagliata; mettere il SAST nello sviluppo cattura i bug mentre il contesto è fresco nella mente di
chi li ha scritti.&lt;/p&gt;
&lt;h2 id=&#34;due-framework-da-conoscere&#34;&gt;Due framework da conoscere
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;NIST SSDF (SP 800-218)&lt;/strong&gt;: descrive &lt;em&gt;pratiche&lt;/em&gt; in quattro gruppi — preparare l&amp;rsquo;organizzazione,
proteggere il software, produrre software ben protetto, rispondere alle vulnerabilità. È
prescrittivo sul &lt;em&gt;cosa&lt;/em&gt;, agnostico sul &lt;em&gt;come&lt;/em&gt;. Ottimo come checklist di copertura.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OWASP SAMM&lt;/strong&gt;: un &lt;em&gt;modello di maturità&lt;/em&gt;. Non chiede solo &amp;ldquo;lo fai?&amp;rdquo; ma &amp;ldquo;a che livello?&amp;rdquo; (1, 2, 3)
su quindici pratiche. Serve a misurare dove sei e dove andare, non a fare tutto subito.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;maturità-non-perfezione&#34;&gt;Maturità, non perfezione
&lt;/h2&gt;&lt;p&gt;L&amp;rsquo;errore classico è voler implementare ogni controllo al massimo livello dal primo giorno. Risultato:
pipeline lentissime, team in rivolta, controlli disattivati. La maturità è un percorso:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Livello 1  controllo implementato, anche solo su progetti pilota   ← comincia qui
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Livello 2  applicato in modo coerente, con processo definito
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Livello 3  misurato, ottimizzato, automatizzato ovunque
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Si sceglie &lt;em&gt;per rischio&lt;/em&gt;: i servizi esposti a internet e che toccano dati sensibili salgono di
livello prima di un tool interno letto da tre persone. Una cornice serve a prioritizzare, non a
pretendere uniformità.&lt;/p&gt;
&lt;h2 id=&#34;il-sdlc-incontra-il-cicd&#34;&gt;Il SDLC incontra il CI/CD
&lt;/h2&gt;&lt;p&gt;Il Secure SDLC è il &lt;em&gt;cosa&lt;/em&gt;; la pipeline CI/CD è il &lt;em&gt;dove lo automatizzi&lt;/em&gt;. Ogni controllo della
catena ha una collocazione naturale nella pipeline: il secret scanning come hook di pre-commit, il
SAST sulla pull request, il DAST in staging, la firma dell&amp;rsquo;artefatto al rilascio. I capitoli
successivi riempiono ogni casella; questa è la mappa che impedisce di dimenticarne una.&lt;/p&gt;


&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Domanda:&lt;/strong&gt; i framework come SSDF e SAMM non sono solo burocrazia che rallenta un team agile?&lt;/summary&gt;
&lt;p&gt;Diventano burocrazia solo se usati male — come moduli da compilare per un auditor invece che come
checklist per non dimenticare domini interi. Usati bene fanno l&#39;opposto di rallentare: evitano la
retromarcia costosa. Il team agile che salta il threat modeling e scopre a sei mesi dal lancio che
l&#39;architettura di multi-tenancy perde dati tra clienti non è stato veloce, è stato veloce verso un muro.
Il valore di una cornice non è la cerimonia, è la &lt;em&gt;copertura&lt;/em&gt;: senza, è statisticamente certo che
dimenticherai qualcosa — di solito la gestione dei segreti o la supply chain, i due domini che nessuno
&#34;sente&#34; come proprio finché non esplodono. Il modo agile di usare questi framework è prenderli come menu,
non come contratto: scegli i controlli proporzionati al rischio del servizio, li automatizzi nella
pipeline così non pesano sul lavoro quotidiano, e sali di maturità quando il rischio lo giustifica. La
cornice è leggera; è l&#39;incidente che evita a essere pesante.&lt;/p&gt;
&lt;/details&gt;


&lt;h2 id=&#34;conclusione&#34;&gt;Conclusione
&lt;/h2&gt;&lt;p&gt;Il Secure SDLC mappa un controllo a ogni fase, e i modelli di maturità trasformano &amp;ldquo;fai tutto&amp;rdquo; in un
percorso guidato dal rischio. È la mappa; il resto della serie sono le tappe. La prima, e quella con
il miglior rapporto costo/beneficio, vive nel design: ragionare da attaccante &lt;em&gt;prima&lt;/em&gt; di scrivere
codice. È il threat modeling, prossimo capitolo.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Che cos&#39;è DevSecOps (e cosa non è)</title>
        <link>https://www.matteobianchi.eu/p/cos-e-devsecops/</link>
        <pubDate>Tue, 17 Mar 2026 09:00:00 +0200</pubDate>
        
        <guid>https://www.matteobianchi.eu/p/cos-e-devsecops/</guid>
        <description>&lt;img src="https://www.matteobianchi.eu/p/cos-e-devsecops/cover.png" alt="Featured image of post Che cos&#39;è DevSecOps (e cosa non è)" /&gt;&lt;h2 id=&#34;perché-conta&#34;&gt;Perché conta
&lt;/h2&gt;&lt;p&gt;Il modello tradizionale tratta la sicurezza come un cancello: il team costruisce per mesi, poi un
gruppo separato fa un audit e restituisce una lista di problemi. A quel punto correggere è costoso,
lento e conflittuale. &lt;strong&gt;DevSecOps&lt;/strong&gt; elimina il cancello e distribuisce la sicurezza lungo tutto il
flusso. La &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/devsecops-la-serie/&#34; &gt;serie&lt;/a&gt; parte da qui perché, senza capire &lt;em&gt;il
perché&lt;/em&gt;, ogni strumento diventa solo un altro ostacolo da aggirare.&lt;/p&gt;
&lt;h2 id=&#34;il-costo-del-difetto-nel-tempo&#34;&gt;Il costo del difetto nel tempo
&lt;/h2&gt;&lt;p&gt;L&amp;rsquo;argomento economico è il più solido. Un difetto costa in modo crescente a seconda di quando lo si
scopre:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Fase in cui si trova il difetto      Costo relativo di correzione
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Design / requisiti                  1×   ← qui vuoi i controlli
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Implementazione                     ~5×
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Test / QA                           ~10×
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Produzione                          ~30× e oltre  ← qui li trovi se non fai nulla
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Le cifre esatte variano da studio a studio, ma la direzione è costante: &lt;strong&gt;prima trovi, meno paghi&lt;/strong&gt;.
Questo è il senso economico dello &lt;em&gt;shift left&lt;/em&gt;, spostare i controlli verso sinistra nella timeline.&lt;/p&gt;
&lt;h2 id=&#34;i-tre-pilastri&#34;&gt;I tre pilastri
&lt;/h2&gt;&lt;p&gt;DevSecOps non è un prodotto. È l&amp;rsquo;incontro di tre dimensioni:&lt;/p&gt;
&lt;pre class=&#34;mermaid&#34;&gt;
  flowchart TD
    P[Persone&amp;lt;br/&amp;gt;responsabilità condivisa] --- PR[Processi&amp;lt;br/&amp;gt;sicurezza in ogni fase]
    PR --- T[Tecnologia&amp;lt;br/&amp;gt;automazione nel flusso]
    T --- P
    style P fill:#fde2e4,stroke:#e63946
&lt;/pre&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Persone&lt;/strong&gt;: la sicurezza è di tutti, non di un team isolato. Gli sviluppatori ricevono feedback
nel loro strumento (IDE, pull request), non in un report che leggeranno forse mai.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Processi&lt;/strong&gt;: ogni fase ha un controllo adeguato, dal design al runtime. Niente è lasciato &amp;ldquo;al
momento del rilascio&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tecnologia&lt;/strong&gt;: i controlli sono &lt;strong&gt;automatizzati&lt;/strong&gt; nella pipeline. Ciò che è manuale viene saltato
sotto pressione; ciò che è automatico vale per ogni commit.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;cosa-non-è-devsecops&#34;&gt;Cosa NON è DevSecOps
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Non è comprare uno strumento&lt;/strong&gt;: uno scanner senza un processo che agisca sui risultati produce
solo rumore.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Non è assumere un &amp;ldquo;DevSecOps engineer&amp;rdquo;&lt;/strong&gt; che faccia sicurezza al posto degli altri: ricrea il
silo che si voleva eliminare.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Non è bloccare ogni build al primo warning&lt;/strong&gt;: una pipeline che grida al lupo viene disattivata.
La sicurezza utile è quella &lt;em&gt;azionabile&lt;/em&gt; e proporzionata al rischio.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;guardrail-non-gate&#34;&gt;Guardrail, non gate
&lt;/h2&gt;&lt;p&gt;La metafora giusta non è il cancello (gate) che ferma tutti, ma il &lt;strong&gt;guardrail&lt;/strong&gt;: una protezione che
ti lascia andare veloce mantenendoti in carreggiata. Un buon controllo DevSecOps dà un feedback
rapido, con pochi falsi positivi, e dice &lt;em&gt;come&lt;/em&gt; risolvere — non solo &lt;em&gt;che&lt;/em&gt; c&amp;rsquo;è un problema.&lt;/p&gt;


&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Domanda:&lt;/strong&gt; se &#34;shift left&#34; mette tutti i controlli all&#39;inizio, non trascuriamo la sicurezza in produzione, dove avvengono gli attacchi veri?&lt;/summary&gt;
&lt;p&gt;È un fraintendimento comune e importante da correggere: shift-left non significa spostare &lt;em&gt;tutto&lt;/em&gt;
a sinistra, significa &lt;em&gt;aggiungere&lt;/em&gt; controlli a sinistra senza togliere quelli a destra. Il termine
più onesto oggi è &#34;shift everywhere&#34;. Trovare una SQL injection in fase di design con il threat modeling
costa un disegno su una lavagna; trovarla con il SAST in fase di build costa un commento su una pull
request; trovarla con il DAST in staging costa un ticket; trovarla in produzione con un WAF o la detection
costa un incidente. Sono controlli complementari, non alternativi: ognuno cattura ciò che gli altri si
lasciano sfuggire. Il SAST non vede un errore di configurazione del server, il runtime non vede una logica
di business difettosa fino a quando non viene sfruttata. La difesa in profondità vuole controlli a ogni
stadio; shift-left corregge solo lo squilibrio storico per cui a sinistra non c&#39;era &lt;em&gt;nulla&lt;/em&gt; e tutto
il peso cadeva su un audit finale. Chi interpreta shift-left come &#34;smontiamo il monitoraggio di produzione&#34;
ha capito l&#39;esatto contrario.&lt;/p&gt;
&lt;/details&gt;


&lt;h2 id=&#34;conclusione&#34;&gt;Conclusione
&lt;/h2&gt;&lt;p&gt;DevSecOps è un cambiamento di responsabilità (da un silo a tutti), di tempismo (da fine a ovunque) e
di modo (da manuale ad automatico). L&amp;rsquo;argomento è economico prima che morale: trovare presto costa
meno. Il primo controllo che sposta a sinistra non è uno scanner, ma una conversazione sul design:
il threat modeling. Ma prima serve una cornice che dica &lt;em&gt;quali&lt;/em&gt; pratiche e &lt;em&gt;dove&lt;/em&gt; — il Secure SDLC,
prossimo capitolo.&lt;/p&gt;
</description>
        </item>
        
    </channel>
</rss>
