Skip to content

feat(network-tiers): balanced baseline allowlist + deterministic additions guard (#301, #302) - #315

Merged
wz-gsa merged 3 commits into
mainfrom
feat/network-tier-balanced-baseline-301
Aug 12, 2026
Merged

feat(network-tiers): balanced baseline allowlist + deterministic additions guard (#301, #302)#315
wz-gsa merged 3 commits into
mainfrom
feat/network-tier-balanced-baseline-301

Conversation

@wz-gsa

@wz-gsa wz-gsa commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator

Summary

Two pieces of the neutral-network-tiers epic (#303; design ADR 0002, schema vocab #300 in PR #313), folded together because the baseline data and its additions-guard are one reviewable unit.

#301 — curated balanced baseline

integrations/isolation/network-tiers/balanced.yaml — the version-controlled source of truth for what the balanced tier allows, seeded from the merged quickstart msb-balanced mirror. Every host carries a one-line why.

  • core (148) = the minimal, vouched-safe set SHIPPED as the balanced default (language/package registries, first-party AI model APIs, source-host + container-registry family, OS mirrors, cert CRL/OCSP).
  • extended (43) = dev-convenience SaaS (Figma/Supabase/Vercel, third-party AI IDEs, broad **.amazonaws/**.googleapis wildcards) — deliberately NOT in the default egress for a prompt-injectable agent; documented, justified, opt-in.
  • schemas/network-tier-baseline-v1.schema.json (draft-2020-12) + scripts/validate_network_tiers.py (per-entry why required, no cross-tier dup, host/wildcard/port pattern).

#302 — deterministic additions guard

scripts/check_balanced_allowlist_additions.py — an offline, no-network risk lint over the hosts (wired into make validate/CI). A 3/3 nexus-agents consensus rejected a live reputation feed (over-engineering + a federal data-sharing concern for a hand-curated, human+CODEOWNERS-reviewed list); Option A (no network) satisfies the fail-safe/offline/deterministic constraints and cannot flake.

  • ERROR: raw IP literal; wildcard over a public suffix (opens a whole TLD).
  • WARN (advisory, exit 0): punycode/IDN homograph, risky TLD, deep nesting, unexpected plaintext :80 (cert/CRL/OCSP + OS mirrors excused).
  • Typosquat/edit-distance heuristic deliberately omitted — sibling brands (github/gitlab, docker.io/docker.com) would fire every run and train reviewers to ignore it.

Governance

Ships as a PROPOSED list — an agent proposes, never self-approves; the contents of a federally-shipped default egress allowlist are a CODEOWNERS + security decision. The per-host why makes that review fast; the guard is an aid, not the authority.

Verification

342 tests pass (30 for the tier work); make validate green; ruff clean.

Dependencies

Consumes the network.tier vocab from #313 (#300). Unblocks quickstart #294 (adapter maps tier → sbx/msb and consumes this baseline). Closes #301 and #302.

AI-assisted (OpenCode); consensus-reviewed (3/3). Requires human review — especially the core/extended split.

@mogul mogul left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No cloud.gov...?

wz-gsa added 3 commits August 12, 2026 12:27
…dator (#301)

Second piece of the neutral-network-tiers epic (#303; design ADR 0002, schema
vocab #300). Adds the version-controlled, in-repo source of truth for what the
'balanced' network tier allows, seeded from the merged quickstart
msb-balanced-hosts mirror (itself a copy of sbx 'balanced'). No runtime fetch —
pinned like any kit artifact.

- integrations/isolation/network-tiers/balanced.yaml: every host carries a one-
  line  justification. CORE (148 hosts) = the minimal vouched-safe set
  SHIPPED as the balanced default (language/package registries, first-party AI
  model APIs, source-host + container-registry family, OS mirrors, cert CRL/OCSP).
  EXTENDED (43 hosts) = dev-convenience SaaS (Figma/Supabase/Vercel/Clerk, third-
  party AI IDEs, broad **.amazonaws/**.googleapis cloud wildcards) — deliberately
  NOT in the default balanced egress for a prompt-injectable agent; documented,
  justified, opt-in. This is the curation decision the issue calls for.
- schemas/network-tier-baseline-v1.schema.json: draft-2020-12; host charset +
  wildcard (**./*./crl*) + optional :port; require version/tier/core + per-entry
  why; additionalProperties:false.
- scripts/validate_network_tiers.py (wired into validate_repo/make validate):
  schema + curation rules JSON Schema can't express — every entry justified, no
  cross-tier duplicate host. Falls back to a regex host check without jsonschema.

GOVERNANCE: the CONTENTS of a federally-shipped default allowlist are a
human/CODEOWNERS + security-skill decision. This ships a PROPOSED list for
review; an agent proposes, never self-approves. The validator only keeps the
file well-formed + internally consistent.

Tests: schema (host forms, tier const, why-required, core-required, typo/bad-host
rejected) + live-file consistency (schema-valid, all justified, no cross-tier
dupes, essentials present, SaaS kept out of core) + validator-passes. 328 tests;
make validate green; ruff clean.

Depends on #300 (tier vocab). Unblocks quickstart #294 (adapter consumes this).
Proposes-closes #301 pending human review of the list.

AI-assisted (OpenCode); consensus-reviewed (3/3 on the tier design). Requires human review.

Co-authored-by: OpenCode Agent <william.zujkowski@gsa.gov>
…llowlist (#302)

Third piece of the neutral-network-tiers epic (#303), folded into the baseline
PR (#301) since the guard and the data it guards are one reviewable unit.

Adds scripts/check_balanced_allowlist_additions.py — a DETERMINISTIC, offline
risk lint over the balanced allowlist hosts, wired into validate_repo /
make validate. A 3/3 nexus-agents consensus REJECTED a live reputation feed
(Option B/C) as over-engineering + a federal data-sharing concern for a
hand-curated ~150-entry list already gated by a per-host  + CODEOWNERS
review; Option A (no network) fully satisfies the fail-safe / offline /
deterministic constraints. So the guard makes NO network call and cannot flake.

Signals:
  ERROR - raw IPv4/IPv6 literal (allowlist by hostname; an IP is unauditable).
  ERROR - wildcard over a public suffix (, ) — opens a whole TLD.
  WARN  - punycode/IDN (homograph), risky TLD, deep nesting (>4 labels),
          unexpected plaintext :80 (cert/CRL/OCSP + OS mirrors excused).
Warnings are advisory (exit 0, defer to review); errors fail (exit 1). A
typosquat/edit-distance heuristic was deliberately OMITTED — on a co-curated
list, sibling brands (github/gitlab, docker.io/docker.com) sit within a small
edit distance and would fire every run, training reviewers to ignore the guard.

balanced.yaml header documents the guard + the not-a-runtime-blocklist,
no-network, authority-is-human-review posture.

Tests: 14 (each ERROR/WARN heuristic, cert/OS-mirror :80 excused, sibling-brands
quiet, live-file has no errors). 342 pass; make validate green; ruff clean.

Depends on #301 (same PR). Proposes-closes #302 pending human review.

AI-assisted (OpenCode); consensus-reviewed (3/3, Option A). Requires human review.

Co-authored-by: OpenCode Agent <william.zujkowski@gsa.gov>
Co-authored-by: OpenCode Agent <william.zujkowski@gsa.gov>
@wz-gsa
wz-gsa force-pushed the feat/network-tier-balanced-baseline-301 branch from 0f194a3 to c0a74a9 Compare August 12, 2026 17:05
@wz-gsa
wz-gsa merged commit aff5d63 into main Aug 12, 2026
11 of 13 checks passed
@wz-gsa
wz-gsa deleted the feat/network-tier-balanced-baseline-301 branch August 12, 2026 17:29
mogul pushed a commit that referenced this pull request Aug 12, 2026
…se-positives (#316) (#317)

* fix(ci): authenticate Link Check to github.com to stop rate-limit false-positives (#316)

The Link Check job (tcort/github-action-markdown-link-check, unauthenticated)
intermittently reported LIVE github.com URLs as dead (Status 0/503) when a run
checked many links at once and hit GitHub's ~60/hr anonymous rate limit — seen
blocking approved PRs #313/#315 on consecutive runs, every flagged link 200 in
a browser. retryOn429 never engaged because GitHub sheds anonymous load with
503, not 429.

Fix (no new secret, read-only token only):
- httpHeaders: send Authorization: Bearer <token> for github.com / api.github.com
  / raw.githubusercontent.com, so those links are checked AUTHENTICATED
  (5000/hr). A CI step renders the read-only workflow GITHUB_TOKEN into the
  placeholder via envsubst (whitelisted to  only) → a
  git-ignored .markdown-link-check.ci.json; locally the placeholder stays inert
  ('Bearer '), so github still answers anonymously and the committed config
  carries no token.
- aliveStatusCodes: add 429 + 503 so a throttled probe of a live host defers
  instead of being reported dead (belt-and-suspenders alongside the token).
- retryCount 3 -> 5.

Real dead links still fail (a genuine 404 is not in aliveStatusCodes). Job stays
continue-on-error. Verified: config renders to valid JSON with + without a token;
make validate + 354 tests pass.

Closes #316.

AI-assisted (OpenCode). Requires human review.

Co-authored-by: OpenCode Agent <william.zujkowski@gsa.gov>

* fix(ci): ignore nvd.nist.gov in Link Check (bot-hostile to HEAD probe)

Follow-up within #316: with github.com now authenticated, the only remaining
Link Check false-positive was nvd.nist.gov -> Status 0. NVD is bot-hostile to the
checker's unauthenticated HEAD probe (same behavior as asciinema.org) but is a
live, stable gov site referenced from the dependency-analysis skill. Ignore it,
matching the asciinema treatment. Real dead links still fail.

Co-authored-by: OpenCode Agent <william.zujkowski@gsa.gov>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

network-tiers: add the curated, SHA-pinned 'balanced' baseline allowlist data file

2 participants