<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Kata on lo0 — Blog Técnico</title><link>https://blog.lo0.es/tags/kata/</link><description>Recent content in Kata on lo0 — Blog Técnico</description><generator>Hugo -- gohugo.io</generator><language>es</language><lastBuildDate>Tue, 09 Jun 2026 17:00:00 +0200</lastBuildDate><atom:link href="https://blog.lo0.es/tags/kata/index.xml" rel="self" type="application/rss+xml"/><item><title>Runbook: enjaular al agente de IA — bubblewrap en el cliente, Tetragon en el cluster</title><link>https://blog.lo0.es/posts/runbook-aislar-agentes-ia-bubblewrap-tetragon/</link><pubDate>Tue, 09 Jun 2026 17:00:00 +0200</pubDate><guid>https://blog.lo0.es/posts/runbook-aislar-agentes-ia-bubblewrap-tetragon/</guid><description>&lt;blockquote>
&lt;p>Compañero &lt;strong>operativo&lt;/strong> de &lt;a href="https://blog.lo0.es/posts/aislar-agentes-ia-cliente-cluster/">El contratista con la llave maestra&lt;/a>. Aquel post explica el &lt;em>porqué&lt;/em> y el &lt;em>dónde&lt;/em> —el modelo de amenaza, las cinco familias de aislamiento, qué dominio usa cada una—; este es el &lt;em>cómo&lt;/em>, con comandos. Si no lo has leído, léelo antes: aquí doy por sabido qué es el radio de explosión, por qué &lt;code>bwrap&lt;/code> corre sin root y qué vigila Tetragon. El procedimiento va en dos tracks independientes —&lt;strong>cliente&lt;/strong> y &lt;strong>cluster&lt;/strong>— porque, como argumenta el post hermano, el control se extrapola pero la primitiva se reescribe.&lt;/p>
&lt;/blockquote>
&lt;h2 id="tldr">TL;DR&lt;/h2>
&lt;p>Dos procedimientos reproducibles. &lt;strong>Cliente (workstation):&lt;/strong> instala &lt;code>ai-jail&lt;/code> (envuelve &lt;code>bubblewrap&lt;/code>), genera el &lt;code>.ai-jail&lt;/code> por proyecto, audita con &lt;code>--dry-run&lt;/code>, fija las allowlists con &lt;code>--bootstrap&lt;/code>, usa &lt;code>--lockdown&lt;/code> para lo que no te fíes, y deja al agente sin permiso de &lt;code>git push&lt;/code>. &lt;strong>Cluster (RKE2 con Cilium + Tetragon):&lt;/strong> pon el baseline de pod (&lt;code>securityContext&lt;/code> sin privilegios, &lt;code>seccomp: RuntimeDefault&lt;/code>, &lt;code>NetworkPolicy&lt;/code> default-deny), mete el pod del agente no confiable en una microVM con &lt;code>runtimeClassName: kata&lt;/code>, y despliega las &lt;code>TracingPolicy&lt;/code> de Tetragon en &lt;strong>dos fases&lt;/strong> —observar con &lt;code>action: Post&lt;/code> para levantar el baseline, luego promover a &lt;code>action: Sigkill&lt;/code> sobre &lt;code>tcp_connect&lt;/code> (egress) y &lt;code>security_file_open&lt;/code> (rutas de secretos)—. La regla de oro de la fase Tetragon: &lt;strong>adopta primero, bloquea después&lt;/strong>; nunca metas un &lt;code>Sigkill&lt;/code> en producción sin haber visto antes los eventos en modo observación.&lt;/p>
&lt;h2 id="el-flujo-de-los-dos-tracks">El flujo de los dos tracks&lt;/h2>
&lt;div class="diagram" style="max-width:800px;margin:1.5rem auto;">
&lt;svg viewBox="0 0 800 250" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Dos tracks operativos: cliente (instalar, configurar, bootstrap, lockdown) y cluster (baseline, RuntimeClass, observar, enforce)">
&lt;defs>&lt;marker id="rm2" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto">&lt;path d="M0,0 L10,5 L0,10 z" fill="#666"/>&lt;/marker>&lt;/defs>
&lt;text x="400" y="22" text-anchor="middle" font-family="sans-serif" font-size="13" font-weight="700" fill="currentColor">Track CLIENTE — workstation&lt;/text>
&lt;rect x="20" y="36" width="150" height="46" rx="7" fill="#d4ecff" stroke="#1f5fa8" stroke-width="1.4"/>
&lt;text x="95" y="56" text-anchor="middle" font-family="sans-serif" font-size="11" font-weight="600" fill="#0d3a66">1 · Instalar&lt;/text>
&lt;text x="95" y="72" text-anchor="middle" font-family="sans-serif" font-size="9.5" fill="#0d3a66">ai-jail + bwrap&lt;/text>
&lt;rect x="200" y="36" width="150" height="46" rx="7" fill="#d4ecff" stroke="#1f5fa8" stroke-width="1.4"/>
&lt;text x="275" y="56" text-anchor="middle" font-family="sans-serif" font-size="11" font-weight="600" fill="#0d3a66">2 · .ai-jail&lt;/text>
&lt;text x="275" y="72" text-anchor="middle" font-family="sans-serif" font-size="9.5" fill="#0d3a66">--dry-run&lt;/text>
&lt;rect x="380" y="36" width="150" height="46" rx="7" fill="#d4ecff" stroke="#1f5fa8" stroke-width="1.4"/>
&lt;text x="455" y="56" text-anchor="middle" font-family="sans-serif" font-size="11" font-weight="600" fill="#0d3a66">3 · --bootstrap&lt;/text>
&lt;text x="455" y="72" text-anchor="middle" font-family="sans-serif" font-size="9.5" fill="#0d3a66">allow/deny/ask&lt;/text>
&lt;rect x="560" y="36" width="150" height="46" rx="7" fill="#d4ecff" stroke="#1f5fa8" stroke-width="1.4"/>
&lt;text x="635" y="52" text-anchor="middle" font-family="sans-serif" font-size="11" font-weight="600" fill="#0d3a66">4 · lockdown&lt;/text>
&lt;text x="635" y="68" text-anchor="middle" font-family="sans-serif" font-size="9.5" fill="#0d3a66">+ git sin push&lt;/text>
&lt;path d="M170,59 L198,59" stroke="#666" stroke-width="1.5" fill="none" marker-end="url(#rm2)"/>
&lt;path d="M350,59 L378,59" stroke="#666" stroke-width="1.5" fill="none" marker-end="url(#rm2)"/>
&lt;path d="M530,59 L558,59" stroke="#666" stroke-width="1.5" fill="none" marker-end="url(#rm2)"/>
&lt;line x1="20" y1="118" x2="780" y2="118" stroke="#ccc" stroke-width="1" stroke-dasharray="3 3"/>
&lt;text x="400" y="150" text-anchor="middle" font-family="sans-serif" font-size="13" font-weight="700" fill="currentColor">Track CLUSTER — RKE2 + Cilium/Tetragon&lt;/text>
&lt;rect x="20" y="164" width="150" height="46" rx="7" fill="#e6d9f2" stroke="#5a2db0" stroke-width="1.4"/>
&lt;text x="95" y="184" text-anchor="middle" font-family="sans-serif" font-size="11" font-weight="600" fill="#42208a">1 · Baseline&lt;/text>
&lt;text x="95" y="200" text-anchor="middle" font-family="sans-serif" font-size="9.5" fill="#42208a">secCtx+NetPol&lt;/text>
&lt;rect x="200" y="164" width="150" height="46" rx="7" fill="#e6d9f2" stroke="#5a2db0" stroke-width="1.4"/>
&lt;text x="275" y="184" text-anchor="middle" font-family="sans-serif" font-size="11" font-weight="600" fill="#42208a">2 · RuntimeClass&lt;/text>
&lt;text x="275" y="200" text-anchor="middle" font-family="sans-serif" font-size="9.5" fill="#42208a">kata microVM&lt;/text>
&lt;rect x="380" y="164" width="150" height="46" rx="7" fill="#fde9d6" stroke="#a85a00" stroke-width="1.6"/>
&lt;text x="455" y="184" text-anchor="middle" font-family="sans-serif" font-size="11" font-weight="600" fill="#8a4a00">3 · Observar&lt;/text>
&lt;text x="455" y="200" text-anchor="middle" font-family="sans-serif" font-size="9.5" fill="#8a4a00">Tetragon · Post&lt;/text>
&lt;rect x="560" y="164" width="150" height="46" rx="7" fill="#fbd4b8" stroke="#a85a00" stroke-width="1.8"/>
&lt;text x="635" y="184" text-anchor="middle" font-family="sans-serif" font-size="11" font-weight="600" fill="#8a4a00">4 · Enforce&lt;/text>
&lt;text x="635" y="200" text-anchor="middle" font-family="sans-serif" font-size="9.5" fill="#8a4a00">Tetragon · Sigkill&lt;/text>
&lt;path d="M170,187 L198,187" stroke="#666" stroke-width="1.5" fill="none" marker-end="url(#rm2)"/>
&lt;path d="M350,187 L378,187" stroke="#666" stroke-width="1.5" fill="none" marker-end="url(#rm2)"/>
&lt;path d="M530,187 L558,187" stroke="#666" stroke-width="1.5" fill="none" marker-end="url(#rm2)"/>
&lt;text x="400" y="236" text-anchor="middle" font-family="sans-serif" font-size="10" font-style="italic" fill="#555">adopta primero (observar), bloquea después (enforce)&lt;/text>
&lt;/svg>
&lt;/div>
&lt;hr>
&lt;h1 id="track-a--cliente-workstation-del-desarrollador">Track A — Cliente (workstation del desarrollador)&lt;/h1>
&lt;h2 id="a0--instalar-ai-jail-y-bubblewrap">A0 — Instalar ai-jail y bubblewrap&lt;/h2>
&lt;p>&lt;code>ai-jail&lt;/code> envuelve el sandbox; en Linux necesita &lt;code>bubblewrap&lt;/code> aparte, en macOS no necesita dependencia extra.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># ai-jail (macOS y Linux)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">brew tap akitaonrails/tap &lt;span class="o">&amp;amp;&amp;amp;&lt;/span> brew install ai-jail
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># o, con cargo:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">cargo install ai-jail
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># o, con mise:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">mise use -g ubi:akitaonrails/ai-jail
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># bubblewrap en Linux (elige tu distro)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">sudo pacman -S bubblewrap &lt;span class="c1"># Arch&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">sudo apt install bubblewrap &lt;span class="c1"># Debian / Ubuntu&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">sudo dnf install bubblewrap &lt;span class="c1"># Fedora&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Comprueba que el binario está y que &lt;code>bwrap&lt;/code> corre sin root (no debe pedir &lt;code>sudo&lt;/code>):&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">ai-jail --version
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">bwrap --ro-bind / / --unshare-all &lt;span class="nb">echo&lt;/span> &lt;span class="s2">&amp;#34;bwrap ok sin root&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Si &lt;code>bwrap&lt;/code> falla pidiendo privilegios, tu kernel tiene los &lt;em>unprivileged user namespaces&lt;/em> deshabilitados; habilítalos (&lt;code>sysctl kernel.unprivileged_userns_clone=1&lt;/code> en Debian/Ubuntu antiguos) antes de seguir.&lt;/p>
&lt;h2 id="a1--el-fichero-ai-jail-por-proyecto">A1 — El fichero .ai-jail por proyecto&lt;/h2>
&lt;p>En el primer arranque dentro del proyecto, &lt;code>ai-jail&lt;/code> crea un &lt;code>.ai-jail&lt;/code> (TOML) &lt;strong>commiteable al repo&lt;/strong>: cualquier compañero que clone hereda la misma política.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">cd&lt;/span> ~/Projects/mi-app
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">ai-jail claude &lt;span class="c1"># crea .ai-jail y lanza Claude Code dentro del sandbox&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>El fichero generado:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-toml" data-lang="toml">&lt;span class="line">&lt;span class="cl">&lt;span class="c"># .ai-jail — configuración del sandbox (commitéalo al repo)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">command&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;claude&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">rw_maps&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="p">[]&lt;/span> &lt;span class="c"># directorios extra con escritura&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">ro_maps&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="p">[]&lt;/span> &lt;span class="c"># directorios extra de solo lectura&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>Antes de confiar en el sandbox, audítalo.&lt;/strong> &lt;code>--dry-run --verbose&lt;/code> imprime cada punto de montaje, cada flag de aislamiento y el comando &lt;code>bwrap&lt;/code> completo, sin ejecutar nada:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">ai-jail --dry-run --verbose claude
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Lee la salida y confirma tres cosas: que &lt;code>$HOME&lt;/code> se monta como tmpfs (no el real), que &lt;code>~/.ssh&lt;/code>, &lt;code>~/.aws&lt;/code> y &lt;code>~/.gnupg&lt;/code> &lt;strong>no aparecen&lt;/strong> entre los montajes, y que el único directorio con escritura es el del proyecto. Si necesitas un directorio extra:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">ai-jail --rw-map ~/Projects/shared-lib claude &lt;span class="c1"># extra con escritura&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">ai-jail --map /opt/datasets claude &lt;span class="c1"># extra de solo lectura&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Otros agentes, mismo binario:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">ai-jail codex
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">ai-jail opencode
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">ai-jail bash &lt;span class="c1"># shell pelado para depurar el sandbox&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">ai-jail -- python script.py &lt;span class="c1"># cualquier comando&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="a2--las-allowlists-de-permisos-con---bootstrap">A2 — Las allowlists de permisos con &amp;ndash;bootstrap&lt;/h2>
&lt;p>&lt;code>--bootstrap&lt;/code> genera las configuraciones de permisos de cada agente, con allow/deny/ask sensatos, y hace backup antes de sobrescribir:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">ai-jail --bootstrap
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Lo que produce, en resumen:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Agente&lt;/th>
&lt;th>Fichero&lt;/th>
&lt;th>Política base&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Claude Code&lt;/td>
&lt;td>&lt;code>~/.claude/settings.json&lt;/code>&lt;/td>
&lt;td>&lt;strong>allow&lt;/strong>: &lt;code>git status/diff/log&lt;/code>, &lt;code>ls&lt;/code>, &lt;code>grep&lt;/code>, &lt;code>cargo&lt;/code>, &lt;code>npm&lt;/code>, &lt;code>python&lt;/code>, &lt;code>docker compose&lt;/code> · &lt;strong>ask&lt;/strong>: &lt;code>git push&lt;/code>, &lt;code>rm&lt;/code>, &lt;code>docker run&lt;/code> · &lt;strong>deny&lt;/strong>: &lt;code>rm -rf&lt;/code>, &lt;code>sudo&lt;/code>, &lt;code>chmod 777&lt;/code>, &lt;code>git push --force&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Codex&lt;/td>
&lt;td>&lt;code>~/.codex/config.toml&lt;/code>&lt;/td>
&lt;td>&lt;code>approval_policy = &amp;quot;on-request&amp;quot;&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>OpenCode&lt;/td>
&lt;td>&lt;code>~/.config/opencode/opencode.json&lt;/code>&lt;/td>
&lt;td>permisos de &lt;code>bash&lt;/code>, &lt;code>edit&lt;/code>, &lt;code>write&lt;/code>&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>La clave operativa: &lt;code>git push&lt;/code> está en &lt;strong>ask&lt;/strong>, no en &lt;strong>allow&lt;/strong>, y &lt;code>git push --force&lt;/code> en &lt;strong>deny&lt;/strong>. El agente puede commitear, ramear y rebasar localmente cuanto quiera; nada de eso toca el remoto. (Si usas el &lt;code>/sandbox&lt;/code> de Claude Code, fija además &lt;code>&amp;quot;allowUnsandboxedCommands&amp;quot;: false&lt;/code> para cerrar el &lt;em>escape hatch&lt;/em> &lt;code>dangerouslyDisableSandbox&lt;/code>, que de fábrica es opt-out.)&lt;/p>
&lt;h2 id="a3--lockdown-para-lo-que-no-te-fíes">A3 — Lockdown para lo que no te fíes&lt;/h2>
&lt;p>Para auditar código de terceros o correr un agente sobre un proyecto que no conoces, &lt;code>--lockdown&lt;/code> va más allá: proyecto montado en &lt;strong>read-only&lt;/strong>, GPU/Docker/display deshabilitados, &lt;code>--rw-map&lt;/code>/&lt;code>--map&lt;/code> ignorados, &lt;code>$HOME&lt;/code> tmpfs puro sin dotfiles del host, red cortada con &lt;code>--unshare-net&lt;/code> y environment limpiado con &lt;code>--clearenv&lt;/code>.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">ai-jail --lockdown bash
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Es el sandbox más restrictivo posible sin llegar a una VM. Úsalo como defecto mental para todo lo que no sea tu propio código en tu propia máquina.&lt;/p>
&lt;h2 id="a4--la-red-de-seguridad-git-sin-push">A4 — La red de seguridad: git sin push&lt;/h2>
&lt;p>No es un flag, es una propiedad del entorno que cambia el cálculo de riesgo. Si el proyecto está en git con remoto, y el agente &lt;strong>no&lt;/strong> tiene permiso de &lt;code>push&lt;/code>, el peor caso —que corrompa cada fichero del proyecto— se revierte con:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">git checkout . &lt;span class="c1"># vuelve al último commit&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># y si tocó .git (improbable): borra el dir y re-clona&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>El remoto nunca se tocó. &lt;strong>Sandbox para el filesystem + git para el código + push manual&lt;/strong> es ya un nivel razonable para uso diario: &lt;code>ai-jail&lt;/code> protege tus datos y el sistema, git protege el código, y la decisión de publicar sigue siendo tuya.&lt;/p>
&lt;hr>
&lt;h1 id="track-b--cluster-rke2-con-cilium--tetragon">Track B — Cluster (RKE2 con Cilium + Tetragon)&lt;/h1>
&lt;p>El agente no confiable —o la inferencia que ejecuta código generado— corre como pod. El mismo principio del cliente, otras primitivas. Asumimos un cluster genérico RKE2 con Cilium como CNI y Tetragon ya desplegado (el &lt;code>DaemonSet&lt;/code> del agente eBPF en cada nodo).&lt;/p>
&lt;h2 id="b0--el-baseline-del-pod">B0 — El baseline del pod&lt;/h2>
&lt;p>Antes de cualquier eBPF, lo de serie. &lt;code>securityContext&lt;/code> sin privilegios, raíz read-only, seccomp por defecto:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="nt">apiVersion&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">v1&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">kind&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">Pod&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">metadata&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">ai-agent&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">namespace&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">agentes&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">labels&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">app&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">ai-agent&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">spec&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">securityContext&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">runAsNonRoot&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">true&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">runAsUser&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">10001&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">seccompProfile&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">type&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">RuntimeDefault&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">containers&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">agent&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">image&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">registry.interno/ai-agent:pinned&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">securityContext&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">allowPrivilegeEscalation&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">false&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">readOnlyRootFilesystem&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">true&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">capabilities&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">drop&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;ALL&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">volumeMounts&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- {&lt;span class="w"> &lt;/span>&lt;span class="nt">name: work, mountPath&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">/work } &lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># único escribible&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">volumes&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">work&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">emptyDir&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>{}&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Y el corte de egress por defecto —el gemelo cluster del &lt;code>--unshare-net&lt;/code>—. NetworkPolicy default-deny de salida en el namespace, abriendo solo DNS y lo imprescindible:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="nt">apiVersion&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">networking.k8s.io/v1&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">kind&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">NetworkPolicy&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">metadata&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">default-deny-egress&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">namespace&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">agentes&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">spec&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">podSelector&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>{}&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">policyTypes&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;Egress&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">egress&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">to&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">namespaceSelector&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">matchLabels&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>{&lt;span class="w"> &lt;/span>&lt;span class="nt">kubernetes.io/metadata.name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">kube-system }&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">ports&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- {&lt;span class="w"> &lt;/span>&lt;span class="nt">protocol: UDP, port&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">53&lt;/span>&lt;span class="w"> &lt;/span>}&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- {&lt;span class="w"> &lt;/span>&lt;span class="nt">protocol: TCP, port&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">53&lt;/span>&lt;span class="w"> &lt;/span>}&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="b1--runtimeclass-kata-el-pod-no-confiable-en-su-propia-microvm">B1 — RuntimeClass Kata: el pod no confiable en su propia microVM&lt;/h2>
&lt;p>Para código realmente no confiable, sácalo del kernel compartido. Con Kata desplegado existe un &lt;code>RuntimeClass&lt;/code>:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="nt">apiVersion&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">node.k8s.io/v1&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">kind&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">RuntimeClass&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">metadata&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">kata&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">handler&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">kata&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Y el pod lo pide con una línea —&lt;code>runtimeClassName: kata&lt;/code>—, ejecutándose en su propia microVM con kernel dedicado en lugar de compartir el del nodo:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="nt">spec&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">runtimeClassName&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">kata &lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># ← el pod corre en una microVM, no en el kernel del nodo&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="c"># ...resto igual que B0&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Es el gemelo cluster del aislamiento por construcción: un exploit de kernel dentro del pod no alcanza al nodo.&lt;/p>
&lt;h2 id="b2--tetragon-fase-observación-post">B2 — Tetragon, fase observación (Post)&lt;/h2>
&lt;p>Ahora la capa que distingue una plataforma con visibilidad de runtime. &lt;strong>Primero observar, nunca matar de entrada.&lt;/strong> Una &lt;code>TracingPolicyNamespaced&lt;/code> —scoped al namespace y a la etiqueta del agente— que reporta (no mata) tres cosas: ejecuciones de proceso, conexiones de red y aperturas de rutas sensibles. &lt;code>action: Post&lt;/code> solo emite el evento.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="nt">apiVersion&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">cilium.io/v1alpha1&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">kind&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">TracingPolicyNamespaced&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">metadata&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">agente-observa&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">namespace&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">agentes&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">spec&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">podSelector&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">matchLabels&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">app&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">ai-agent&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">kprobes&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="c"># --- conexiones salientes ---&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">call&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;tcp_connect&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">syscall&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">false&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">args&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">index&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">0&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">type&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;sock&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">selectors&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">matchActions&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">action&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">Post&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="c"># --- aperturas de ficheros sensibles ---&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">call&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;security_file_open&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">syscall&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">false&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">args&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">index&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">0&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">type&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;file&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">selectors&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">matchArgs&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">index&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">0&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">operator&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;Prefix&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">values&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="s2">&amp;#34;/var/run/secrets&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="s2">&amp;#34;/work/.git/config&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">matchActions&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">action&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">Post&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>(Las ejecuciones de proceso no necesitan kprobe: Tetragon emite &lt;code>process_exec&lt;/code>/&lt;code>process_exit&lt;/code> de forma nativa.) Despliega y observa los eventos en vivo desde el pod de Tetragon del nodo:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">kubectl apply -f agente-observa.yaml
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># eventos legibles, filtrando por el namespace:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">kubectl &lt;span class="nb">exec&lt;/span> -n kube-system ds/tetragon -c tetragon -- &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> tetra getevents -o compact --namespace agentes
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Deja esto rodando una jornada típica del agente. Apunta a &lt;strong>qué destinos&lt;/strong> conecta de verdad (tu registry interno, tu mirror de HF, tu endpoint de vLLM) y &lt;strong>qué rutas&lt;/strong> abre. Eso es tu baseline: la lista de lo legítimo. Sin este paso, un &lt;code>Sigkill&lt;/code> mata trabajo bueno y te genera un incidente de disponibilidad —justo lo que el ENS te pide evitar—.&lt;/p>
&lt;h2 id="b3--tetragon-fase-enforcement-sigkill">B3 — Tetragon, fase enforcement (Sigkill)&lt;/h2>
&lt;p>Con el baseline en la mano, promueve a bloqueo. Dos reglas. La primera: &lt;strong>mata cualquier conexión cuyo destino no esté en la allowlist&lt;/strong> —&lt;code>NotDAddr&lt;/code> invierte el match: dispara para todo lo que &lt;em>no&lt;/em> sea esas redes—. La segunda: &lt;strong>mata cualquier intento de abrir una ruta de secretos&lt;/strong>.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="nt">apiVersion&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">cilium.io/v1alpha1&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">kind&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">TracingPolicyNamespaced&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">metadata&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">agente-enforce&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">namespace&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">agentes&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">spec&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">podSelector&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">matchLabels&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">app&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">ai-agent&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">kprobes&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="c"># --- egress: mata todo lo que NO sea la allowlist ---&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">call&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;tcp_connect&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">syscall&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">false&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">args&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">index&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">0&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">type&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;sock&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">selectors&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">matchArgs&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">index&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">0&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">operator&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;NotDAddr&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">values&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="s2">&amp;#34;127.0.0.1&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="s2">&amp;#34;10.0.0.0/8&amp;#34;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># red interna del cluster&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="s2">&amp;#34;172.16.10.20&amp;#34;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># registry interno (ejemplo)&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">matchActions&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">action&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">Sigkill&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="c"># --- lectura de secretos: mata el proceso ---&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">call&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;security_file_open&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">syscall&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">false&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">args&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">index&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">0&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">type&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;file&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">selectors&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">matchArgs&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">index&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">0&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">operator&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;Prefix&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">values&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="s2">&amp;#34;/var/run/secrets/kubernetes.io/serviceaccount/token&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="s2">&amp;#34;/work/.ssh&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">matchActions&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">action&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">Sigkill&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">kubectl apply -f agente-enforce.yaml
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Ahora el agente puede hacer lo que quiera dentro del pod, pero &lt;strong>en el instante&lt;/strong> en que intenta conectar a un destino no permitido o leer el token de la service account, Tetragon lo mata en el kernel —antes de que el paquete salga o el &lt;code>read&lt;/code> devuelva bytes—. Es el gemelo cluster de la blocklist de &lt;code>curl&lt;/code> y del &lt;code>~/.ssh&lt;/code> no montado, pero aplicado en runtime y sobre &lt;em>cualquier&lt;/em> binario, no solo los que conoces.&lt;/p>
&lt;blockquote>
&lt;p>&lt;strong>Aviso operativo.&lt;/strong> El enforcement con &lt;code>Sigkill&lt;/code> requiere kernel reciente con soporte de la acción en eBPF (5.10+ es seguro). Despliega &lt;code>agente-enforce&lt;/code> primero en un namespace de pruebas, y mantén &lt;code>agente-observa&lt;/code> activo en paralelo: si el bloqueo dispara, el evento &lt;code>Post&lt;/code> te dice exactamente qué lo provocó. Adopta primero, bloquea después.&lt;/p>
&lt;/blockquote>
&lt;h2 id="la-tabla-de-equivalencias-cliente--cluster">La tabla de equivalencias cliente ↔ cluster&lt;/h2>
&lt;p>El mismo vector, las dos primitivas. Esto es &amp;ldquo;extrapolar la tecnología&amp;rdquo; hecho explícito:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Vector de amenaza&lt;/th>
&lt;th>Cliente (workstation)&lt;/th>
&lt;th>Cluster (RKE2)&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>$HOME&lt;/code> / raíz escribible&lt;/td>
&lt;td>&lt;code>$HOME&lt;/code> como tmpfs efímero (&lt;code>bwrap&lt;/code>)&lt;/td>
&lt;td>&lt;code>readOnlyRootFilesystem: true&lt;/code> + &lt;code>emptyDir&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Egress arbitrario&lt;/td>
&lt;td>blocklist &lt;code>curl&lt;/code>/&lt;code>wget&lt;/code> · &lt;code>--unshare-net&lt;/code>&lt;/td>
&lt;td>NetworkPolicy default-deny + Tetragon &lt;code>NotDAddr&lt;/code>→&lt;code>Sigkill&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Lectura de secretos&lt;/td>
&lt;td>&lt;code>~/.ssh&lt;/code>/&lt;code>~/.aws&lt;/code>/&lt;code>~/.gnupg&lt;/code> no montados&lt;/td>
&lt;td>secretos fuera del pod + Tetragon &lt;code>security_file_open&lt;/code>→&lt;code>Sigkill&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Escape del kernel&lt;/td>
&lt;td>Landlock (2ª barrera VFS)&lt;/td>
&lt;td>&lt;code>runtimeClassName: kata&lt;/code> (microVM, kernel propio)&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Sin escape hatch&lt;/td>
&lt;td>proceso dentro de &lt;code>bwrap&lt;/code>, sin salida&lt;/td>
&lt;td>sin &lt;code>privileged&lt;/code>, &lt;code>drop ALL&lt;/code>, &lt;code>allowPrivilegeEscalation:false&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Daño al código&lt;/td>
&lt;td>git remoto sin &lt;code>push&lt;/code> → &lt;code>git checkout .&lt;/code>&lt;/td>
&lt;td>GitOps + revisión de PR, el agente no aplica a &lt;code>main&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Visibilidad&lt;/td>
&lt;td>&lt;code>--dry-run --verbose&lt;/code> (estático, pre-run)&lt;/td>
&lt;td>Tetragon &lt;code>tetra getevents&lt;/code> (dinámico, en runtime)&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h2 id="checklist-de-gotchas">Checklist de gotchas&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>No metas un &lt;code>Sigkill&lt;/code> sin pasar por &lt;code>Post&lt;/code>.&lt;/strong> El baseline de observación no es opcional: es lo que separa &amp;ldquo;bloquear un C2&amp;rdquo; de &amp;ldquo;tirar tu propio job de fine-tuning&amp;rdquo;.&lt;/li>
&lt;li>&lt;strong>El &lt;code>.ai-jail&lt;/code> se commitea; los secretos no.&lt;/strong> El TOML es política, no credenciales. Verifica que no metes rutas con datos sensibles en &lt;code>rw_maps&lt;/code>.&lt;/li>
&lt;li>&lt;strong>&lt;code>readOnlyRootFilesystem&lt;/code> rompe apps que escriben en &lt;code>/tmp&lt;/code>.&lt;/strong> Monta un &lt;code>emptyDir&lt;/code> en &lt;code>/tmp&lt;/code> además del de trabajo.&lt;/li>
&lt;li>&lt;strong>NetworkPolicy sin regla de DNS deja al pod ciego.&lt;/strong> Abre el puerto 53 a &lt;code>kube-system&lt;/code> o nada resuelve.&lt;/li>
&lt;li>&lt;strong>Kata no es gratis.&lt;/strong> Añade latencia de arranque y no todo workload con dispositivos especiales (GPU passthrough) encaja; resérvalo para lo no confiable, no para todo.&lt;/li>
&lt;li>&lt;strong>El &lt;code>/sandbox&lt;/code> de Claude Code no cubre MCP ni hooks&lt;/strong> salvo que actives &lt;code>sandbox-runtime&lt;/code>. Si tu agente usa servidores MCP, asume que corren con permisos completos hasta que lo hagas.&lt;/li>
&lt;li>&lt;strong>&lt;code>NotDAddr&lt;/code> con IPs literales envejece mal.&lt;/strong> Documenta la allowlist y revísala cuando cambie el registry o el endpoint de inferencia; considera CIDRs internos estables en vez de IPs sueltas.&lt;/li>
&lt;/ul>
&lt;h2 id="ver-también">Ver también&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://blog.lo0.es/posts/aislar-agentes-ia-cliente-cluster/">El contratista con la llave maestra: aislar agentes de IA del workstation al cluster&lt;/a> — el panorama que este runbook ejecuta: modelo de amenaza, las cinco familias de aislamiento y por qué cliente y cluster usan primitivas distintas.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/posts/cilium-ebpf-dranet-numa-de-red-inferencia/">La puerta de la cocina que el maître no miró: Cilium eBPF y DRANET&lt;/a> — la capa eBPF de Cilium sobre la que Tetragon engancha sus kprobes; el datapath que ya tienes en el cluster.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/posts/controles-tecnicos-ens-42001-eu-ai-act/">Controles técnicos: ENS × ISO 42001 × EU AI Act&lt;/a> — los eventos de Tetragon como evidencia técnica de &lt;code>op.mon&lt;/code>/&lt;code>op.exp&lt;/code>; el enforcement como medida de protección.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/posts/guardrails-safety-llm/">Guardrails y safety en LLM&lt;/a> — la mitigación en el plano del contenido; este runbook, la del plano de la ejecución.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/posts/siete-fases-despliegue-plataforma-llm-on-premise/">Siete fases de despliegue de una plataforma LLM on-premise&lt;/a> — dónde encaja el endurecimiento de runtime en la secuencia de despliegue (F4 identidad/políticas, F5 plataforma).&lt;/li>
&lt;/ul>
&lt;h2 id="referencias">Referencias&lt;/h2>
&lt;ul>
&lt;li>ai-jail (Fabio Akita), GPL-3.0: &lt;a href="https://github.com/akitaonrails/ai-jail">https://github.com/akitaonrails/ai-jail&lt;/a>&lt;/li>
&lt;li>bubblewrap: &lt;a href="https://github.com/containers/bubblewrap">https://github.com/containers/bubblewrap&lt;/a>&lt;/li>
&lt;li>Landlock LSM: &lt;a href="https://landlock.io">https://landlock.io&lt;/a>&lt;/li>
&lt;li>Tetragon — TracingPolicy: &lt;a href="https://tetragon.io/docs/concepts/tracing-policy/">https://tetragon.io/docs/concepts/tracing-policy/&lt;/a>&lt;/li>
&lt;li>Tetragon — enforcement (Sigkill/Override): &lt;a href="https://tetragon.io/docs/concepts/enforcement/">https://tetragon.io/docs/concepts/enforcement/&lt;/a>&lt;/li>
&lt;li>Kata Containers — Kubernetes RuntimeClass: &lt;a href="https://katacontainers.io">https://katacontainers.io&lt;/a>&lt;/li>
&lt;li>Kubernetes — Pod Security &amp;amp; seccomp: &lt;a href="https://kubernetes.io/docs/tutorials/security/seccomp/">https://kubernetes.io/docs/tutorials/security/seccomp/&lt;/a>&lt;/li>
&lt;li>Kubernetes — Network Policies: &lt;a href="https://kubernetes.io/docs/concepts/services-networking/network-policies/">https://kubernetes.io/docs/concepts/services-networking/network-policies/&lt;/a>&lt;/li>
&lt;li>Cilium: &lt;a href="https://cilium.io">https://cilium.io&lt;/a>&lt;/li>
&lt;/ul></description></item></channel></rss>