Permission/resource API rough edges: DeleteProjectResource 500, CreatePermission silent no-op and 500 on short names
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 344
- Forks
- 47
- Avg merge
- 4d 4h
- Merged PRs (30d)
- 26
Description
Summary
While testing permission deletion (PR #1685) end-to-end against a local server (ConnectRPC + SpiceDB), three pre-existing rough edges surfaced in the permission/resource APIs. None are caused by #1685 — they live in CreatePermission and DeleteProjectResource — but they make working with custom permission namespaces awkward and can return a 500 where a clean client error is expected. Filing together for triage.
1. DeleteProjectResource returns 500 for a custom-namespace resource that has no delete verb
A permission namespace created via CreatePermission (e.g. compute/machine) only gets the verbs you define. DeleteProjectResource runs an authorization precheck for the delete permission on the resource's type, so if the namespace never defined a delete verb, the check fails inside SpiceDB and the call 500s.
Repro
CreatePermissionwith keylab.sample.scan(creates namespacelab/samplewith only ascanverb).CreateProjectResourcewith namespacelab/sampleunder some project.DeleteProjectResourcefor that resource.
Actual: 500 internal. Server log:
IsAuthorized.CheckAuthz operation failed ...
error: rpc error: code = FailedPrecondition desc = relation/permission `delete` not found under definition `lab/sample`
method: /raystack.frontier.v1beta1.FrontierService/DeleteProjectResource
Expected: the resource can be deleted (or a clear client error), regardless of which verbs its namespace happens to define.
Why it matters: this collides with the new permission-delete guard, which refuses to delete the last permission of a namespace while relationships of that type still exist and advises "remove the resources first." For a namespace without a delete verb, you can't remove the resource through the API at all — the only way out is direct DB/SpiceDB cleanup.
2. CreatePermission silently no-ops in the core app/* namespaces
Creating a permission whose namespace is one of the built-in app namespaces (e.g. key app.organization.somenewverb) returns 200 with an empty body and creates nothing — those namespaces are filtered out server-side.
Repro
CreatePermissionwith keyapp.organization.zzcustom.
Actual: 200 {}, no permission created, no error.
Expected: either create it, or reject with a clear error explaining that core app namespaces are reserved. A silent success that does nothing is confusing.
3. CreatePermission returns 500 (not 400) when the service or verb is shorter than 3 characters
The service and verb segments of a permission key become SpiceDB relation/definition identifiers, which must match ^[a-z][a-z0-9_]{1,62}[a-z0-9]$ (minimum 3 characters). A shorter segment passes API validation but fails at schema-compile time, returning a 500.
Repro (each 500s)
- key
foo.bar.go(verbgo, 2 chars) - key
zoo.animal.it(verbit, 2 chars) - key
r2.widget.read(servicer2, 2 chars)
For comparison, abc.widget.read and zoo.animal.use (all segments ≥3 chars) succeed.
Actual: 500 internal. Server log:
CreatePermission.AppendSchema operation failed ...
error: ... compile: failed to compile authz schema: ... invalid Relation.Name:
value does not match regex pattern "^[a-z][a-z0-9_]{1,62}[a-z0-9]$"
Expected: validate the key segments at the API and reject with a 400 InvalidArgument describing the constraint, instead of letting it reach SpiceDB and 500.
Found while manually testing PR #1685. The permission-delete behavior in that PR works correctly; these are separate, pre-existing API issues.
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 by tracing the CreatePermission and DeleteProjectResource API handlers and their validation and authorization paths. Reproduce the three cases described in the issue, then add coverage for custom namespaces without a delete verb, reserved app namespaces, and short key segments. Done means these cases either succeed appropriately or return clear client errors instead of silent success or 500 responses.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- api, authorization, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100