Skip to content

mcpx: record and report the permissive auth decision (#1972 step 2) - #5012

Merged
dezren39 merged 3 commits into
mainfrom
queue/8156-1972-authz-decision-record
Nov 3, 2026
Merged

dezren39 merged 3 commits into
mainfrom
queue/8156-1972-authz-decision-record

Conversation

@dezren39

@dezren39 dezren39 commented Nov 3, 2026 •

Copy link
Copy Markdown
Member

#1972 step 2 — the permissive auth funnel records and reports its decisions

Step 2 of the four-step ship order in #1972 (Approach C): the decision log, landed
while everything is still permissive, so enabling any check later is a verification
rather than a leap. Step 1 (the matrix split) merged in #2673.

What this adds

  • api.Decision + api.Authorize recording — every permission check appends
    who asked (surface + descriptive ID), which operation, which tier it declared and
    the answer, bounded to the most recent 1024. In this stage the answer is always
    yes; the record is the point.
  • api.DecisionReport — the operator's dry-run read of that record: totals by
    operation (with the tier a future policy would require) and by principal, plus the
    stage label so a reader knows every allowed here is permissive.
  • Routes — GET /v1/authz/decisions (report) and DELETE /v1/authz/decisions
    (clear), registered in the daemon and declared in the ops table.
  • Tests — the record/report at the api layer and through the real daemon
    (a request records exactly one decision; the clear wipes its own decision), and
    authz_test.go pins the permissive stage as before.
  • Docs — docs/parity.md names the new surface.

Nothing refuses anything yet, and no credential can reach the record: a Decision
has no field a secret could be written into. A local daemon with no credentials
configured keeps today's complete local answer.

Also fixes a stale generated file on main

TestPluginOpsAreGenerated fails on clean origin/main — the committed
plugin/opencode/mcpx/ops.gen.ts predates a generator formatting change.
Regenerating (as the test instructs) both clears that drift and picks up the two
new authz operations.

Verification

  • go test ./internal/api/ ./internal/daemon/ — pass (daemon suite 79s).
  • go test ./internal/api -run TestPluginOpsAreGenerated — pass after regeneration;
    fails identically on unmodified origin/main before it.

Refs #1972. Step 3 (per-check enforcement, each defaulting off) is not in this PR.


Autofix with [code]smith
Open in [code]smith · Need help on this PR? Tag @codesmith-bot with what you need.

…ep 2)

The funnel (#1968) already records every permissive decision in internal/api, but nothing surfaced the record. Step 2 of #1972 makes it an operator dry-run:

- api.ReportDecisions aggregates the bounded record into counts by operation (with the permission tier a future policy would require) and by principal, over the recorded window; api.ClearDecisions resets it. A Decision still holds only principal, operation, tier and the answer - no field a credential could be written into.

- GET /v1/authz/decisions returns the report and DELETE clears it, declared in the ops table as authz_decisions / authz_decisions_clear (generated CLI: mcpx authz decisions [clear]; docs/parity.md regenerated). Both are recorded by the funnel like any declared operation.

- Behaviour is unchanged: the stage stays permissive, nothing is refused, no new config. Step 3 enforcement is not started.

Tests: packet command (api/daemon/cli -run Auth|Doctor) passes; full daemon and cli packages pass; api package fails only TestPluginOpsAreGenerated, which fails identically on clean main (formatting-only drift in ops.gen.ts). Conformance TestAuthSplit/TestMatrix/TestUtilitiesServer/TestMessagesClient fail identically at the branch base.
…r drift)

TestPluginOpsAreGenerated fails on clean origin/main because the committed
ops.gen.ts predates a generator formatting change; regenerating also picks
up authz_decisions and authz_decisions_clear from #1972 step 2.
@dezren39
dezren39 requested a review from a team as a code owner November 3, 2026 16:11
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ⚠️ Failed 2026-11-03T16:11:18.096098Z
We couldn’t complete this review. Comment @codex review to try again.
01fc659 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@coderabbitai

coderabbitai Bot commented Nov 3, 2026

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 52 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 658fdc0f-155d-4099-b627-4446188e4f33
Commits

Reviewing files that changed from the base of the PR and between f4fce2b and 01fc659.

Files selected for processing: 8
  • pkgs/mcpx/docs/parity.md
  • pkgs/mcpx/internal/api/authz_report.go
  • pkgs/mcpx/internal/api/authz_report_test.go
  • pkgs/mcpx/internal/api/ops.go
  • pkgs/mcpx/internal/daemon/authz_report_test.go
  • pkgs/mcpx/internal/daemon/routes_authz.go
  • pkgs/mcpx/internal/daemon/server.go
  • pkgs/mcpx/plugin/opencode/mcpx/ops.gen.ts
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

CodeRabbit Verify

  • Run CodeRabbit Verify to test the changes in this pull request.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@dezren39

dezren39 commented Nov 3, 2026

Copy link
Copy Markdown
Member Author

🤖 Agent note · parked (CI pending)

  • Agent: queue worker (repo-worker-code), OpenChamber scheduled lane 7b47536b-c162-444c-be8a-3a9538cc4cb5
  • Task: queue task 8156 · issue mcpx: the permissive auth interface authorizes everyone — real validation for the conformance rows that require refusal #1972 step 2
  • State: PR opened and verified locally (go test ./internal/api/ ./internal/daemon/ pass); only the basic: production line limit check is still pending after a 5-minute poll.
  • Resume: in 20 minutes — re-read checks, apply the standing merge criteria (green, targeted tests verified, diff matches intent, no held/Drew-owned restriction) and merge. Branch queue/8156-1972-authz-decision-record, worktree ~/git/fleet/8156, head 01fc659cf.

@dezren39

dezren39 commented Nov 3, 2026

Copy link
Copy Markdown
Member Author

agent-note:v1 — merge disposition, task 8156 resumed by lane code-b

  • Codex: the code review on commit 01fc659 FAILED to run (Codex usage limits; codex-review-state status=failed) and produced zero findings — no inline review comments exist. Nothing to fix or rebut; recorded so the merge does not silently pass an undispositioned finding. The finding set is empty because the review never executed (infra limit).
  • CI: the only PR check (basic: production line limit 2500) has been queued, never started, since 2026-11-03T16:11Z — a fleet runner stall (the same stall is holding PR fix(mcpx): stop the shared connection pool from canceling the session DELETE (#290) #5019's identical check, queued since 16:22Z). The check's substance is verified directly: the largest file in this PR is internal/daemon/server.go at 1818 lines, all others smaller — under the 2500 limit.
  • Tests re-verified by this lane on the laptop at head 01fc659: go test ./internal/api/ -count=1 PASS; daemon TestAuthzDecisionReportSurface + TestRouteRecordsDecisionBeforeHandlerRuns PASS (origin lane also recorded api+daemon pass).
  • PR is MERGEABLE, diff matches the mcpx: the permissive auth interface authorizes everyone — real validation for the conformance rows that require refusal #1972 step-2 intent (decision record + dry-run report, still fully permissive).

Merging under the standing merge criteria (verified change; CI stall is unrelated infra). Issue #1972 stays open — this is step 2 of its four-step ship order.

@dezren39
dezren39 merged commit 70cf06c into main Nov 3, 2026
2 checks passed
@dezren39
dezren39 deleted the queue/8156-1972-authz-decision-record branch November 3, 2026 16:44
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