<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Gpg on inetshell</title><link>https://inet.sh/es/tags/gpg/</link><description>Recent content in Gpg on inetshell</description><generator>Hugo</generator><language>es</language><lastBuildDate>Mon, 24 Aug 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://inet.sh/es/tags/gpg/index.xml" rel="self" type="application/rss+xml"/><item><title>Cifrar secretos con SOPS y GPG (PGP)</title><link>https://inet.sh/es/posts/sops/gpg/</link><pubDate>Mon, 24 Aug 2026 00:00:00 +0000</pubDate><guid>https://inet.sh/es/posts/sops/gpg/</guid><description>Cifra secretos en git con SOPS y una llave GPG/PGP: genera la llave, pon la fingerprint en .sops.yaml y cifra/descifra solo los valores.</description><content:encoded><![CDATA[<h2 id="en-corto">En corto</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">gpg --list-secret-keys --keyid-format<span class="o">=</span>long   <span class="c1"># obtén la fingerprint</span>
</span></span><span class="line"><span class="cl"><span class="c1"># .sops.yaml → creation_rules: pgp: &lt;FINGERPRINT&gt;</span>
</span></span><span class="line"><span class="cl">sops -e -i secrets.yaml                        <span class="c1"># cifra in-place</span>
</span></span><span class="line"><span class="cl">sops secrets.yaml                              <span class="c1"># edita descifrado, re-cifra al guardar</span>
</span></span><span class="line"><span class="cl">sops -d secrets.yaml                           <span class="c1"># descifra a stdout</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>SOPS cifra los <strong>valores</strong> de un archivo estructurado (YAML/JSON/env/ini) y deja las <strong>llaves</strong> legibles, así que un <code>secrets.enc.yaml</code> da un diff de git limpio y revisable. Para descifrar necesitas la llave <strong>privada</strong> de GPG en la máquina.</p>
<h2 id="requisitos">Requisitos</h2>
<p><code>gpg</code> y <code>sops</code> instalados. Verifica: <code>gpg --version</code> y <code>sops --version</code>.</p>
<h2 id="1-consigue-una-llave-gpg">1. Consigue una llave GPG</h2>
<p>Usa una existente o crea una:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">gpg --full-generate-key
</span></span><span class="line"><span class="cl">gpg --list-secret-keys --keyid-format<span class="o">=</span>long
</span></span></code></pre></td></tr></table>
</div>
</div><p>Copia la <strong>fingerprint</strong> de 40 caracteres (la línea larga en hex bajo <code>sec</code>). Esa fingerprint es la que referencia SOPS — no el key id corto.</p>
<h2 id="2-dile-a-sops-qué-llave-usar">2. Dile a SOPS qué llave usar</h2>
<p>Pon un <code>.sops.yaml</code> en la raíz del repo para no pasar llaves a mano:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">creation_rules</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">path_regex</span><span class="p">:</span><span class="w"> </span><span class="l">\.enc\.ya?ml$</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">pgp</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;FBC7B9E2A4F9289AC0C1D4843C1FCF3D&#34;</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li><code>path_regex</code> acota la regla a los archivos que nombres <code>*.enc.yaml</code>.</li>
<li><code>pgp</code> acepta una o varias fingerprints separadas por coma (varios destinatarios = cualquiera con una de esas llaves privadas puede descifrar).</li>
</ul>
<h2 id="3-cifra-edita-descifra">3. Cifra, edita, descifra</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">sops -e -i secrets.enc.yaml     <span class="c1"># cifra in-place (-i), solo valores</span>
</span></span><span class="line"><span class="cl">sops secrets.enc.yaml           <span class="c1"># abre $EDITOR descifrado; re-cifra al guardar</span>
</span></span><span class="line"><span class="cl">sops -d secrets.enc.yaml        <span class="c1"># descifra a stdout</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>Commitea el archivo cifrado. El texto plano nunca toca git.</p>
<h2 id="qué-toca-sops">Qué toca SOPS</h2>
<table>
  <thead>
      <tr>
          <th>Parte</th>
          <th>¿Cifrada?</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Valores (<code>password: hunter2</code>)</td>
          <td>sí</td>
      </tr>
      <tr>
          <td>Llaves / estructura (<code>password:</code>)</td>
          <td>no (diffs legibles)</td>
      </tr>
      <tr>
          <td>Bloque extra <code>sops:</code></td>
          <td>se agrega (destinatarios, MAC)</td>
      </tr>
  </tbody>
</table>
<h2 id="trampas">Trampas</h2>
<ul>
<li><strong>Subkeys:</strong> para forzar una subkey concreta de GnuPG, agrega <code>!</code> al final de la fingerprint en <code>creation_rules</code> (ej. <code>A3D6...E8F!</code>). Solo se respeta desde SOPS 3.9.3.</li>
<li><strong>Otro binario de gpg:</strong> define <code>SOPS_GPG_EXEC</code> para apuntar SOPS a un wrapper en vez del <code>gpg</code> por defecto.</li>
<li><strong>Respalda la llave privada.</strong> Si la pierdes, los archivos cifrados se van con ella — SOPS es tan recuperable como la llave GPG. Agrega un segundo destinatario (llave de respaldo/escrow) en <code>creation_rules</code> desde el día uno.</li>
<li><strong>Rotar destinatarios:</strong> tras editar <code>creation_rules</code>, corre <code>sops updatekeys secrets.enc.yaml</code> para re-cifrar la file key con el nuevo conjunto.</li>
<li>Solo los archivos estructurados reciben cifrado a nivel de valor; para un blob usa <code>sops -e --input-type binary</code>.</li>
</ul>
<h2 id="git-y-automatización">Git y automatización</h2>
<ul>
<li>Lo que vive en git es el archivo cifrado; quien revisa ve nombres de llaves, nunca valores.</li>
<li>En cualquier host/CI que deba descifrar, importa primero la llave <strong>privada</strong> al keyring de GPG (<code>gpg --import</code>) y luego <code>sops -d</code>.</li>
<li>Ansible puede consumir SOPS directo con la colección <code>community.sops</code> (ej. el lookup <code>community.sops.sops</code> / <code>load_vars</code>), así los playbooks leen secretos sin un descifrado manual. Verifica que la colección esté instalada en el nodo de control.</li>
</ul>
<h2 id="ver-también">Ver también</h2>
<ul>
<li>Docs de SOPS PGP / GnuPG: <a href="https://getsops.io/docs/usage/identities/pgp/">https://getsops.io/docs/usage/identities/pgp/</a></li>
</ul>
]]></content:encoded></item></channel></rss>