Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 17 additions & 16 deletions .github/workflows/url-authority-gate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,23 +79,21 @@ jobs:
"src/omnibase_core/validation/baselines/url_authority_baseline.json"
)
head = json.loads(baseline.read_text())
head_repo = {
e["fingerprint"]
for e in head["violations"]
if e["repo"] == "omnibase_core"
}
# Baseline growth is checked across ALL repos recorded in this file,
# not just omnibase_core's own subset — the baseline is a single
# shared grandfather list for every repo the gate scans (including
# cross-repo entries such as omnibase_infra), and a repo-scoped
# filter here would let growth in any other repo's entries through
# unnoticed.
head_all = {e["fingerprint"] for e in head["violations"]}
# Compare against the baseline on the PR base branch.
base_ref = "origin/${{ github.base_ref || 'dev' }}"
try:
prior_text = subprocess.check_output(
["git", "show", f"{base_ref}:{baseline}"], text=True
)
prior = json.loads(prior_text)
prior_repo = {
e["fingerprint"]
for e in prior["violations"]
if e["repo"] == "omnibase_core"
}
prior_all = {e["fingerprint"] for e in prior["violations"]}
except subprocess.CalledProcessError:
# Baseline file does not exist on the base branch — this is the
# initial introduction of the baseline for this repo. By definition
Expand All @@ -104,21 +102,24 @@ jobs:
# caught by the gate step above.
print(
"URL-AUTHORITY BASELINE OK (initial): "
f"baseline file is new on this PR ({len(head_repo)} grandfathered "
f"baseline file is new on this PR ({len(head_all)} grandfathered "
"fingerprints); no prior to compare against."
)
sys.exit(0)
grew = head_repo - prior_repo
grew = head_all - prior_all
if grew:
sys.stderr.write(
"URL-AUTHORITY BASELINE GREW: "
f"{len(grew)} new fingerprint(s) added to the baseline. The baseline "
"is burn-down only — fix the violation or annotate with "
"# url-authority-ok:, never grow the baseline.\n"
f"{len(grew)} new fingerprint(s) added to the baseline (any repo). "
"The baseline is burn-down only — never grow it. For rules 1-4, "
"fix the violation or annotate with # url-authority-ok: <reason>. "
"For rule 5 (msk-direct-broker-endpoint) the entry MUST be removed "
"— that rule is not suppressible, so annotating it never clears "
"the growth.\n"
)
Comment thread
coderabbitai[bot] marked this conversation as resolved.
sys.exit(1)
print(
"URL-AUTHORITY BASELINE OK: "
f"omnibase_core subset {len(head_repo)} (<= prior {len(prior_repo)})."
f"{len(head_all)} total (<= prior {len(prior_all)})."
)
PY
16 changes: 14 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1380,14 +1380,26 @@ repos:
# Ratchet: NEW fingerprints fail; existing violations are grandfathered.
# Baseline is burn-down only. Migration debt: OMN-12806 (omnibase_core).
# Suppress with: # url-authority-ok: <reason>
#
# File scope covers .py (rules 1-4 + rule 5) plus yaml/yml/sh/env/cfg/
# conf/toml/ini/json/tf (named files with a real ".env" extension, e.g.
# gateway.env, match via this suffix group — NOT the basename group
# below), and (by basename, not suffix — a pure suffix regex cannot
# select these extensionless names) the bare .env file / .env.<profile>
# / Dockerfile / Dockerfile.<variant> families (rule 5,
# msk-direct-broker-endpoint, only — OMN-15692). Kept as an explicit
# `files` regex rather than pre-commit
# `types` tags so the covered set mirrors _MSK_SCAN_SUFFIXES +
# _is_msk_scannable in the validator itself (single source of truth
# for "which files this gate touches").
- id: check-url-authority
name: URL Authority Gate (OMN-12818)
entry: uv run python -m omnibase_core.validation.validator_url_authority
args: [--repo, omnibase_core, --repo-root, .]
language: system
types: [python]
files: (^|/)Dockerfile(\.[^/]*)?$|(^|/)\.env(\.[^/]*)?$|\.(py|ya?ml|sh|env|cfg|conf|toml|ini|json|tf)$
pass_filenames: true
exclude: ^(tests/|archived/|archive/).*\.py$
exclude: ^(tests/|archived/|archive/)
stages: [pre-commit]

# Backend Secret-Ref Discipline Gate (OMN-13305, ported from OMN-12971).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,16 @@ validation:
Every URL and *_URL / *_ENDPOINT env read must resolve from a contract
(routing authority / integration catalog), not a bare literal or env var.

Three rules:
Five rules:
- public-https-literal: quoted https:// URLs to public hosts (connection targets only)
- env-url-read: os.environ[*_URL] / os.environ.get(*_ENDPOINT) reads
- url-const-assignment: module-constant assignments from os.environ or https:// literal
- localhost-literal: hardcoded http(s):// loopback connection-target literals
- msk-direct-broker-endpoint: direct MSK broker hostname:port or raw bastion-IP literal
in an on-prem-facing config/script file (OMN-15692, operator ruling 2026-08-04).
Unlike the other four, this rule also scans non-.py files (yaml/yml/sh/env/
env.<profile>/cfg/conf/toml/ini/json/tf/Dockerfile[.variant]) — see target_patterns
below.

Existing violations are grandfathered by content fingerprint (ratchet baseline).
Only NEW fingerprints fail the gate. Baseline is burn-down only.
Expand All @@ -32,6 +38,19 @@ validation:

target_patterns:
- "**/*.py"
- "**/*.yaml"
- "**/*.yml"
- "**/*.sh"
- "**/*.env"
- "**/*.env.*"
- "**/*.cfg"
- "**/*.conf"
- "**/*.toml"
- "**/*.ini"
- "**/*.json"
- "**/*.tf"
- "**/Dockerfile"
- "**/Dockerfile.*"

exclude_patterns:
- "**/tests/**"
Expand Down Expand Up @@ -78,6 +97,18 @@ validation:
severity: error
enabled: true

- rule_id: msk-direct-broker-endpoint
description: >-
Rejects a direct MSK broker hostname (*.kafka.<region>.amazonaws.com, any AWS region) on its own
— no co-occurring port required, so split-key configs and non-9098/9096 ports (e.g. 9092/9094)
are equally caught — or the raw SNI-passthrough bastion IP, in an on-prem-facing config/script
file. On-prem hosts must go through the gateway, never a direct MSK broker connection (OMN-15692,
operator ruling 2026-08-04). Unlike the other four rules, this one also scans non-.py files, and
is NOT suppressible via # url-authority-ok: — the ruling states no exception path, so a self-authored
justification comment cannot waive it. Fix the reference instead.
severity: error
enabled: true

suppression_comments:
- "# url-authority-ok:"
- "# contract-config-ok:"
Expand Down
Loading
Loading