All checks were successful
Build and publish policy-nexus image / build-and-push (push) Successful in 1m10s
Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a058f3-8ba0-7692-a042-9a870fc3d663
320 lines
34 KiB
HTML
320 lines
34 KiB
HTML
<!doctype html>
|
||
<html lang="en"><meta charset="utf-8">
|
||
<meta name="policy-source-revision" content="9781102e2971d762ae42fdd5085a6647afd1cd66">
|
||
<meta name="policy-source-digest" content="32e71e9c0d6946bb14099eb66193822da26f199de0e11d8488464207f3bd9906">
|
||
<title>NetKingdom Security Zones v0.1</title>
|
||
<style>
|
||
:root{
|
||
--paper:#EDEEF0; --surface:#F6F7F8; --surface-2:#E4E6E9;
|
||
--ink:#171D24; --ink-2:#4A5561; --ink-3:#737E8A;
|
||
--rule:#D3D7DC; --rule-strong:#B6BCC3;
|
||
--brass:#8A6A2E; --brass-soft:#EFE5CD; --brass-line:#C9AE74;
|
||
--clay:#8A3A2C; --clay-soft:#F2DFDA;
|
||
--l0:#DCE0E2; --l1:#B9C4C7; --l2:#8CA1A6; --l3:#567D84; --l4:#23555E;
|
||
--chip-fg:#F6F7F8;
|
||
--font-display:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",sans-serif;
|
||
--font-body:"Iowan Old Style","Palatino Linotype",Palatino,Georgia,serif;
|
||
--font-mono:ui-monospace,"SF Mono","Cascadia Code",Menlo,Consolas,monospace;
|
||
--measure:66ch;
|
||
}
|
||
@media (prefers-color-scheme:dark){
|
||
:root:not([data-theme="light"]){
|
||
--paper:#12161A; --surface:#191E24; --surface-2:#222831;
|
||
--ink:#E6E9EC; --ink-2:#A3ADB7; --ink-3:#78838E;
|
||
--rule:#2A3138; --rule-strong:#3B444D;
|
||
--brass:#C9A45C; --brass-soft:#33290F; --brass-line:#6B5426;
|
||
--clay:#D08A76; --clay-soft:#3A211B;
|
||
--l0:#262C32; --l1:#35424A; --l2:#4A626B; --l3:#6A939D; --l4:#97C4CD;
|
||
--chip-fg:#12161A;
|
||
}
|
||
}
|
||
:root[data-theme="dark"]{
|
||
--paper:#12161A; --surface:#191E24; --surface-2:#222831;
|
||
--ink:#E6E9EC; --ink-2:#A3ADB7; --ink-3:#78838E;
|
||
--rule:#2A3138; --rule-strong:#3B444D;
|
||
--brass:#C9A45C; --brass-soft:#33290F; --brass-line:#6B5426;
|
||
--clay:#D08A76; --clay-soft:#3A211B;
|
||
--l0:#262C32; --l1:#35424A; --l2:#4A626B; --l3:#6A939D; --l4:#97C4CD;
|
||
--chip-fg:#12161A;
|
||
}
|
||
|
||
*{box-sizing:border-box}
|
||
body{
|
||
margin:0; background:var(--paper); color:var(--ink);
|
||
font-family:var(--font-body); font-size:17px; line-height:1.62;
|
||
-webkit-font-smoothing:antialiased;
|
||
}
|
||
.wrap{max-width:1180px;margin:0 auto;padding:0 24px 96px}
|
||
.layout{display:grid;grid-template-columns:180px minmax(0,1fr);gap:56px;align-items:start}
|
||
@media (max-width:960px){.layout{grid-template-columns:1fr;gap:0}.rail{display:none}}
|
||
|
||
/* ---------- rail ---------- */
|
||
.rail{position:sticky;top:28px;padding-top:8px;font-family:var(--font-display);font-size:12px;line-height:1.5}
|
||
.rail ol{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:7px}
|
||
.rail a{color:var(--ink-3);text-decoration:none;display:flex;gap:9px}
|
||
.rail a:hover,.rail a:focus-visible{color:var(--brass)}
|
||
.rail .n{font-family:var(--font-mono);font-size:10px;color:var(--rule-strong);min-width:16px;padding-top:1px}
|
||
.rail .grp{margin-top:14px;font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--rule-strong)}
|
||
|
||
/* ---------- header ---------- */
|
||
header{padding:64px 0 40px;border-bottom:2px solid var(--ink);margin-bottom:44px}
|
||
.eyebrow{font-family:var(--font-mono);font-size:11.5px;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-3);display:flex;flex-wrap:wrap;gap:14px;margin-bottom:22px}
|
||
.eyebrow .stat{color:var(--clay)}
|
||
h1{font-family:var(--font-display);font-weight:800;letter-spacing:-.035em;line-height:.94;font-size:clamp(46px,9vw,92px);margin:0 0 6px;text-wrap:balance}
|
||
.sub{font-family:var(--font-display);font-weight:500;font-size:clamp(16px,2.4vw,21px);letter-spacing:-.01em;color:var(--ink-2);margin:0 0 30px;max-width:34ch;line-height:1.3}
|
||
.metagrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:20px 28px;border-top:1px solid var(--rule);padding-top:20px}
|
||
.metagrid dt{font-family:var(--font-mono);font-size:10px;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-3);margin-bottom:5px}
|
||
.metagrid dd{margin:0;font-family:var(--font-display);font-size:13.5px;line-height:1.45;color:var(--ink)}
|
||
|
||
/* ---------- typography ---------- */
|
||
section{margin-bottom:60px;scroll-margin-top:24px}
|
||
h2{font-family:var(--font-display);font-weight:750;letter-spacing:-.022em;font-size:clamp(24px,3.4vw,31px);line-height:1.12;margin:0 0 18px;text-wrap:balance;display:flex;gap:14px;align-items:baseline}
|
||
h2 .sn{font-family:var(--font-mono);font-size:12px;font-weight:400;color:var(--brass);letter-spacing:.06em;flex:none;padding-top:2px}
|
||
h3{font-family:var(--font-display);font-weight:700;font-size:16px;letter-spacing:-.008em;margin:34px 0 10px;color:var(--ink)}
|
||
p{margin:0 0 15px;max-width:var(--measure)}
|
||
ul,ol{max-width:var(--measure);margin:0 0 15px;padding-left:20px}
|
||
li{margin-bottom:7px}
|
||
strong{font-weight:600}
|
||
em{font-style:italic}
|
||
code{font-family:var(--font-mono);font-size:.855em;background:var(--surface-2);padding:1px 5px;border-radius:2px}
|
||
a{color:var(--brass)}
|
||
.lede{font-size:19px;line-height:1.55;color:var(--ink-2);max-width:60ch}
|
||
|
||
/* ---------- devices ---------- */
|
||
.callout{border-left:3px solid var(--brass);background:var(--brass-soft);padding:18px 22px;margin:0 0 24px;max-width:var(--measure)}
|
||
.callout p:last-child{margin-bottom:0}
|
||
.callout .lbl{font-family:var(--font-mono);font-size:10px;letter-spacing:.13em;text-transform:uppercase;color:var(--brass);display:block;margin-bottom:8px}
|
||
.rule-quote{border-top:2px solid var(--ink);border-bottom:2px solid var(--ink);padding:26px 0;margin:28px 0;max-width:var(--measure)}
|
||
.rule-quote p{font-family:var(--font-display);font-weight:600;font-size:19px;line-height:1.38;letter-spacing:-.014em;margin:0;text-wrap:balance}
|
||
.hard{border-left:3px solid var(--clay);background:var(--clay-soft);padding:18px 22px;margin:0 0 24px;max-width:var(--measure)}
|
||
.hard .lbl{font-family:var(--font-mono);font-size:10px;letter-spacing:.13em;text-transform:uppercase;color:var(--clay);display:block;margin-bottom:8px}
|
||
.hard p:last-child{margin-bottom:0}
|
||
.dec{font-family:var(--font-mono);font-size:10.5px;letter-spacing:.08em;color:var(--brass);text-transform:uppercase}
|
||
.vec{font-family:var(--font-mono);font-size:.9em;font-weight:600;background:var(--surface-2);padding:2px 7px;border-radius:2px;white-space:nowrap;letter-spacing:.04em}
|
||
|
||
/* ---------- tables ---------- */
|
||
.scroll{overflow-x:auto;margin:0 0 24px;-webkit-overflow-scrolling:touch}
|
||
table{border-collapse:collapse;width:100%;min-width:520px;font-family:var(--font-display);font-size:13.5px;line-height:1.45}
|
||
th{text-align:left;font-family:var(--font-mono);font-size:9.5px;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-3);font-weight:400;padding:0 16px 8px 0;border-bottom:1px solid var(--rule-strong);vertical-align:bottom}
|
||
td{padding:11px 16px 11px 0;border-bottom:1px solid var(--rule);vertical-align:top;color:var(--ink-2)}
|
||
td:first-child{color:var(--ink);font-weight:600}
|
||
tbody tr:last-child td{border-bottom:none}
|
||
.lvl{font-family:var(--font-mono);font-weight:600;font-size:12px;letter-spacing:.04em;color:var(--ink)}
|
||
|
||
/* ---------- ladders ---------- */
|
||
.breakout{margin:34px 0 40px}
|
||
.bhead{display:flex;justify-content:space-between;align-items:baseline;gap:20px;border-bottom:1px solid var(--rule-strong);padding-bottom:9px;margin-bottom:22px;flex-wrap:wrap}
|
||
.bhead h3{margin:0;font-size:13px;letter-spacing:.1em;text-transform:uppercase;font-family:var(--font-mono);font-weight:400;color:var(--ink-3)}
|
||
.bhead .note{font-family:var(--font-display);font-size:12.5px;color:var(--ink-3)}
|
||
.ladders{display:grid;gap:26px}
|
||
.ladder{display:grid;grid-template-columns:126px minmax(0,1fr);gap:18px;align-items:start}
|
||
@media (max-width:700px){.ladder{grid-template-columns:1fr;gap:10px}}
|
||
.ladder .pname{font-family:var(--font-display);font-weight:700;font-size:14px;letter-spacing:-.01em;padding-top:2px}
|
||
.ladder .pname span{display:block;font-family:var(--font-mono);font-size:10px;font-weight:400;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3);margin-top:3px}
|
||
.rungs{display:grid;gap:3px;grid-template-columns:repeat(5,minmax(0,1fr))}
|
||
@media (max-width:700px){.rungs{grid-template-columns:repeat(2,minmax(0,1fr))}}
|
||
.rung{padding:9px 10px 11px;background:var(--surface);border-top:4px solid var(--l0);min-width:0}
|
||
.rung.r1{border-top-color:var(--l1)} .rung.r2{border-top-color:var(--l2)}
|
||
.rung.r3{border-top-color:var(--l3)} .rung.r4{border-top-color:var(--l4)}
|
||
.rung .code{font-family:var(--font-mono);font-size:11px;font-weight:600;letter-spacing:.06em;color:var(--ink);display:block;margin-bottom:4px}
|
||
.rung .txt{font-family:var(--font-display);font-size:11.5px;line-height:1.34;color:var(--ink-2);display:block}
|
||
.rung.na{opacity:.42}
|
||
|
||
/* ---------- matrix ---------- */
|
||
.matrix-shell{display:grid;grid-template-columns:auto minmax(0,1fr);gap:12px;align-items:stretch;margin-bottom:14px}
|
||
.ylab{writing-mode:vertical-rl;transform:rotate(180deg);font-family:var(--font-mono);font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3);text-align:center;padding-bottom:22px}
|
||
.mgrid{display:grid;grid-template-columns:34px repeat(5,minmax(0,1fr));gap:3px}
|
||
.mcell{background:var(--surface);min-height:60px;padding:6px;display:flex;flex-direction:column;justify-content:flex-end;gap:4px;min-width:0}
|
||
.mcell.tint1{background:color-mix(in srgb,var(--l1) 26%,var(--surface))}
|
||
.mcell.tint2{background:color-mix(in srgb,var(--l2) 26%,var(--surface))}
|
||
.mcell.tint3{background:color-mix(in srgb,var(--l3) 24%,var(--surface))}
|
||
.mcell.tint4{background:color-mix(in srgb,var(--l4) 22%,var(--surface))}
|
||
.mcell.void{background:repeating-linear-gradient(135deg,transparent,transparent 5px,var(--rule) 5px,var(--rule) 6px);opacity:.55}
|
||
.rlab,.clab{font-family:var(--font-mono);font-size:10px;font-weight:600;letter-spacing:.05em;color:var(--ink-3);display:flex;align-items:center;justify-content:center}
|
||
.rlab{min-height:60px}
|
||
.clab{padding-top:7px;min-height:22px}
|
||
.pin{font-family:var(--font-mono);font-size:9.5px;font-weight:600;letter-spacing:.02em;background:var(--ink);color:var(--paper);padding:2px 5px;border-radius:2px;line-height:1.3;display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
||
.pin.ghost{background:transparent;color:var(--ink-2);border:1px dashed var(--rule-strong)}
|
||
.mnote{display:flex;gap:22px;flex-wrap:wrap;font-family:var(--font-display);font-size:12px;color:var(--ink-3);padding-top:6px}
|
||
.mnote .k{display:flex;align-items:center;gap:7px}
|
||
.sw{width:13px;height:13px;flex:none;background:var(--ink)}
|
||
.sw.g{background:transparent;border:1px dashed var(--rule-strong)}
|
||
.sw.v{background:repeating-linear-gradient(135deg,transparent,transparent 4px,var(--rule) 4px,var(--rule) 5px);border:1px solid var(--rule)}
|
||
@media (max-width:640px){
|
||
.mgrid{grid-template-columns:28px repeat(5,minmax(0,1fr))}
|
||
.mcell{min-height:52px;padding:4px}
|
||
.pin{font-size:8px;padding:1px 3px}
|
||
.rlab{min-height:52px}
|
||
}
|
||
|
||
/* ---------- methodology ---------- */
|
||
.verbs{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:2px;background:var(--rule);border:1px solid var(--rule)}
|
||
.verb{background:var(--surface);padding:18px 18px 20px}
|
||
.verb h4{font-family:var(--font-display);font-weight:750;font-size:15px;margin:0 0 7px;letter-spacing:-.01em}
|
||
.verb p{font-family:var(--font-display);font-size:12.5px;line-height:1.46;color:var(--ink-2);margin:0;max-width:none}
|
||
.verb .step{font-family:var(--font-mono);font-size:9.5px;letter-spacing:.13em;color:var(--brass);display:block;margin-bottom:9px}
|
||
|
||
/* ---------- questions ---------- */
|
||
.qs{display:flex;flex-direction:column;gap:0;border-top:1px solid var(--rule-strong)}
|
||
.q{display:grid;grid-template-columns:34px minmax(0,1fr) 170px;gap:18px;padding:16px 0;border-bottom:1px solid var(--rule);align-items:start}
|
||
@media (max-width:760px){.q{grid-template-columns:28px minmax(0,1fr);gap:12px}.q .owner{grid-column:2}}
|
||
.q .qn{font-family:var(--font-mono);font-size:11px;color:var(--brass);padding-top:3px}
|
||
.q .qt{font-family:var(--font-display);font-size:14px;line-height:1.48;color:var(--ink-2)}
|
||
.q .qt b{color:var(--ink);font-weight:700;display:block;margin-bottom:2px;font-size:14.5px}
|
||
.owner{font-family:var(--font-mono);font-size:10px;letter-spacing:.05em;color:var(--ink-3);padding-top:4px}
|
||
.owner .tag{display:inline-block;border:1px solid var(--rule-strong);padding:2px 7px;border-radius:2px}
|
||
.owner .tag.need{border-color:var(--clay);color:var(--clay)}
|
||
|
||
/* ---------- misc ---------- */
|
||
.numbers{font-family:var(--font-mono);font-size:12.5px;line-height:1.85;background:var(--surface);border-left:3px solid var(--l3);padding:16px 20px;margin:0 0 22px;overflow-x:auto;max-width:var(--measure)}
|
||
.numbers .v{color:var(--ink);font-weight:600}
|
||
.numbers .k{color:var(--ink-3)}
|
||
pre{font-family:var(--font-mono);font-size:12.5px;line-height:1.68;background:var(--surface);border-left:3px solid var(--rule-strong);padding:16px 20px;overflow-x:auto;margin:0 0 22px;max-width:var(--measure);color:var(--ink-2)}
|
||
.alt{border-bottom:1px solid var(--rule);padding:14px 0;max-width:var(--measure)}
|
||
.alt:last-of-type{border-bottom:none}
|
||
.alt b{font-family:var(--font-display);font-size:14px;display:block;margin-bottom:3px}
|
||
.alt p{font-size:14.5px;margin:0;color:var(--ink-2)}
|
||
.alt .verdict{font-family:var(--font-mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--clay)}
|
||
footer{border-top:2px solid var(--ink);margin-top:20px;padding-top:22px;font-family:var(--font-mono);font-size:11px;letter-spacing:.06em;color:var(--ink-3);display:flex;justify-content:space-between;gap:20px;flex-wrap:wrap}
|
||
.tm td,.tm th{text-align:center}
|
||
.tm td:first-child,.tm th:first-child{text-align:left}
|
||
.yes{color:var(--l4);font-weight:700}
|
||
.no{color:var(--clay);font-weight:700}
|
||
.kind{font-family:var(--font-mono);font-size:9px;letter-spacing:.09em;text-transform:uppercase;padding:2px 6px;border-radius:2px;white-space:nowrap;border:1px solid var(--rule-strong);color:var(--ink-3)}
|
||
.kind.adv{border-color:var(--clay);color:var(--clay)}
|
||
.routes{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:2px;background:var(--rule);border:1px solid var(--rule);margin:0 0 22px}
|
||
.route{background:var(--surface);padding:16px 18px}
|
||
.route h4{font-family:var(--font-display);font-weight:750;font-size:14px;margin:0 0 6px}
|
||
.route p{font-family:var(--font-display);font-size:12.5px;line-height:1.45;color:var(--ink-2);margin:0;max-width:none}
|
||
.route .tag{font-family:var(--font-mono);font-size:9px;letter-spacing:.1em;text-transform:uppercase;color:var(--brass);display:block;margin-bottom:8px}
|
||
a:focus-visible,.rail a:focus-visible{outline:2px solid var(--brass);outline-offset:3px}
|
||
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
|
||
|
||
</style>
|
||
<div class="wrap"><header><div class="eyebrow"><span>netkingdom-security-zones-v0.1</span> <span class="stat">proposed</span> <span>zone-engine</span> <span>reviewed 2026-08-22</span><span>generated from canonical source — do not edit</span></div><h1>NetKingdom Security Zones v0.1</h1><p class="sub">Source: <code>net-kingdom · canon/standards/security-zones_v0.1.md · 9781102e2971d762ae42fdd5085a6647afd1cd66</code></p><p class="sub">Review due: 2026-11-22</p></header><div class="layout"><nav class="rail" aria-label="Sections"><ol><li><a href="#s1"><span class="n">1</span>Purpose</a></li><li><a href="#s2"><span class="n">2</span>Authority and conformance</a></li><li><a href="#s3"><span class="n">3</span>Resolution is authoritative</a></li><li><a href="#s4"><span class="n">4</span>Zone catalog</a></li><li><a href="#s5"><span class="n">5</span>Stance and failure-mode model</a></li><li><a href="#s6"><span class="n">6</span>Declaration in `tenancy.yaml`</a></li><li><a href="#s7"><span class="n">7</span>Compilation and resolved view</a></li><li><a href="#s8"><span class="n">8</span>Membership-change observability</a></li><li><a href="#s9"><span class="n">9</span>Time-boxed exceptions</a></li><li><a href="#s10"><span class="n">10</span>Adoption</a></li></ol></nav><main><section id="s1"><h2><span class="sn">01</span>Purpose</h2>
|
||
<p>A security zone is a named workload-admission standard. It answers which scrutiny a workload has qualified for; control-owner policy then answers what a particular control does in that zone. A zone is not a repository label, a credential lane, a network segment, a reef, or a temporary exception.</p>
|
||
<p>This standard is a sibling of <code>tenancy-posture_v0.1</code>. It owns zone identity, membership, admission, resolution, and the time-boxed exception lifecycle. <code>flex-auth</code> remains the only PDP for decisions it renders. Every other control continues to be owned and evaluated at its existing enforcement point.</p>
|
||
</section>
|
||
<section id="s2"><h2><span class="sn">02</span>Authority and conformance</h2>
|
||
<p>Authority is split deliberately:</p>
|
||
<div class="scroll"><table><thead><tr><th>Fact or rule</th><th>Authority</th></tr></thead><tbody><tr><td>Workload identity and requested membership</td><td>Workload's responsible repo</td></tr><tr><td>Zone identities and admission standards</td><td>This standard, owned by zone-engine</td></tr><tr><td>Per-zone stance</td><td>Owner of the control that renders the effect</td></tr><tr><td>Failure behavior when a dependency is unavailable</td><td>Owner of the PEP</td></tr><tr><td>Publication</td><td>net-kingdom canon</td></tr></tbody></table></div>
|
||
<p>Conformance is <strong>accuracy, not altitude</strong>. A lower zone declared with evidence is conformant. A stricter zone that the workload cannot evidence is not. Changing membership to evade a control is not an exception mechanism.</p>
|
||
<p>The workload is the sole <strong>zone</strong> policy subject. It includes independently governed application, automation, maintenance, and operational/control-plane execution units. The workload executing a tunnel, credential broker, policy service, or maintenance operation requires identity; the tunnel, grant, lane, pattern, action, human, or agent does not become a workload merely because a control observes it. Those retain native typed identity and caller/resource context.</p>
|
||
</section>
|
||
<section id="s3"><h2><span class="sn">03</span>Resolution is authoritative</h2>
|
||
<p>The stable <code>workload_identity.name</code> is the join key. Runtime principals, resources, credential lanes, and controls reference it explicitly. A resolver MUST NOT infer membership from repository ownership, paths, lane types, actor classes, environment, criticality, reefs, organization posture, or naming conventions.</p>
|
||
<p>For a managed deployable, the authoritative cross-repository reference is the Repo Manager v1 tuple <code>(rapp_id, workload_identity.name)</code>, optionally narrowed by <code>deployable</code>. A catalog also declares whether its subject is workload applicable. Resolution returns both the reference result and admission result:</p>
|
||
<ul><li><code>satisfied</code> — the workload has an authoritative identity and evidence meeting the declared zone's floor; <code>effective_zone</code> is the declared zone;</li><li><code>unsatisfied</code> — identity and membership are declared, but evidence is below the admission floor; <code>effective_zone</code> is <code>unknown</code>;</li><li><code>unknown</code> — identity, membership, or a required floor/evidence input cannot be resolved for a workload-applicable subject; <code>effective_zone</code> is <code>unknown</code>;</li><li><code>not-applicable</code> — the owning catalog explicitly establishes that the subject is an action, actor, lane, pattern, or resource rather than a workload; no zone is resolved and the control uses that subject's native identity.</li></ul>
|
||
<p><code>unknown</code> is a result, not a zone. A control MUST declare an explicit treatment for it. That treatment may deny, escalate, or use a reviewed build-stage rule; it never manufactures membership and never grants an exception.</p>
|
||
</section>
|
||
<section id="s4"><h2><span class="sn">04</span>Zone catalog</h2>
|
||
<p>The initial catalog follows the estate's existing <code>M0</code>–<code>M3</code> maturity ladder and adds one non-monotone continuity band required by ops-warden <code>ADR-0006</code>.</p>
|
||
<div class="scroll"><table><thead><tr><th>Zone id</th><th>Admission floor</th><th>Environment/data boundary</th><th>Purpose</th></tr></thead><tbody><tr><td><code>z0-experimental</code></td><td><code>M0</code> promotion evidence</td><td>Synthetic only; no real credential or user data</td><td>Experiments where advisory controls preserve iteration speed</td></tr><tr><td><code>z1-operational</code></td><td><code>M1</code> promotion evidence</td><td>Production secret handling for at most <code>internal</code> data</td><td>Early operational workloads with an owned front door</td></tr><tr><td><code>z2-protected</code></td><td><code>M2</code> promotion evidence</td><td><code>prod</code>; at most <code>confidential</code> data</td><td>Production workloads requiring review, SLO/on-call, and incident readiness</td></tr><tr><td><code>z3-critical</code></td><td><code>M3</code> promotion evidence</td><td><code>prod</code>; at most <code>restricted</code> data</td><td>Critical or regulated workloads with the strongest normal failure behavior</td></tr><tr><td><code>z2-continuity</code></td><td><code>M2</code> plus dependency/recovery evidence</td><td><code>prod</code>; at most <code>confidential</code> data</td><td>Foundational access or recovery workloads where fail-closed dependency cycles would cause an outage</td></tr></tbody></table></div>
|
||
<p><code>z2-continuity</code> is a sibling of <code>z2-protected</code>, not a relaxation of its admission floor. It exists because enforcement stance is not monotone: a tunnel or credential-issuance path can require production scrutiny while deliberately remaining fail-open for one availability-sensitive control. Placement on a reef is never evidence for any zone.</p>
|
||
<h3>4.1 Context floor</h3>
|
||
<p>The declared zone must be at least as strict as the workload context requires. The context floor is the maximum of every resolved input:</p>
|
||
<div class="scroll"><table><thead><tr><th><code>criticality</code></th><th>Minimum maturity</th></tr></thead><tbody><tr><td><code>low</code></td><td><code>M0</code></td></tr><tr><td><code>medium</code></td><td><code>M1</code></td></tr><tr><td><code>high</code></td><td><code>M2</code></td></tr><tr><td><code>critical</code></td><td><code>M3</code></td></tr></tbody></table></div>
|
||
<p>Data-class floors are consumed from the canon-owned classification mapping; the current <code>synthetic → M0</code>, <code>internal → M1</code>, <code>confidential → M2</code>, and <code>restricted → M3</code> mapping is already used by ops-warden. An absent or unresolved floor makes admission <code>unknown</code>. In particular, <code>public</code> is disclosure policy and <code>synthetic</code> is data origin: they are not aliases, and this standard does not invent a floor while info-tech-canon's ruling is pending.</p>
|
||
<p><code>organization_posture</code> may select a versioned control profile, but it never changes identity, membership, or admission.</p>
|
||
</section>
|
||
<section id="s5"><h2><span class="sn">05</span>Stance and failure-mode model</h2>
|
||
<p>Every owner-qualified control publishes a total mapping over all zone ids plus <code>unknown</code>. There is no implicit default.</p>
|
||
<ul><li><code>enforced</code> — the control's deny or escalation effect changes the outcome;</li><li><code>advisory</code> — the control evaluates fully and records the outcome it would have produced, but does not block;</li><li><code>exempt</code> — the control is deliberately not evaluated for this zone and emits the versioned exemption reason.</li></ul>
|
||
<p>Failure mode is separate and PEP-side:</p>
|
||
<ul><li><code>fail_closed</code> — an unavailable or invalid evaluator produces the control's safe blocking/escalation outcome;</li><li><code>fail_open</code> — the PEP proceeds and records that the control was unavailable.</li></ul>
|
||
<p><code>exempt</code> has no failure mode. A local control with no remote dependency uses <code>fail_closed</code> to describe evaluator errors. Changing stance is a policy-package change owned by the control owner, not a membership change.</p>
|
||
<h3>5.1 Initial build-stage control profile</h3>
|
||
<p>This profile is the v0.1 proposal for the first consumer. It is not stored in a workload's <code>zones:</code> declaration. flex-auth owns the pre-sign rows; ops-warden owns the other rows and every PEP failure mode.</p>
|
||
<div class="scroll"><table><thead><tr><th>Zone</th><th>flex-auth pre-sign stance / ops-warden PEP</th><th>agent high-risk read boundary</th><th><code>warden plan</code> zone rule</th></tr></thead><tbody><tr><td><code>z0-experimental</code></td><td><code>advisory</code> / <code>fail_open</code></td><td><code>enforced</code> / <code>fail_closed</code></td><td><code>advisory</code>; evaluator failure cannot produce <code>autonomous</code></td></tr><tr><td><code>z1-operational</code></td><td><code>advisory</code> / <code>fail_open</code></td><td><code>enforced</code> / <code>fail_closed</code></td><td><code>advisory</code>; evaluator failure cannot produce <code>autonomous</code></td></tr><tr><td><code>z2-protected</code></td><td><code>enforced</code> / <code>fail_open</code></td><td><code>enforced</code> / <code>fail_closed</code></td><td><code>enforced</code>; minimum <code>founder_required</code> when the zone rule matches</td></tr><tr><td><code>z3-critical</code></td><td><code>enforced</code> / <code>fail_closed</code></td><td><code>enforced</code> / <code>fail_closed</code></td><td><code>enforced</code>; minimum <code>founder_required</code> when the zone rule matches</td></tr><tr><td><code>z2-continuity</code></td><td><code>enforced</code> / <code>fail_open</code></td><td><code>enforced</code> / <code>fail_closed</code></td><td><code>enforced</code>; minimum <code>founder_required</code> when the zone rule matches</td></tr><tr><td><code>unknown</code></td><td><code>advisory</code> / <code>fail_open</code> under the versioned <code>build</code> profile</td><td><code>enforced</code> / <code>fail_closed</code></td><td><code>enforced</code>; never <code>autonomous</code> from zone evidence</td></tr></tbody></table></div>
|
||
<p>The <code>unknown</code> pre-sign treatment is an explicit organization-build policy, not a permissive membership default. It must change through a versioned control profile when the organization posture graduates.</p>
|
||
<p>The agent read boundary stays enforced in every zone: build-stage permissiveness does not extend to disclosing high-risk credentials. For a missing lane risk:</p>
|
||
<ul><li><code>z0-experimental</code> may resolve to <code>standard</code> only when admission proves the lane can expose synthetic material exclusively;</li><li><code>z1-operational</code> and <code>z2-protected</code> resolve to at least <code>high</code>;</li><li><code>z3-critical</code> resolves to <code>critical</code>, treated by the boundary as at least <code>high</code>; and</li><li>unresolved membership resolves to at least <code>high</code>.</li></ul>
|
||
<p>An explicit grade always remains preferable. <code>accepted</code> is an acceptance record, not a risk grade.</p>
|
||
</section>
|
||
<section id="s6"><h2><span class="sn">06</span>Declaration in <code>tenancy.yaml</code></h2>
|
||
<p>For a single-service declaration, <code>zones:</code> is a sibling of <code>tenancy:</code> and <code>workload_identity</code>. For a <code>services:</code> declaration, both <code>workload_identity</code> and <code>zones</code> occur inside the same service entry. A multi-service file MUST NOT use a top-level <code>zones:</code> block.</p>
|
||
<p>Every managed running deployable has an authoritative <code>rapp-*/declarations/rapp.yaml</code>. Its <code>workload_identity.declaration_ref</code> points to that declaration, and consuming catalogs reference it using the Repo Manager v1 tuple. A pre-rapp deployable is migration debt and resolves <code>unknown</code>. An independently governed operational execution unit that is not a managed deployable may declare directly in its responsible repo's <code>tenancy.yaml</code>; this does not turn a human action or infrastructure resource into a fictional rapp or workload.</p>
|
||
<pre>schema_version: "0.1"
|
||
framework: netkingdom-tenancy-posture
|
||
service: ops-bridge-tunnel
|
||
role: operational-access-path
|
||
workload_identity:
|
||
name: ops-bridge-tunnel
|
||
kind: operational-control-plane
|
||
responsible_repo: ops-bridge
|
||
identity_bindings:
|
||
- scheme: ssh-certificate
|
||
authority: ops-warden
|
||
subject: agt-ops-bridge
|
||
principal_type: agent
|
||
environment: prod
|
||
tenancy:
|
||
# tenancy-posture_v0.1 content omitted
|
||
zones:
|
||
standard: security-zones_v0.1
|
||
membership: z2-continuity
|
||
responsible_party: ops-bridge
|
||
justification: foundational tunnel path must retain availability under PDP loss
|
||
context:
|
||
maturity: M2
|
||
criticality: high
|
||
data_classification: confidential
|
||
evidence:
|
||
- ref: docs/evidence/ops-bridge-tunnel-zone.md
|
||
supports: [M2, continuity-dependency, recovery]
|
||
reviewed: "2026-08-22"
|
||
review_due: "2026-11-22"</pre>
|
||
<p>The <code>zones:</code> block contains only membership evidence. It MUST NOT contain control stance, failure mode, organization posture, or exceptions.</p>
|
||
<p>Required fields are:</p>
|
||
<ul><li><code>standard</code> — exactly <code>security-zones_v0.1</code>;</li><li><code>membership</code> — one zone id from §4;</li><li><code>responsible_party</code> — the party answering for this membership;</li><li><code>justification</code> — why the zone fits the workload's actual context;</li><li><code>context</code> — the evidenced <code>maturity</code>, <code>criticality</code>, and <code>data_classification</code> used for admission. A managed workload's latter two values must agree with its resolved rapp projection; <code>n/a</code> requires an evidence-backed reason;</li><li><code>evidence</code> — one or more references and the admission facts each supports;</li><li><code>reviewed</code> and <code>review_due</code> — ISO dates, with review due after review.</li></ul>
|
||
<p>Permanent membership changes are reviewed source changes. A change to a lower floor also records its reason and approver in the change review. Temporary relaxation uses an exception and never changes <code>membership</code>.</p>
|
||
</section>
|
||
<section id="s7"><h2><span class="sn">07</span>Compilation and resolved view</h2>
|
||
<p>Compilation produces a workload-addressable resolved record. At minimum it contains:</p>
|
||
<pre>workload_id: ops-bridge-tunnel
|
||
workload_ref:
|
||
applicability: applicable
|
||
rapp_id: null # required for a managed deployable
|
||
name: ops-bridge-tunnel
|
||
deployable: null # optional for a managed deployable
|
||
identity_binding: ssh-certificate/ops-warden/agt-ops-bridge
|
||
declared_zone: z2-continuity
|
||
admission: satisfied
|
||
effective_zone: z2-continuity
|
||
membership_revision: sha256:<digest>
|
||
guarantees:
|
||
- authoritative-workload-identity
|
||
- explicit-zone-membership
|
||
- non-inferred-resolution
|
||
- enforcement-time-exception-expiry
|
||
controls:
|
||
- id: flex-auth/pre-sign
|
||
policy_owner: flex-auth
|
||
stance: enforced
|
||
pep_owner: ops-warden
|
||
failure_mode: fail_open
|
||
policy_ref: <versioned-package></pre>
|
||
<p>The <code>membership_revision</code> covers the authoritative workload binding, <code>zones:</code> block, and source revision. Control results include their policy/profile version and any active exception id and expiry. This is the machine-readable answer to “which zone is this workload in, and what applies there?” It may be compiled into existing consumer artifacts; it is not a synchronous zone-engine lookup.</p>
|
||
<p>For managed deployables, compilation consumes the exact Repo Manager reference projection:</p>
|
||
<pre>workload_ref:
|
||
applicability: applicable
|
||
rapp_id: rapp-issue-core
|
||
name: issue-core
|
||
deployable: issue-core # optional</pre>
|
||
<p>The owning catalog uses <code>applicability: not-applicable</code> for a native non-workload subject. Absence of either applicability or an expected reference is <code>unknown</code>, not <code>not-applicable</code>. Zone-engine consumes these outcomes; it does not parse a path or repository name to repair them.</p>
|
||
<p>For flex-auth's pre-sign control, the governed workload is the target of the certificate or grant, so the compiler writes <code>workload_id</code>, <code>security_zone</code>, <code>security_zone_admission</code>, and <code>security_zone_revision</code> on the resource attributes. Caller identity remains in the subject. A control that governs the requesting workload must declare that role explicitly and use separately named caller-workload attributes.</p>
|
||
<p>The dormant <code>trust_zone: platform</code> constant is not security-zone membership and MUST be retired before adoption. The new concept is named <code>security_zone</code>; the two fields must not coexist as competing zone sources.</p>
|
||
</section>
|
||
<section id="s8"><h2><span class="sn">08</span>Membership-change observability</h2>
|
||
<p>A membership change becomes effective only through a reviewed declaration and a newly compiled artifact. The compiler emits the source and membership revision, rejects ambiguous identities, and reports additions, removals, and changes against the preceding snapshot. Controls expose the membership revision in their decision or verdict evidence.</p>
|
||
<p>A zone that can be widened by editing an unversioned runtime label is not conformant.</p>
|
||
</section>
|
||
<section id="s9"><h2><span class="sn">09</span>Time-boxed exceptions</h2>
|
||
<p>The normative lifecycle is the ZONE-WP-0001-T04 decision in <code>zone-engine/docs/exception-lifecycle-2026-08-22.md</code>: only the control owner's designated authority grants a named-workload, named-zone, named-control relaxation within a declared maximum duration. Enforcement applies it only for <code>not_before <= now < not_after</code>; invalid or unevaluable records are inactive, expiry restores the base rule automatically, and no minted credential, lease, or session may outlive the exception.</p>
|
||
<p>Exceptions live with the versioned control policy or PEP configuration and are evaluated where their effects occur. This requires no zone-engine runtime.</p>
|
||
</section>
|
||
<section id="s10"><h2><span class="sn">10</span>Adoption</h2>
|
||
<p>Net-kingdom published this standard at revision <code>337484a</code>. Adoption requires:</p>
|
||
<ol><li>flex-auth and ops-warden accept the initial control profile or publish a versioned replacement with total zone and <code>unknown</code> coverage;</li><li>at least two workload owners declare authoritative identities and zones;</li><li>a third consumer compiles or reads the resolved view; and</li><li>ops-warden retires <code>policy.enabled</code> and the dormant <code>trust_zone</code> constant in the same migration.</li></ol>
|
||
<p>All four gates were met on 2026-08-22. The owning zone-engine repository records the exact consumer revisions, tests, resolved membership digests, and live caller decision in <code>docs/evidence/security-zone-adoption-2026-08-22.md</code>.</p>
|
||
</section><footer><span>netkingdom-security-zones-v0.1 · · proposed</span><span>net-kingdom · canon/standards/security-zones_v0.1.md · 9781102e2971d762ae42fdd5085a6647afd1cd66</span></footer></main></div></div></html>
|