getsentry / getsentry/sentry

Return org _capabilities for UI permission checks

Open
#121,799 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Feature
Dominant language
Python
Stars
44.8k
Forks
4.9k
Avg merge
21h 23m
Merged PRs (30d)
607

Description

Summary

The frontend recomputes permission decisions (for example project creation) from scopes, org flags, and team roles. That logic drifts from the API. A server-computed _capabilities map on the org payload would let the UI read one field instead of reimplementing access rules.

Current behavior

  • Org serializers expose access as a flat scope list when access=request.access is passed (src/sentry/api/serializers/models/organization.py).
  • They also expose policy flags such as allowMemberProjectCreation (org setting, not "this caller can create").
  • Projects/teams already return computed hasAccess + per-object access.
  • UI still stacks scopes + flags + team admin locally, e.g. static/app/components/projects/canCreateProject.tsx via useCanCreateProject.
  • Project create API rules live separately:
    • Org create: POST scopes project:read|write|admin, then deny when member creation is disabled unless org:write.
    • Team create: POST scopes project:write|admin, with a per-team team:admin escape when member creation is disabled.

Gap

  • UI and API permission models already diverge (scopes checked, org:write bypass, team-admin path).
  • Every new org-level action risks another client-side recreation of server rules.
  • access is the wrong place to extend: it is a public scope array, not a capability map.

Related work this would improve

Proposed shape (discussion)

Add a private sibling field on the detailed/org session serializer (not inside access, not on the user endpoint):

{
  "access": ["org:read", "project:read", "team:read"],
  "allowMemberProjectCreation": true,
  "_capabilities": {
    "canCreateProject": true
  }
}

Notes:

  • Leading underscore marks it as UI/internal; also exclude from public OpenAPI if present on a documented endpoint.
  • Compute with the same rules as the create endpoints so UI gating cannot drift.
  • Start with canCreateProject; grow the map only when another UI gate is re-encoding server policy.
  • Prefer the detailed org bootstrap payload the frontend already stores over the bare public summary.

Requested by David Cramer.

--

View Junior Session [Sentry]

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with src/sentry/api/serializers/models/organization.py and static/app/components/projects/canCreateProject.tsx, including useCanCreateProject. Compare the serializer's detailed org payload with the org and team project-create rules, then add the proposed _capabilities.canCreateProject value to the detailed bootstrap response so the UI can use it without recomputing permissions.

Written by the indexing model from the issue text.

Assessment

Tech stack
python, typescript
Domain
api, backend-api-design, frontend
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.