blog: 'The most secure credential is the one you never mount'
Least-privilege for Kubernetes workloads — own ServiceAccount + no auto-mounted API token, then non-root + dropped caps, then Pod Security as the enforced floor. Adds a matching house-style SVG diagram (workload-least-privilege).
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1120" height="400" viewBox="0 0 1120 400" role="img" aria-label="Workload least privilege: each pod gets its own ServiceAccount with no API token, runs non-root with capabilities dropped, inside a namespace with Pod Security enforced; the cluster API it never calls stays out of reach, and only a few scoped components keep a token">
|
||||
<rect width="1120" height="400" fill="#ffffff"></rect>
|
||||
|
||||
<!-- title -->
|
||||
<text x="60" y="44" font-family="ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, sans-serif" font-size="23" font-weight="700" fill="#0e1726">Service accounts all the way</text>
|
||||
<text x="61" y="68" font-family="ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, sans-serif" font-size="13.5" fill="#64748b">least privilege = identity → non-root → an enforced floor</text>
|
||||
|
||||
<!-- Kubernetes API -->
|
||||
<rect x="60" y="150" width="180" height="96" rx="14" fill="#f8fafc" stroke="#0e1726" stroke-width="1.6"></rect>
|
||||
<text x="150" y="192" text-anchor="middle" font-family="ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, sans-serif" font-size="15" font-weight="700" fill="#0e1726">Kubernetes API</text>
|
||||
<text x="150" y="214" text-anchor="middle" font-family="ui-monospace, 'SF Mono', Menlo, monospace" font-size="11" fill="#64748b">control plane</text>
|
||||
|
||||
<!-- broken link: API -> pod (token never mounted) -->
|
||||
<text x="336" y="180" text-anchor="middle" font-family="ui-monospace, 'SF Mono', Menlo, monospace" font-size="11.5" fill="#64748b">no API token mounted</text>
|
||||
<path d="M244 198 H424" fill="none" stroke="#64748b" stroke-width="2" stroke-dasharray="6 6" stroke-linecap="round"></path>
|
||||
<path d="M328 190 L344 206 M344 190 L328 206" fill="none" stroke="#0d9488" stroke-width="2.6" stroke-linecap="round"></path>
|
||||
|
||||
<!-- namespace boundary -->
|
||||
<rect x="430" y="92" width="630" height="252" rx="18" fill="#0d9488" fill-opacity="0.04" stroke="#0d9488" stroke-width="2.2" stroke-dasharray="7 6"></rect>
|
||||
<text x="452" y="121" font-family="ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, sans-serif" font-size="14" font-weight="700" fill="#0d9488">namespace</text>
|
||||
<rect x="792" y="104" width="246" height="30" rx="15" fill="#ffffff" stroke="#0d9488" stroke-width="1.4"></rect>
|
||||
<text x="915" y="124" text-anchor="middle" font-family="ui-monospace, 'SF Mono', Menlo, monospace" font-size="12" fill="#0d9488">PodSecurity: baseline → restricted</text>
|
||||
|
||||
<!-- workload pod -->
|
||||
<rect x="470" y="156" width="420" height="176" rx="14" fill="#ffffff" stroke="#3b6fb0" stroke-width="1.8"></rect>
|
||||
<text x="490" y="184" font-family="ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, sans-serif" font-size="14" font-weight="700" fill="#0e1726">workload pod</text>
|
||||
|
||||
<!-- badge 1 -->
|
||||
<rect x="490" y="196" width="380" height="26" rx="13" fill="#f1f5f9"></rect>
|
||||
<circle cx="507" cy="209" r="3.6" fill="#0d9488"></circle>
|
||||
<text x="522" y="213" font-family="ui-monospace, 'SF Mono', Menlo, monospace" font-size="12" fill="#0e1726">ServiceAccount: its own — not the default</text>
|
||||
<!-- badge 2 -->
|
||||
<rect x="490" y="228" width="380" height="26" rx="13" fill="#f1f5f9"></rect>
|
||||
<circle cx="507" cy="241" r="3.6" fill="#0d9488"></circle>
|
||||
<text x="522" y="245" font-family="ui-monospace, 'SF Mono', Menlo, monospace" font-size="12" fill="#0e1726">automountServiceAccountToken: false</text>
|
||||
<!-- badge 3 -->
|
||||
<rect x="490" y="260" width="380" height="26" rx="13" fill="#f1f5f9"></rect>
|
||||
<circle cx="507" cy="273" r="3.6" fill="#0d9488"></circle>
|
||||
<text x="522" y="277" font-family="ui-monospace, 'SF Mono', Menlo, monospace" font-size="12" fill="#0e1726">runAsNonRoot · uid 1000 · drop ALL caps</text>
|
||||
<!-- badge 4 -->
|
||||
<rect x="490" y="292" width="380" height="26" rx="13" fill="#f1f5f9"></rect>
|
||||
<circle cx="507" cy="305" r="3.6" fill="#0d9488"></circle>
|
||||
<text x="522" y="309" font-family="ui-monospace, 'SF Mono', Menlo, monospace" font-size="12" fill="#0e1726">seccompProfile: RuntimeDefault</text>
|
||||
|
||||
<!-- the exception: components that DO call the API -->
|
||||
<rect x="60" y="286" width="300" height="80" rx="12" fill="#ffffff" stroke="#2e8b57" stroke-width="1.6"></rect>
|
||||
<text x="78" y="309" font-family="ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, sans-serif" font-size="12.5" font-weight="700" fill="#2e8b57">the documented exception</text>
|
||||
<text x="78" y="330" font-family="ui-monospace, 'SF Mono', Menlo, monospace" font-size="10.5" fill="#64748b">GitOps · LoadBalancer · secrets operator</text>
|
||||
<text x="78" y="350" font-family="ui-monospace, 'SF Mono', Menlo, monospace" font-size="10.5" fill="#0e1726">→ scoped Role + token, nothing more</text>
|
||||
<path d="M150 286 V246" fill="none" stroke="#2e8b57" stroke-width="1.6" stroke-linecap="round"></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.8 KiB |
Reference in New Issue
Block a user