Skip to content

DEVOP-579: add NetworkPolicy egress rollout plan (doc only) - #7

Open
srt0422 wants to merge 11 commits into
allora-network:mainfrom
srt0422:devop-579-networkpolicy-rollout
Open

DEVOP-579: add NetworkPolicy egress rollout plan (doc only)#7
srt0422 wants to merge 11 commits into
allora-network:mainfrom
srt0422:devop-579-networkpolicy-rollout

Conversation

@srt0422

@srt0422 srt0422 commented May 13, 2026

Copy link
Copy Markdown

Summary

Adds tickets/devop-579-network-policy-rollout.md — a staged plan for rolling default-deny-egress NetworkPolicies across our 13 clusters.

Why doc-first

NetworkPolicy egress hardening is a 3-engineer-week project where the bulk of effort is discovery, not deployment. default-deny-egress silently breaks every workload that has an un-enumerated outbound dependency, so rushing it is production-impacting. Capturing the plan now (Phases 0-4, rollback procedure, dependencies on DEVOP-588/589) means subsequent loop runs or human owners can pick up execution without redoing the planning.

This PR adds only the plan document. No NetworkPolicy is deployed.

Test plan

  • Document compiles, internal links resolve.
  • Reviewer: confirm CNI assumption (Calico/Cilium across all 13 clusters?) and adjust Phase 0 if wrong.
  • Reviewer: confirm priority ordering of namespaces in Phase 1 matches actual blast-radius.

Related

Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com


Summary by cubic

Adds a phased doc plan to roll out default-deny-egress with a parallel default-deny-ingress across all 13 clusters for DEVOP-579; no policies are deployed. Pins exact policy names for Kyverno/rollback, notes NetworkPolicies are stateful (conntrack), fixes Phase 0 with per‑CNI flow logging plus CoreDNS dnstap/Cilium DNS capture, enforces 48‑hour one‑namespace soaks with a clean gate, adds a suspect‑egress checklist, updates SECURITY-RUNBOOK.md with both rollback commands, and removes a phantom ingress baseline‑allow from the naming table.

  • Dependencies
    • Hard: DEVOP-589 (Harbor proxy-cache) must land before Phase 2.
    • Soft: DEVOP-588 (Kyverno on all clusters) for Phase 4 enforcement.

Written for commit 058a8ea. Summary will update on new commits.

Review in cubic

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 issues found across 1 file

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="tickets/devop-579-network-policy-rollout.md">

<violation number="1" location="tickets/devop-579-network-policy-rollout.md:33">
P2: The discovery checklist omits the DEVOP-579 requirement to explicitly flag suspect egress destinations (webhook/pastebin/ngrok/169.254.169.254).</violation>

<violation number="2" location="tickets/devop-579-network-policy-rollout.md:52">
P1: Phase 3 uses 24-hour soak windows, but linked Linear issue DEVOP-579 specifies 48-hour soaks for staged rollout.</violation>

<violation number="3" location="tickets/devop-579-network-policy-rollout.md:64">
P2: Phase 4 is missing the DEVOP-579 requirement to document the rollout/policies in SECURITY-RUNBOOK.md.</violation>

<violation number="4" location="tickets/devop-579-network-policy-rollout.md:74">
P2: This plan marks ingress NetworkPolicies as out of scope, but linked Linear issue DEVOP-579 requires default-deny for both egress and ingress.</violation>
</file>
Architecture diagram
sequenceDiagram
    participant K8s as Kubernetes Clusters (13)
    participant CNI as CNI Plugin (Calico/Cilium)
    participant Hubble as Hubble/Flow Logs
    participant Harbor as Harbor Registry
    participant Kyverno as Kyverno Policy Engine
    participant Runbook as Rollback Runbook

    Note over K8s,Runbook: Phase 0 — Pre-flight Assessment
    K8s->>CNI: Confirm NetworkPolicy support
    alt CNI supports NetworkPolicy
        CNI-->>K8s: Calico, Cilium, or Antrea confirmed
    else Flannel without --network-policy
        CNI-->>K8s: Need to migrate CNI first
    end
    K8s->>Hubble: Enable flow logs on staging cluster
    Note over Hubble: Capture 7 days baseline traffic

    Note over K8s,Rollback: Phase 1 — Discovery (per namespace)
    loop For each namespace in priority order
        K8s->>Hubble: Query egress flow logs (7 days)
        Hubble-->>K8s: Destination CIDRs, DNS, ports
        K8s->>K8s: Categorize traffic (internal/infra/vendor/registries/customer)
        K8s->>K8s: Document in network-policies/discovery/<namespace>.md
    end

    Note over K8s,Rollback: Phase 2 — Allowlist Authoring
    K8s->>K8s: Create default-deny.yaml (deny all egress except DNS)
    K8s->>K8s: Create allowlist.yaml (derived from Phase 1)
    Note over K8s: DNS to kube-dns/coredns (53/udp, 53/tcp)
    Note over K8s: NTP always allowed (123/udp)
    Note over K8s: Cluster-internal pod-to-pod allowed by default
    K8s->>Harbor: Dependency on DEVOP-589 (Harbor proxy-cache)
    alt DEVOP-589 landed
        Note over K8s: Allowlists reference Harbor proxy instead of direct registries
    else Not yet landed
        Note over K8s: Allowlists must allow direct ghcr.io, docker.io, etc.
    end

    Note over K8s,Rollback: Phase 3 — Staged Rollout
    K8s->>K8s: Day 1: Apply to 1 staging namespace, observe 24h
    K8s->>K8s: Day 2: Apply to all staging namespaces, observe 24h
    K8s->>K8s: Day 3: Apply to 1 production namespace (lowest risk), observe 24h
    K8s->>K8s: Days 4-5: Roll forward remaining namespaces (lowest blast-radius first)
    alt Egress broken for workload
        K8s->>Runbook: kubectl delete networkpolicy default-deny -n <ns>
        Runbook-->>K8s: Egress restored immediately
    end

    Note over K8s,Rollback: Phase 4 — Steady State
    alt DEVOP-588 landed (Kyverno on all clusters)
        Kyverno->>K8s: Auto-flag new namespaces without default-deny
        K8s->>K8s: Monthly review of discovery documents
    else Not yet landed
        Note over K8s: Manual enforcement only
    end
Loading

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.

Comment thread tickets/devop-579-network-policy-rollout.md Outdated
Comment thread tickets/devop-579-network-policy-rollout.md
Comment thread tickets/devop-579-network-policy-rollout.md Outdated
Comment thread tickets/devop-579-network-policy-rollout.md Outdated
@srt0422 srt0422 added the shai-hulud Shai-Hulud supply-chain defense work label May 13, 2026
srt0422 and others added 2 commits May 21, 2026 17:07
NetworkPolicy egress hardening is a 3-engineer-week project that
must NOT be rushed — `default-deny-egress` silently breaks every
workload that has an un-enumerated outbound dependency. The bulk of
the work is discovery (7 days of baseline flow logs per namespace),
not deployment.

This doc captures the staged rollout plan so subsequent loop runs
(or whoever picks up execution) don't redo the planning work. Covers:

- Phase 0: pre-flight (CNI compat, flow log enablement).
- Phase 1: discovery (per-namespace egress enumeration).
- Phase 2: allowlist authoring.
- Phase 3: staged rollout (1 staging → 1 prod → fan out).
- Phase 4: steady-state (Kyverno schema enforcement, monthly review).

Dependencies:
- DEVOP-589 (Harbor proxy-cache) must land before Phase 2 or the
  allowlists will churn.
- DEVOP-588 (Kyverno on all clusters) is a soft dep for Phase 4.

This PR adds the doc only. No NetworkPolicy is deployed.

Linear: https://linear.app/alloralabs/issue/DEVOP-579

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ook hook, ingress in scope

Four findings from cubic addressed:

1. tickets/devop-579-network-policy-rollout.md:33 (P2) — Phase 1
   discovery checklist now explicitly enumerates suspect egress
   destinations to flag for incident review (webhook receivers,
   pastebins, ngrok/tunnel services, 169.254.169.254 / cloud
   metadata, residential dynamic-DNS). Each flagged destination
   gets an owner-review gate before allowlist inclusion.

2. tickets/devop-579-network-policy-rollout.md:52 (P1) — Phase 3
   staged rollout soak windows changed from 24h to the 48h spec'd
   by DEVOP-579, and now require a clean soak before advancing.

3. tickets/devop-579-network-policy-rollout.md:64 (P2) — Phase 4
   steady-state now mandates documenting the rollout, allowlist
   layout, rollback command, and on-call escalation path in
   SECURITY-RUNBOOK.md (DEVOP-571).

4. tickets/devop-579-network-policy-rollout.md:74 (P2) — Ingress
   default-deny is no longer out-of-scope. Added a dedicated
   section laying out the parallel ingress cohort (same Phases 0–4
   shape with ingress-specific discovery, allowlist patterns,
   slower production rollout because ingress blast-radius is
   higher, and Kyverno asserting both directions in Phase 4).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@srt0422
srt0422 force-pushed the devop-579-networkpolicy-rollout branch from f377778 to 7b93a18 Compare May 22, 2026 00:07
Comment thread tickets/devop-579-network-policy-rollout.md
…d DNS-log enablement + join step

@gh-allora flagged that Hubble/Calico egress flow logs are L3/L4 only,
so the Phase 1 line "enumerate destination CIDRs, DNS names, and ports"
can't be satisfied from flow logs alone. Confirmed: Hubble flow records
and Calico flow logs surface src/dst IP, port, and protocol — DNS names
require either a CoreDNS query log feed or Cilium's L7 DNS visibility
(which routes pod DNS through the proxy and records resolved FQDNs).

Fix is structural, not cosmetic:

- Phase 0 now has an explicit "enable verbose DNS query logging" step
  alongside flow log enablement, with concrete options for CoreDNS
  (`log` plugin) and Cilium (L7 DNS via `hubble observe --type=dns`),
  plus a retention check so the 7-day baseline is actually queryable
  before Phase 1 starts.
- Phase 1 line 33 is split into two checklist items: enumerate CIDRs +
  ports from flow logs (the only fields they carry), then resolve to
  FQDNs by joining flow records against the Phase 0 DNS logs on
  (srcPodIP, dstIP) within a short window. Destinations with no DNS
  match (hard-coded IPs, 169.254.169.254, raw cloud-metadata) are
  carried through as IP-only and fall into the existing suspect-
  destination review.

review-fix-loop iteration 1
reviewer(s): gh-allora (human PR thread)
file: tickets/devop-579-network-policy-rollout.md:17,33

Co-Authored-By: Claude Opus 4.7 (review-fix-loop) <noreply@anthropic.com>

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 1 file (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Fix all with cubic | Re-trigger cubic

Comment thread tickets/devop-579-network-policy-rollout.md Outdated
srt0422 and others added 4 commits May 30, 2026 07:33
…ith real per-CNI enablement

Two problems in the Phase 0 checklist that would have wasted an
engineer's day before they figured out the doc was wrong:

1. `network-policy-engine (Calico)` and `Cilium's native NPL` are not
   real component names. Felix is Calico's per-node policy enforcer;
   Cilium ships NetworkPolicy enforcement built in (no separate "NPL"
   — NPL means NodePort Local in Antrea/Calico, unrelated to
   NetworkPolicy). The flannel-fallback bullet now correctly says the
   only path forward on flannel-without-policy is a CNI migration to
   Calico or Cilium, since flannel itself cannot enforce
   NetworkPolicies.

2. `calicoctl flow logs enable` is not a calicoctl subcommand. Calico
   OSS flow logs are turned on via the FelixConfiguration CR
   (`spec.flowLogsFileEnabled: true`), and the resulting files land
   under `/var/log/calico/flowlogs/` on each node. Also called out
   that OSS file-based flow logs cover allow/deny only — for richer
   flow context the team needs Calico Enterprise / Calico Cloud, and
   the recommendation is to prefer the Cilium staging cluster for
   baseline capture if the option exists. Antrea enablement (Flow
   Exporter feature gate + flow-aggregator) added for completeness
   since one of our clusters is on Antrea.

review-fix-loop iteration 1
reviewer(s): review-fix-loop (correctness lens)
file: tickets/devop-579-network-policy-rollout.md:15-17

Co-Authored-By: Claude Opus 4.7 (review-fix-loop) <noreply@anthropic.com>
…ok now matches actual resource names

The rollback runbook command `kubectl delete networkpolicy default-deny
-n <ns>` would no-op (NotFound) once ingress lands, because the ingress
section calls the ingress policy `default-deny-ingress` while the egress
section never pinned the egress resource name. So:

- An engineer authoring `default-deny.yaml` could legitimately name the
  resource `default-deny-egress`, `egress-default-deny`, or anything
  else. The runbook would silently fail to delete it in an incident.
- Once both directions are deployed, the runbook needs both rollback
  commands, not one.
- The Phase 4 Kyverno asserter needs to grep on a deterministic
  resource name to enforce "every namespace has both default-deny
  policies".

Fix is structural: Phase 2 now contains a pinned naming convention
table that the rollback runbook (Phase 3) and the Kyverno asserter
(Phase 4) both reference by exact `metadata.name`. As a side effect of
pinning, also split the egress baseline allows (DNS/NTP) into a
separate generated policy (`egress-baseline-allow`) so the per-namespace
`egress-allowlist` only contains workload-specific rules — resolves
the Phase 2 ambiguity over which baseline rules live in default-deny
vs allowlist.

Changes:
- New Phase 2 naming-convention table mapping filename ↔ metadata.name
  ↔ purpose for all five policy kinds (3 egress + 2 ingress).
- Rollback runbook now lists both `default-deny-egress` and
  `default-deny-ingress` commands and calls out drift as an incident.
- Phase 4 SECURITY-RUNBOOK hook now references both rollback commands.
- Phase 4 Kyverno bullet now matches by exact metadata.name from the
  pinned table.
- Ingress section's Phase 2 substitution now references the same table
  for both file name and resource name.

review-fix-loop iteration 1
reviewer(s): review-fix-loop (reliability lens)
file: tickets/devop-579-network-policy-rollout.md:52,80,87,112,122

Co-Authored-By: Claude Opus 4.7 (review-fix-loop) <noreply@anthropic.com>
…witch to dnstap (full)

cubic flagged that my iter-1 Phase 0 DNS-log instruction was broken:
the CoreDNS `log` plugin emits client IP + query name + response code
but NOT the answer-section A/AAAA IPs, so the
`(srcPodIP, dstIP)` join described in Phase 1 has nothing on the DNS
side to match `dstIP` against. Confirmed — `log`'s format is per the
CoreDNS docs, and resolved IPs only appear in the actual DNS message
response (the answer section).

Fix is to use the `dnstap` plugin with the `full` flag, which streams
wire-format DNS messages (request + response, including the answer
section) to a Unix socket or TCP collector. A dnstap collector
(`golang-dnstap`, `dnstap-receiver`) decodes those into
`(timestamp, client_pod_ip, query_name, response_ips[])` records that
can actually be joined against flow-log destinations. The Cilium
`hubble observe --type=dns` path was already correct because Hubble
records FQDN and answer IPs together.

Changes:
- Phase 0 DNS-capture bullet now specifies `dnstap ... full` for
  CoreDNS, names the collector requirement, and calls out explicitly
  that the query-only `log` plugin is insufficient (so a future
  reader who has read the old docs doesn't reach for it).
- Phase 1 resolve-to-FQDN bullet now describes the join key
  accurately: `srcPodIP == DNS client IP, dstIP ∈ DNS response answer
  IPs`, instead of pretending `log` output has the answer IPs.

review-fix-loop iteration 2
reviewer(s): cubic-dev-ai (PR thread PRRT_kwDOLZ5Xss6F4Gnj)
file: tickets/devop-579-network-policy-rollout.md:18-21,38

Co-Authored-By: Claude Opus 4.7 (review-fix-loop) <noreply@anthropic.com>
srt0422 added a commit that referenced this pull request Jun 5, 2026
GitHub PR #7's update-branch created merge commit 1a5cafe from the
PR-cached head (ee15fee) into main, bypassing our local fix commit
9d74209. This merge reconciles: keeps 9d74209's rollback-runbook
correctness fix while also pulling in main's no-op merge so the PR
head and the branch ref converge again.
@srt0422 srt0422 closed this Jun 5, 2026
@srt0422 srt0422 reopened this Jun 5, 2026
srt0422 added 3 commits July 17, 2026 11:47
review-fix-loop iteration 1
reviewer(s): persona
file: tickets/devop-579-network-policy-rollout.md:11
review-fix-loop iteration 1
reviewer(s): persona
file: tickets/devop-579-network-policy-rollout.md:86
review-fix-loop iteration 1
reviewer(s): quality
file: tickets/devop-579-network-policy-rollout.md:162

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 1 file (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="tickets/devop-579-network-policy-rollout.md">

<violation number="1" location="tickets/devop-579-network-policy-rollout.md:86">
P2: The new cohort definition serializes rollout to one namespace every two days, which cannot fit the stated Phase 3/week-3 and three-engineer-week schedule across 13 clusters. Define a batched cohort or revise the timeline/estimate so this plan is operationally schedulable.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Fix all with cubic | Re-trigger cubic

- [ ] Days 1–2: apply policies to **1 staging namespace** in **1 staging cluster**. Soak 48h.
- [ ] Days 3–4: apply to all staging namespaces in 1 cluster. Soak 48h.
- [ ] Days 5–6: apply to 1 production namespace (lowest-risk: docs site). Soak 48h.
- [ ] Days 7+: roll forward through remaining production namespaces in priority-inverse order (lowest-blast-radius first), keeping a 48h soak between each cohort — one cohort is one namespace.

@cubic-dev-ai cubic-dev-ai Bot Jul 17, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The new cohort definition serializes rollout to one namespace every two days, which cannot fit the stated Phase 3/week-3 and three-engineer-week schedule across 13 clusters. Define a batched cohort or revise the timeline/estimate so this plan is operationally schedulable.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At tickets/devop-579-network-policy-rollout.md, line 86:

<comment>The new cohort definition serializes rollout to one namespace every two days, which cannot fit the stated Phase 3/week-3 and three-engineer-week schedule across 13 clusters. Define a batched cohort or revise the timeline/estimate so this plan is operationally schedulable.</comment>

<file context>
@@ -83,7 +83,7 @@ whose egress only fires on cron/batch schedules.
 - [ ] Days 3–4: apply to all staging namespaces in 1 cluster. Soak 48h.
 - [ ] Days 5–6: apply to 1 production namespace (lowest-risk: docs site). Soak 48h.
-- [ ] Days 7+: roll forward through remaining production namespaces in priority-inverse order (lowest-blast-radius first), keeping a 48h soak between each cluster cohort.
+- [ ] Days 7+: roll forward through remaining production namespaces in priority-inverse order (lowest-blast-radius first), keeping a 48h soak between each cohort — one cohort is one namespace.
 
 A stage may only advance if the prior soak completed with zero
</file context>
Fix with cubic

@srt0422

srt0422 commented Jul 17, 2026

Copy link
Copy Markdown
Author

Final cross-provider review (agent-code-review, 3-pass)
verdict: Not ready
counts: P0=1 P1=2 P2=1 P3=1
coverage: Pass 1: kimi-k3 (orchestrator — substituted for Claude Opus 4.7 correctness+security and Claude Sonnet 5 style per user mandate; claude-code CLI not invoked). Pass 2: google/gemini-2.5-pro (correctness), deepseek/deepseek-v4-pro (security; 1 retry after initial timeout), meta-llama/llama-4-maverick (style). Pass 3: meta-llama/llama-4-maverick (correctness), z-ai/glm-5.2 (security — substituted for Claude Sonnet 5 per user mandate), meta-llama/llama-4-scout (style). No reductions. Every Pass 2/3 finding source-verified by the orchestrator before acceptance.

severity file:line category reviewer summary suggested_fix
P0 tickets/devop-579-network-policy-rollout.md:94-95 correctness both The documented rollback does not restore traffic. After kubectl delete networkpolicy default-deny-egress -n <ns>, egress-baseline-allow (podSelector {} per the Phase 2 table) still selects every pod, so all pods remain egress-isolated with only DNS+NTP allowed; egress-allowlist likewise keeps its pods isolated. "Restores all egress instantly" is false, and the ingress command on line 95 has the same defect via ingress-allowlist. On-call executing this runbook during an incident leaves the namespace broken and escalates with a failed rollback. Confirmed by 4 independent passes (Gemini, DeepSeek, GLM, orchestrator). Document deleting ALL egress policies: kubectl delete networkpolicy default-deny-egress egress-baseline-allow egress-allowlist -n <ns>; and for ingress: kubectl delete networkpolicy default-deny-ingress ingress-allowlist -n <ns>. Add a re-apply procedure (with SLA) so the namespace does not stay open indefinitely.
P1 tickets/devop-579-network-policy-rollout.md:61 security both The egress-baseline-allow DNS permit (53/udp+tcp to kube-dns/CoreDNS) leaves DNS tunneling / subdomain-encoded exfiltration open through the legitimate in-cluster resolver, defeating the stated C2-blocking goal (line 7); the suspect-destination review cannot see it because traffic terminates at the cluster resolver. Unacknowledged as residual risk. Confirmed by DeepSeek + GLM. Acknowledge DNS tunneling as a residual risk in the plan and either (a) add a compensating control (Cilium DNS-proxy inspection of query patterns, CoreDNS query-rate/response-size anomaly detection), or (b) explicitly defer detection to DEVOP-570 (Falco) with the gap stated in the goal section.
P1 tickets/devop-579-network-policy-rollout.md:5 security both hostNetwork: true pods bypass NetworkPolicy enforcement entirely (Calico, Cilium, Antrea). No phase inventories or mitigates hostNetwork workloads, so the plan's goal (closing pod-to-C2 egress) is not achieved for that class; a compromised hostNetwork pod retains unrestricted egress and metadata access. Confirmed by DeepSeek + GLM. Add a Phase 0/1 task to inventory all hostNetwork: true pods across the 13 clusters; then migrate them off hostNetwork where possible, apply host-level egress controls (iptables/eBPF) where not, or document them as accepted residual risk with compensating controls.
P2 tickets/devop-579-network-policy-rollout.md:101 security persona The Phase 4 Kyverno asserter only fails NEW namespaces missing a default-deny. After an emergency rollback deletes policies from an EXISTING namespace, no automated control detects or alerts on the resulting open-egress state; the namespace stays less-secure until manual re-apply. Add a Kyverno audit-mode policy that periodically asserts ALL existing non-system namespaces contain default-deny-egress/default-deny-ingress by pinned metadata.name, alert on absence, and document a post-rollback re-apply SLA in SECURITY-RUNBOOK.md.
P3 tickets/devop-579-network-policy-rollout.md:62 doc persona egress-allowlist scoping is implied ("workload-specific") but not pinned; an author could write a single policy with namespace-wide podSelector: {} carrying broad allows, silently violating least privilege. Add one line to the naming convention: egress-allowlist.yaml contains one NetworkPolicy object per workload, each with a specific spec.podSelector scoping rules to that workload.

Refuted after source-verification (14, recorded per the Pass 2/3 verification gate):

  • "Cilium L7 DNS visibility works regardless of DNS proxy in-path" (pass3-correctness) — false; Hubble DNS events require the DNS proxy in-path, and the doc's statement is correct.
  • "The rollback command is correct" (pass3-correctness) — refuted by the P0 finding above; its post-rollback policy-review concern is subsumed by the P2 finding.
  • Line 60 "deny except baseline allows" called imprecise (pass2-correctness) — the Purpose column describes net effect under additive semantics, consistent with the other rows; no operator harm.
  • "Phase 1 categories non-exhaustive" (pass3-correctness) — the list already signals openness via "etc." and the per-namespace bucket.
  • Pass 2/3 style items (10): sink options already listed at line 18; DEVOP-571 already linked in the Links section; join predicate explained in prose at line 22; SECURITY-RUNBOOK.md sits at this repo's root so the bare name is unambiguous; "Direction/Purpose" headers self-explanatory; "emergency" used consistently in both rollback bullets; "do not roll suspect destinations by default" is disambiguated by the incident-review sentence in the same bullet; the ingress "mirror with substitutions" structure is a deliberate DRY choice (duplicating the full egress checklist was previously considered and rejected); "on-call escalation path" is a specification of what to document, not an unresolved reference.

Loop context: review-fix-loop applied 4 doc fixes across 3 iterations before this pass (conntrack/stateful wording, cohort=one-namespace definition, related-ticket links, phantom ingress baseline-allow reference). The blocking findings above were surfaced only by the cross-provider matrix; per the bounded-loop design they are recorded here as residuals for the next loop run or human decision — they were not auto-fixed in this pass.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-human-review shai-hulud Shai-Hulud supply-chain defense work

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants