Skip to content

Resource update: reconcile SpiceDB #project/#owner, but first decide project-move + AuthZ + billing behaviour #1703

@whoAbhishekSah

Description

@whoAbhishekSah

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 #project tuple, add the new one
  • on owner change: delete the old #owner tuple, add the new one
  • repository Update now persists urn/project_id/principal_id/principal_type (and stores NULL, not "", when there is no principal, matching Create)
  • e2e test moves a resource from project A to project B and asserts the #project subject 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:

  1. AuthZIsAuthorized(Object{namespace, resource_id}, update). This only checks the update permission 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.

  2. Billing entitlementCheckPlanEntitlement(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 UpdateProjectResource be 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 update on 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions