DocsCore concepts

Authorization & permissions

Centralized, unit-tested authorization: org roles, project/repo roles, visibility grants, custom roles, teams, and site admins.

Authorization is centralized in packages/permissions, a dependency-free TypeScript package unit-tested independently of the NestJS app. Every controller resolves a permission set through it before performing a mutation or returning a resource — there is no ad hoc "is this user special-cased" branching elsewhere in the codebase.

Organization roles#

RoleORG_VIEWORG_CREATE_PROJECTORG_MANAGE_MEMBERSORG_MANAGE_TEAMSORG_MANAGE_SETTINGSORG_MANAGE_SECRETSORG_VIEW_AUDIT_LOGORG_DELETE
GUEST
MEMBER
ADMIN
OWNER

Project / repository roles#

Repository access is governed by the project role ladder (ProjectRole), since a project's repositories share reviewers and contributors by default:

RoleREPO_READ/CLONEREPO_PUSHCREATE_BRANCHCREATE_PRMERGEMANAGEMANAGE_WEBHOOKSMANAGE_CIMANAGE_COLLABORATORS
GUEST
REPORTER
DEVELOPER
MAINTAINER

Roles are ranked (GUEST < REPORTER < DEVELOPER < MAINTAINER) and a user's effective role on a repository is the highest of: a direct repository-level role, their project-level role, or — critically — an automatic MAINTAINER floor if they hold OWNER or ADMIN at the organization level. Organization admins are never locked out of a repository by an unrelated repository-level grant.

Visibility grants permissions too#

Independent of any role, resolveRepositoryPermissions also grants REPO_READ/REPO_CLONE from visibility alone: PUBLIC repositories grant read to unauthenticated requests, INTERNAL repositories grant read to any authenticated user regardless of organization membership. Role-derived permissions and visibility-derived permissions are unioned, not chosen between — a GUEST on a PUBLIC repository can still read it.

Custom roles#

An organization can define a custom role: an explicit RepoPermission[] set that replaces the ladder position a ProjectRole would otherwise imply for a specific repository grant, rather than adding to it. Every other grant path (project-wide role, team grants, the org admin/owner MAINTAINER floor) still unions in on top of a custom role normally — a custom role narrows or reshapes one specific grant, it doesn't cap what a user can otherwise reach through a different path.

Teams#

A Team groups organization members and can be granted a project or repository role once, applied to every member of the team. Team membership changes take effect immediately for every resource the team has been granted access to — there's no separate propagation step, because permission resolution happens live, at request time, not via a materialized ACL.

Site administrators#

A user with isAdmin: true bypasses every check above entirely: resolveRepositoryPermissions/resolveOrganizationPermissions short-circuit to the full permission set. This is intentionally the only "god mode" bit in the system — it's a single boolean on User, toggled by another site admin under Admin → Users, and every use of it (including simply viewing a private repository as an admin) is available for audit via impersonation logging when acting as another user (see Instance administration).