Skip to content

feat(opa): turn the OPA target on by default (SP2b Task 26) - #844

Merged
viethqb merged 11 commits into
mainfrom
feat/opa-default-on
Nov 8, 2026
Merged

viethqb merged 11 commits into
mainfrom
feat/opa-default-on

Conversation

@viethqb

@viethqb viethqb commented Nov 8, 2026 •

Copy link
Copy Markdown
Member

Summary

This is SP2b Task 26. It turns the OPA target on by default: [governance.opa] enabled now defaults to true. It also closes the readiness items that were still open after the port-8080 package (#842, #843).

The surface only runs when ranger.enabled is also on, and that key is off by default. With the defaults, the flip therefore changes nothing: no port is bound, no refresher runs, no error is logged, start-up behaves as before, and a switch to OPA is still refused. An installation that already runs the Ranger surface now mounts OPA and binds 8082 with no config change. Every profile stays on Ranger until an operator switches it.

The plan is in docs/en/plans/2026-11-08-gov-sp2b-task26-opa-default-on.md (with a docs/vi mirror).

Changes

  • Flip.
    • OpaSettings::enabled defaults to true, through both the serde default and Default.
    • The test is renamed governance_opa_is_on_by_default, and it asserts that EGRET_GOVERNANCE__OPA__ENABLED=false turns OPA off.
    • The new Config::opa_effective() is opa.enabled && ranger.enabled. It gates the listen collision and format checks and the OPA engine-URL derivation.
    • With Ranger off, start_opa logs an info! "idle" line instead of an error.
  • Helm.
    • opa.enabled: true.
    • EGRET_GOVERNANCE__OPA__ENABLED is always rendered from opa.enabled.
    • The OPA container port, the Service port, OPA__LISTEN and the NetworkPolicy OPA rule render only when both opa.enabled and ranger.enabled are on.
  • Switch refusal text now names both keys: "OPA is not running on this installation: it needs both [governance.opa] enabled and ranger.enabled".
  • Tag-service warning (readiness 7, user decision: warn, don't block).
    • When a Trino profile has no usable tag service, no_tag_service_warning is set on the PATCH …/mechanism answer (200 and 502) and on every explain profile, on Ranger and on OPA.
    • The UI shows it in the mechanism section and in the explain result.
  • Shared-tag-service refresh latency (readiness 4, M5).
    • Measured first, then fixed: the C8 stored-overlap re-check now loads only the profile's own unit {p, tag(p)}, not one unit per profile that shares the tag service. It reports exactly the same pairs.
    • Time until the last profile is current, p50 on a loaded dev machine:
      • N=5: 1.1 s → 0.39 s;
      • N=10: 4.3 s → 1.04 s;
      • N=20: 18.3 s → 3.5 s.
    • The report section is in docs/en/reports/2026-11-06-gov-sp2b-opa-latency.md.
  • Large /batch through opa_router (readiness 5, M4).
    • A 5 MiB /batch gets 200 under the default limit and 413 over a configured 4 MiB limit.
    • A 5 MiB /allow gets 413.

Test plan

  • Every behaviour change has a test, plus a mutant that the test kills, recorded per task. Examples: the default reverted, the Ranger gate removed, the Helm guard removed, info! turned back into error!, the C8 prefilter removed, and the tag-warning condition inverted.
  • Suites that pass:
    • egret-config (91);
    • egret-policy mechanism_switch (22);
    • egret-perm-compile opa_cache (11), explain_opa, and --lib explain;
    • egret-server opa_surface_mounted (15) and helm_opa_listener (9, including real helm template renders);
    • egret-bin, including opa_start;
    • vitest for the mechanism section and explain;
    • tsc.
  • fmt is clean, and clippy -D warnings is clean on the touched crates.
  • Reviews: a review after each task, and a final whole-branch review (opus) followed by one fix wave. No Critical findings. The C8 change was checked and is not fail-open, and the default-install invariant was verified, including Helm renders for the default, ranger.enabled=true and opa.enabled=false.

Known follow-ups (not in this PR)

  • At N=10 the refresh still takes about 1.04 s. Each rebuild runs load_ep, which reads every grant and rule on the installation.
  • The Helm render tests skip in CI because CI has no helm binary (the guard text tests still run).
  • The trino-config screenshot re-shoot.

Documentation

egret-data/docs#71 covers:

  • the "Trino on OPA" prerequisites and refusal row;
  • the configuration keys;
  • the Kubernetes values and NetworkPolicy;
  • upgrade notes, including the start-up risk for non-Helm installs with Ranger on;
  • the tag-service warning;
  • the shared-tag latency note.

KI-352, KI-353 and KI-354 already exist and are unchanged, per the user's decision.

Checklist

  • Linked to an issue (no tracking issue)
  • Tests added or updated
  • Docs updated in egret-data/docs
  • Commit messages follow Conventional Commits
  • No secrets, tokens or real data added

🤖 Generated with Claude Code

viethqb and others added 11 commits November 8, 2026 14:44
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Extends the T7 M1 rebuild-timing harness with
opa_shared_tag_service_refresh_latency: N compiled profiles on one tag
service, the tag version moved on all of them, the time until the last
is served a snapshot at its new key, plus the pieces of one build.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
stored_overlaps_of_via loaded one unit per profile sharing the tag
service, then dropped every pair but the profile's own. A tag-version
bump over N such profiles loaded N^2 units. The unit ids are now
filtered by the same predicate before any unit is loaded; the pairs
reported are unchanged. Last profile current at N = 10: 4291 ms to
1041 ms p50.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The pair-equality check of the shared-tag-service re-check test compared
two empty lists. A and B now each store one overlapping pair, the check
asserts both are non-empty and runs first, and the filter-removed mutant
fails it. The report states that the load-failure narrowing is untested
and why it is safe, that N also measures installation size, and that the
stale-window formula is approximate.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
governance.opa.enabled now defaults to true. The listener collision checks
apply only while the Ranger surface is on too, since OPA does not start
without it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t on

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
OPA counts as running only with the Ranger surface on: the idle state logs
at info, the engine URL falls back and the listen and engine_url checks are
skipped, and the chart renders no OPA port or rule.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e effective rule

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@viethqb
viethqb merged commit 4414136 into main Nov 8, 2026
9 checks passed
@viethqb
viethqb deleted the feat/opa-default-on branch November 8, 2026 18:59
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.

1 participant