Resource update: reconcile SpiceDB #project/#owner, but first decide project-move + AuthZ + billing behaviour
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 344
- Forks
- 47
- Avg merge
- 4d 4h
- Merged PRs (30d)
- 26
Description
Background
The UpdateProjectResource RPC updates a resource. Today core/resource Update only writes title/metadata to Postgres. It does not touch SpiceDB. So if a resource's project (#project) or owner (#owner) changes, the SpiceDB relations drift away from Postgres. This is gap (7) of #1661.
What the (now closed) PR did
PR #1686 reworked Update to reconcile those relations:
- load the existing resource first
- resolve a PAT principal to its underlying user
- keep the current owner when the request sends no principal (a title/metadata-only update should not blank the owner)
- rebuild the URN from the target project
- on project change: delete the old
#projecttuple, add the new one - on owner change: delete the old
#ownertuple, add the new one - repository
Updatenow persistsurn/project_id/principal_id/principal_type(and stores NULL, not"", when there is no principal, matchingCreate) - e2e test moves a resource from project A to project B and asserts the
#projectsubject flips to B only
The reconcile logic itself is sound. The deletes are scoped to the one resource's object_id plus the single relation name, so there is no over-delete.
Why we paused it
The update path also runs two checks (in pkg/server/connect_interceptors/authorization.go, the UpdateProjectResource entry) that were never designed for a project move:
-
AuthZ —
IsAuthorized(Object{namespace, resource_id}, update). This only checks theupdatepermission on the resource itself. On a move it does not check any permission on the target project. So a caller who can update a resource could move it into a project (and org) where they have no rights. -
Billing entitlement —
CheckPlanEntitlement(Object{project, request.project_id}). This checks the plan of the project named in the request (the target). For a cross-org move, how usage and entitlements are counted between the source org and the target org is undefined.
Open questions (decide before re-landing the reconcile)
- Should
UpdateProjectResourcebe allowed to change the project at all, or should "move" be a separate, explicit operation? - Same-org move vs different-org move — do we allow both? A different-org move is the bigger one: it changes billing, ownership, and audit ownership.
- AuthZ on a move: which permission(s) should we require on the target project (for example create/update on the destination) on top of
updateon the resource? - Billing on a cross-org move: which org's plan applies, and how is usage/entitlement re-attributed?
- Owner change: when the principal changes, do we need any check on the new owner?
- URN: the URN is built from the project name, so moving projects changes the URN. Confirm downstream consumers handle a URN change.
Scope
This stays part of gap (7) of #1661. The SpiceDB reconcile should land only after the move / AuthZ / billing behaviour above is decided. PR #1686 is closed in favor of this issue; its branch and code can be reused once the behaviour is settled.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at the UpdateProjectResource entry in pkg/server/connect_interceptors/authorization.go and the core/resource Update path; then review closed PR #1686 and its end-to-end move test. Map the existing resource, project, owner, authorization, and entitlement behavior against the open questions. Done means the move, owner, URN, AuthZ, and billing rules are decided clearly enough for the SpiceDB reconciliation to be re-landed.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, postgres
- Domain
- api, authorization, backend, databases, payments
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100