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
47 changes: 47 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -873,6 +873,53 @@ jobs:
--check-placeholders \
--scan-dir src/omnibase_infra

# OMN-17320: exposed-identifier gate. Blocks any denylisted customer identifier
# from re-entering this PUBLIC repo. Provenance: OMN-17288 scrubbed a live tenant
# slug out of five files here (omnibase_infra#3062, 3f10ee5e); three hours later
# omnimarket#2239 reintroduced the same slug there with every enforced gate green,
# on the very PR whose acceptance criterion was "zero grep hits". Nothing
# mechanically enforced the convention -- this job is that mechanism.
#
# Registered in scripts/ci/ci_summary_gate.py::STRICT_GATE_JOBS. THAT LINE IS HALF
# THE MECHANISM: the default-deny sweep already fails CI Summary when this job
# FAILS, but an unregistered job that is `skipped` or deleted yields SUCCESS -- so
# without the registration, removing this job would silently restore the
# unenforced state that produced the recurrence.
exposed-identifier-gate:
needs: occ-preflight
if: always()
name: Exposed Identifier Gate (OMN-17320)
# OMNI_RUNNER_SELECTOR_V1 — trusted CI defaults to self-hosted omnibase-ci; public forks default to ubuntu-latest
runs-on: >-
${{
(github.event_name == 'pull_request' &&
github.event.pull_request.head.repo.full_name != github.repository)
&& fromJSON(vars.OMNI_PUBLIC_PR_RUNS_ON_JSON || '["ubuntu-latest"]')
|| fromJSON((github.event_name == 'merge_group' && vars.OMNI_REQUIRED_CI_RUNS_ON_JSON) || vars.OMNI_TRUSTED_CI_RUNS_ON_JSON || '["self-hosted","omnibase-ci"]')
}}
timeout-minutes: 15

steps:
- name: Checkout code
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0

# Full tree, not the diff: a denylisted identifier reaching dev by ANY route
# (a rebase carrying it in, as happened on omnimarket#2241) must red the PR,
# not just one that edits the offending line. Stdlib-only, so no uv setup.
- name: Scan the working tree for denylisted identifiers
run: |
echo "================================================================"
echo "Exposed Identifier Gate (OMN-17320)"
echo "================================================================"
python3 scripts/validation/check_exposed_identifiers.py \
--mode blocking --scope all

- name: Report the cross-repo parity fingerprint
if: always()
run: |
echo "omnibase_infra copy:"
python3 scripts/validation/check_exposed_identifiers.py --print-fingerprint

# Pin reachability -- every cross-repo pin (workflow `uses:`/`with:` refs,
# pyproject [tool.uv.sources] revs, uv.lock git revs) must name a commit
# reachable from a PROTECTED branch of the target repo (OMN-15538).
Expand Down
17 changes: 17 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,23 @@ repos:
exclude: ^(tests/|archived/).*\.py$
pass_filenames: true # Only check changed files, not entire codebase
stages: [pre-push] # Moved to pre-push: ~1-5s for changed files only
# OMN-17320: exposed-identifier gate. Salted-SHA256 denylist of customer
# identifiers that must never re-enter this PUBLIC repo. OMN-17288 scrubbed a
# live tenant slug from five files here; three hours later an unrelated lane
# reintroduced it in omnimarket with every gate green. The denylist holds
# digests, never plaintext -- writing the literal into a pattern list in a
# public repo would be the very occurrence the gate prevents.
# Same script + same denylist as omnimarket (byte-identical; parity pinned by
# tests/ci/test_exposed_identifier_gate.py::test_cross_repo_fingerprint_pin).
# Escape hatch, per line only, ticket + reason required:
# # onex-allow-exposed-identifier OMN-XXXXX reason="<concrete reason>"
- id: exposed-identifier-gate
name: Exposed identifier gate (OMN-17320)
entry: python3 scripts/validation/check_exposed_identifiers.py --mode blocking
language: system
pass_filenames: true
stages: [pre-commit]
exclude: ^(archived/|workspace/sibling-repos/).*$
# Cleanup: Clear tmp/ directory before commits
- id: clean-tmp-directory
name: Clean tmp directory
Expand Down
11 changes: 11 additions & 0 deletions scripts/ci/ci_summary_gate.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,17 @@
# needs/if), so a skip is anomalous and never a legitimate opt-out.
# Superseded by OMN-16783's flow-expectation ratchet when that lands.
"Subscribe Wiring Health", # subscribe-wiring-health
# OMN-17320: salted-digest denylist of customer identifiers that must never
# re-enter this PUBLIC repo. THIS LINE IS HALF THE MECHANISM, same as the two
# entries above: the default-deny sweep already fails CI Summary when the job
# FAILS, but an unregistered job that is `skipped` or absent yields SUCCESS.
# Registered because the failure mode is PROVEN, not hypothetical -- OMN-17288
# scrubbed a live tenant slug from five files here, and three hours later an
# unrelated lane reintroduced it in omnimarket with every enforced gate green,
# on the very PR whose acceptance criterion was its absence. The job is
# unconditional in ci.yml (`if: always()`), so a skip is anomalous and never a
# legitimate opt-out.
"Exposed Identifier Gate (OMN-17320)", # exposed-identifier-gate
# OMN-15378 AC3: scripts/deploy-agent's standalone pytest root. ci.yml's
# `deploy-agent-tests` job CALLS .github/workflows/deploy-agent-tests.yml,
# so the inner job surfaces as "<caller display name> / <inner job name>"
Expand Down
Loading
Loading