fix(services): allow Write members to manage their own services#437
Open
angel-manuel wants to merge 1 commit into
Open
fix(services): allow Write members to manage their own services#437angel-manuel wants to merge 1 commit into
angel-manuel wants to merge 1 commit into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Service create is gated by WriteAcl, but delete/update/update-status required AdminAcl — so a Write-level member (e.g. an app acting via org-service-key + X-Overslash-As) could create a service instance but got 403 "admin access required" when deleting or editing its own. Lower those three handlers to WriteAcl and enforce a strict per-row ownership check (require_owner_or_admin): a caller may mutate a service it owns at Write level; another identity's service, or an org-level (owner_identity_id IS NULL) service, still requires Admin. This mirrors create_service (org-level create re-checks Admin) and update_template. The check is strict identity equality — deliberately NOT a ceiling/family check — so an agent cannot reach its owner-user's or a sibling agent's services through the API; those stay dashboard-managed. The is_system guard runs before the ownership check, so system services still 400. Adds route tests (services_admin_view.rs) covering own/other/org-level/ system/admin delete and an update-status parity case. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ccba131 to
f5bb8a9
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
create_service(POST /v1/services) is gated byWriteAcl, but the service management paths — delete, update, update-status — requiredAdminAcl. That asymmetry meant a Write-level member (e.g. an app acting through an org-service-key +X-Overslash-Asimpersonating a Write identity) could create a service instance but then hit403 "admin access required"when trying to delete or edit its own service.Fix
Lower
delete_service,update_service, andupdate_service_statustoWriteAcland enforce a strict per-row ownership check (require_owner_or_admin):owner_identity_id IS NULL) service, still requires Admin → otherwise403 "admin access required".This mirrors what
create_servicealready does (org-level creation re-checks Admin) and matches the establishedupdate_templateprecedent (templates.rs).The check is strict identity equality — deliberately NOT a ceiling/family check — so an agent cannot reach its owner-user's or a sibling agent's services through the API (those stay dashboard-managed). The
is_systemguard runs before the ownership check, so system services still return400regardless of ownership.Note on framing
The task referenced
delete_connectionas the model, but that handler actually returns{ "deleted": false }at 200 for a non-owner/non-admin (it uses theis_org_adminflag). This PR instead follows the explicit requirement — a real 403 for non-owned rows — which is exactly the shape ofupdate_template(owner_identity_id != acl.identity_id && access_level < Admin → Forbidden).Tests
New
crates/overslash-api/tests/services_admin_view.rs(seeds rows by direct SQL to controlowner_identity_id/is_system; deletes by UUID path):is_systemservice → 400 (row survives)Verification
cargo check/cargo fmt/cargo clippyclean; vet (agentic) reports no issues.service_instances(14),groups(22 — incl.admin_agent_cannot_delete_owner_user_service_by_namestill 404 by-name),org_acl(9).Backend-only auth change; no new user-facing surface (the dashboard already calls these endpoints and simply stops getting spurious 403s for Write members acting on their own services).
🤖 Generated with Claude Code