Skip to content

fix(baseline): wrap CEL expressions with has() guards (closes #220)#258

Merged
mlieberman85 merged 1 commit into
kusari-oss:mainfrom
mlieberman85:fix/220-cel-has-guards
May 14, 2026
Merged

fix(baseline): wrap CEL expressions with has() guards (closes #220)#258
mlieberman85 merged 1 commit into
kusari-oss:mainfrom
mlieberman85:fix/220-cel-has-guards

Conversation

@mlieberman85
Copy link
Copy Markdown
Contributor

Summary

Closes #220. Two CEL expressions in `openssf-baseline.toml` accessed GitHub API fields without checking for their presence first, and crashed with `KeyError` whenever the API response omitted them — which happens routinely for non-admin tokens or orgs that hide 2FA settings.

Control API endpoint Field Old expression New expression
OSPS-AC-01.01 (`RequireMFA`) `/orgs/$OWNER` `two_factor_requirement_enabled` direct access wrapped with `has(...)`
OSPS-AC-03.02 (`PreventBranchDeletion`) `/repos/$OWNER/$REPO/branches/$BRANCH/protection` `allow_deletions.enabled` direct nested access chained `has()` on both outer + leaf keys

The pattern matches an existing one in the same TOML (OSPS-AC-03.01 at line 2563): `has(output.json.enabled) && output.json.enabled == true`. Both affected controls already have a `manual` pass as their second-phase fallback, so missing fields now produce INCONCLUSIVE → fall through → WARN, rather than a hard crash. Conservative-by-default (Constitution Principle II) holds: nothing pretends to PASS without a verified-positive signal.

Test plan

  • 7 new regression tests in `TestIssue220HasGuards` covering: pass / fail / outer-key-missing / inner-key-missing / value-missing for both expressions. The `*_does_not_crash` tests are the canonical guards against this regressing.
  • `uv run ruff check .` — clean on touched files
  • `uv run pytest tests/ --ignore=tests/integration/ -q` — 2115 passed (7 new) / 6 skipped / 0 failed
  • `uv run python scripts/validate_sync.py --verbose` — PASS

🤖 Generated with Claude Code

…oss#220)

The CEL expressions for two OpenSSF Baseline controls assumed fields
that GitHub's API does not always return. When a non-admin token
hits /orgs/<org> (OSPS-AC-01.01) or /repos/.../protection
(OSPS-AC-03.02), the response omits the queried key entirely and the
evaluator raises KeyError instead of falling through to the next
pass.

Fix wraps both expressions with has() guards, matching the pattern
already in use elsewhere in this TOML (e.g. OSPS-AC-03.01 at line
2563). Missing fields now evaluate to false → INCONCLUSIVE →
pipeline falls through to the manual pass (the existing fallback in
both controls), which surfaces as WARN. Conservative-by-default
holds: nothing pretends to PASS without a verified-positive signal.

- OSPS-AC-01.01 (RequireMFA): has(...two_factor_requirement_enabled)
- OSPS-AC-03.02 (PreventBranchDeletion): chained has() because both
  the outer `allow_deletions` key AND the inner `.enabled` leaf may
  be missing independently

Adds 7 regression tests in a new TestIssue220HasGuards class covering
pass / fail / outer-missing / inner-missing / value-missing for both
expressions. The "missing key does not crash" tests are the canonical
guards against this bug recurring.

Verification:
- ruff check: clean
- full suite: 2115 passed (7 new) / 6 skipped / 0 failed
- validate_sync.py: PASS

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@mlieberman85 mlieberman85 merged commit 814ef1e into kusari-oss:main May 14, 2026
9 checks passed
@mlieberman85 mlieberman85 deleted the fix/220-cel-has-guards branch May 14, 2026 11:39
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.

Bug: KeyError on allow_deletions and two_factor_requirement_enabled in CEL expressions

1 participant