Skip to content

fix(server): repair Orbit binding ID auth and preserve legacy upstreams [SAO-17527] - #273

Merged
josjeon merged 4 commits into
mainfrom
fix/sao-17527-binding-id-auth-context
Oct 1, 2026
Merged

josjeon merged 4 commits into
mainfrom
fix/sao-17527-binding-id-auth-context

Conversation

@josjeon

@josjeon josjeon commented Sep 28, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

SAO-17527 reports 10/10 failures for DELETE /api/v1/control-bindings/{binding_id} in demo-v2-poc. The ID route sent control_bindings.write without target context. Orbit rejected that request with 400, which Agent Control surfaced as 502. GET and PATCH use the same by-ID authorization pattern by source inspection; their failure was not reproduced live for this ticket.

Change

  • For target-aware authorizers, resolve the caller namespace, load the binding within that namespace, then authorize control_bindings.read or control_bindings.write with its stored target. The handler reads or mutates the row in the authorized namespace again.
  • At startup, Agent Control derives Orbit's identity URL from the known management authorization URL and passes it to the generic HTTP provider. Local JWT authorizers also use stored-target authorization.
  • Custom HTTP upstreams with neither an explicit nor a derivable identity URL, and other legacy authorizers, retain their previous single namespace-wide authorization call. AGENT_CONTROL_AUTH_UPSTREAM_IDENTITY_URL is optional; compatible custom upstreams can set it to opt into stored-target authorization. Those deployments do not need a new setting to keep their prior behavior.
  • On the target-aware path, invalid credentials retain 401; missing or cross-namespace IDs and target denials return the binding 404. Legacy provider error behavior is unchanged. Request and response schemas are unchanged; generated TypeScript route comments reflect the provider-specific behavior.

Validation

  • Before the rebase, the full local server suite passed (936 tests); focused auth and control-binding suites passed (193 tests), including GET/PATCH/DELETE compatibility checks for a custom upstream that rejects target context.
  • Local Ruff, server mypy, and DB-free configuration/mock HTTP checks passed. The reviewer follow-up adds GET/PATCH/DELETE regression coverage for an identity/target-authorization namespace mismatch and verifies that the binding remains unchanged.
  • Rebased onto main at a0d2660 (#277). git range-diff confirms all four PR patches are unchanged, and local make prepush passed after the rebase.
  • GitHub Python CI, UI CI, TypeScript SDK CI, server build, title validation, and Codecov patch checks passed on rebased head 5fb016b.
  • The DB-backed endpoint test could not run locally because PostgreSQL and Docker were unavailable. The earlier PR commit was exercised on an isolated GCP DevStack for successful ID operations, missing IDs, and invalid credentials; the rebased commit has not been manually exercised on the shared demo stack.

Rollout and remaining risk

  • Before deploying Agent Control, verify that the target Orbit environment exposes POST /internal/auth/resolve_tenant_context and that its management authorization URL matches the known path. Target-aware ID calls add one identity request before the stored-target authorization request.
  • Monitor by-ID binding responses and upstream authorization errors. Roll back by reverting this PR and redeploying the prior Agent Control version.
  • A same-namespace caller may still infer that an inaccessible ID exists from latency or a transient upstream error. Normal target denials return 404. Targetless list authorization is outside this change.

@codecov

codecov Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@josjeon
josjeon force-pushed the fix/sao-17527-binding-id-auth-context branch from 4c7725d to 39138dd Compare September 30, 2026 16:08
@josjeon josjeon changed the title fix(server): authorize binding ID routes with stored target context [SAO-17527] fix(server): repair Orbit binding ID auth and preserve legacy upstreams [SAO-17527] Sep 30, 2026
@josjeon
josjeon enabled auto-merge (squash) September 30, 2026 19:32
Comment thread server/src/agent_control_server/endpoints/control_bindings.py Outdated
@josjeon
josjeon disabled auto-merge October 1, 2026 16:06
Resolve caller identity before the namespace-scoped binding lookup, then authorize against the stored target. Preserve 401 responses and mask missing or target-denied bindings as 404.

Add provider and endpoint regression coverage and refresh generated TypeScript route descriptions.
@josjeon
josjeon force-pushed the fix/sao-17527-binding-id-auth-context branch from 2edb64d to 5fb016b Compare October 1, 2026 17:37
@josjeon
josjeon enabled auto-merge (squash) October 1, 2026 17:42
@josjeon
josjeon merged commit 06dc211 into main Oct 1, 2026
7 checks passed
@josjeon
josjeon deleted the fix/sao-17527-binding-id-auth-context branch October 1, 2026 17: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.

3 participants