Hugo site now
Some checks failed
CI / test (push) Failing after 1m37s

This commit is contained in:
Miguel Jacq 2026-01-06 09:08:28 +11:00
parent 0ed180375e
commit 7f8e7f0c99
Signed by: mig5
GPG key ID: 59B3F0C24135C6A9
25 changed files with 261 additions and 530 deletions

110
src/content/security.html Normal file
View file

@ -0,0 +1,110 @@
---
title: "Security Design"
html_title: "Enroll Security"
description: "Security posture and safe workflows for Enroll outputs."
---
<header class="py-5 hero">
<div class="container py-3">
<div class="kicker mb-3"><i class="bi bi-shield-lock"></i> Security</div>
<h1 class="display-6 fw-bold mb-2">Safe by default. Powerful when you opt in.</h1>
<p class="lead mb-0">Enroll can touch sensitive files. This page helps you use it confidently.</p>
</div>
</header>
<main class="py-5">
<div class="container">
<div class="row g-4">
<div class="col-lg-8">
<div class="feature-card p-4">
<h2 class="h4 fw-bold mb-2">Default behavior</h2>
<p class="text-secondary mb-0">In normal mode, Enroll attempts to avoid harvesting likely secrets using a combination of path deny-lists, content sniffing, and size caps. This means you may see some files intentionally skipped.</p>
</div>
<div class="feature-card p-4 mt-4 border border-warning">
<div class="d-flex align-items-start gap-3">
<div class="icon-pill" style="background: rgba(255,193,7,0.20); border-color: rgba(255,193,7,0.45);"><i class="bi bi-exclamation-triangle"></i></div>
<div>
<h2 class="h4 fw-bold mb-2">The <code>--dangerous</code> flag</h2>
<p class="mb-2">This disables secret-safety checks. It can copy private keys, API tokens, DB passwords, TLS key material, etc.</p>
<p class="small text-secondary mb-0"><strong>Rule:</strong> if you use <code>--dangerous</code>, treat the output as sensitive data and plan secure storage before you run it. Don't store secrets in plaintext in a public place!</p>
</div>
</div>
</div>
<div class="feature-card p-4 mt-4">
<h2 class="h4 fw-bold mb-2">Encrypt bundles at rest with SOPS</h2>
<p class="text-secondary">You can install <a href="https://github.com/getsops/sops" target="_blank" rel="noopener noreferrer">SOPS</a> on your <code>$PATH</code>, then use <code>--sops</code> to write a single encrypted <code>.tar.gz.sops</code> file for harvests and/or manifests. This is meant for storage-at-rest and backups.</p>
<div class="codeblock terminal">
<button class="btn btn-sm btn-outline-secondary copy-btn" data-copy-target="#sec-sops"><i class="bi bi-clipboard"></i> Copy</button>
<pre class="mb-0"><code id="sec-sops"><span class="prompt">$</span> enroll harvest --out /tmp/enroll-harvest --dangerous --sops &lt;FINGERPRINT&gt;
<span class="prompt">$</span> enroll manifest --harvest /tmp/enroll-harvest/harvest.tar.gz.sops \
--out /tmp/enroll-ansible --sops &lt;FINGERPRINT&gt;</code></pre>
</div>
<div class="alert alert-secondary mt-3 mb-0">
<div class="fw-semibold">Important</div>
<div class="small mb-0">In manifest <code>--sops</code> mode, you'll need to decrypt and extract the bundle before running <code>ansible-playbook</code>.</div>
</div>
</div>
</div>
<div class="col-lg-4">
<div class="callout p-4">
<div class="fw-semibold mb-2">Recommended workflow</div>
<ol class="small mb-0">
<li>Start with default mode (no <code>--dangerous</code>).</li>
<li>Add <code>--include-path</code> for a small set of extra files you genuinely want managed.</li>
<li>If you must capture secrets, use <code>--dangerous</code> <strong>and</strong> <code>--sops</code>.</li>
<li>Keep outputs out of public repos; review before committing.</li>
<li>Rotate credentials if you ever suspect they were captured or exposed.</li>
</ol>
</div>
<div class="callout p-4 mt-3">
<div class="fw-semibold mb-2">Storage ideas</div>
<ul class="small mb-0">
<li>Encrypted SOPS bundle stored in a password manager vault</li>
<li>Private git repo with additional encryption at rest</li>
<li>Offline backup in an encrypted volume</li>
</ul>
</div>
<div class="callout p-4 mt-3">
<div class="fw-semibold mb-2">Scope control</div>
<p class="small text-secondary mb-3">You can explicitly include or exclude paths. Excludes take precedence over includes.</p>
<div class="terminal"><pre class="mb-0"><code><span class="prompt">$</span> enroll harvest \
--out /tmp/enroll-harvest \
--include-path '/home/*/.profile' \
--exclude-path '/home/*/.ssh/**'</code></pre></div>
</div>
</div>
</div>
<hr class="my-5">
<div class="feature-card p-4">
<h2 class="h4 fw-bold mb-2">Threat model</h2>
<div class="row g-3">
<div class="col-md-6">
<div class="fw-semibold">What Enroll tries to prevent</div>
<ul class="small mb-0">
<li>Accidentally copying obvious secrets in default mode</li>
<li>Harvesting huge/unbounded file sets by mistake</li>
<li>One host's difference causing problems for other hosts in terms of Ansible task steps (multi-site mode)</li>
</ul>
</div>
<div class="col-md-6">
<div class="fw-semibold">What you still need to think about</div>
<ul class="small mb-0">
<li>Where outputs are stored and who can access them</li>
<li>Reviewing what was captured before committing/sharing</li>
<li>Choosing encryption and secret-management strategy</li>
</ul>
</div>
</div>
</div>
</div>
</main>