Forgeplane permissions, roles, and authorization
To determine whether a principal can perform an action in Forgeplane, evaluate the platform role, organization membership, and team scope together. Authorization is layered: a permission at one layer does not bypass a missing membership, team action, resource check, lifecycle rule, feature gate, or approval policy at another layer.
Use this page to choose a least-privileged role and diagnose an access failure. Use /api/docs on the target coordinator and the Coordinator API reference for declared methods, fields, responses, and resource-access options; use this page for the current permission mapping and server-side authorization. The can-i resource review evaluates only the authenticated principal.
Check access in order
Section titled “Check access in order”When an action is denied, check the boundaries in this order:
- confirm that the principal is authenticated;
- identify the platform role and organization membership;
- confirm team membership and the required team action;
- check resource ownership, lifecycle state, feature gates, and approval policy; and
- use
whoami, a self-subjectcan-iresource review, and the actual operation to confirm authorization; use/api/docson the target coordinator to inspect the declared method, fields, and response options.
A broader platform role does not grant access to an unrelated team resource. Fix the narrowest missing boundary instead of granting a wider role.
Authorization layers
Section titled “Authorization layers”- Platform role grants coarse product permissions to the authenticated principal.
- Organization membership grants an organization role for organization-owned resources.
- Team membership grants team actions for resources scoped to a team.
- Resource and operation checks apply ownership, lifecycle state, feature gates, and approval policy.
When a request is team-scoped, both the platform permission and the required team action must pass.
Platform roles
Section titled “Platform roles”| Role | Current behavior |
|---|---|
admin |
A platform admin principal has core platform access, including identity and system administration and user:manage; plugin execution still requires explicit action assignments and eligible scope. |
maintainer |
Reads and manages delivery resources; can cancel and approve runs, manage assemblies and integrations, read workers and audit data, and manage service accounts. |
operator |
Has maintainer permissions plus destructive run-record deletion through run:delete. |
requester |
Reads delivery resources, creates runs, runs assemblies, and manages only its own profile through profile:manage; it cannot approve, cancel, or administer the platform. |
These summaries are not an exhaustive endpoint matrix. Use /api/docs on the target coordinator and the Coordinator API reference for declared request and response options. The server-side authorization check and the actual operation are authoritative for access.
Choosing a role
Section titled “Choosing a role”- Start automation with
requesterwhen it only needs delivery reads, run creation, assembly execution, and its own profile operations. - Use
maintainerfor an operator who must approve or cancel runs and manage delivery resources. - Reserve
operatorfor controlled workflows that requirerun:delete; deletion is separate from ordinary run operation. - Give every principal only the organization and team scope it needs. A broader platform role does not make unrelated team resources accessible.
User and profile authorization
Section titled “User and profile authorization”User operations use an identity-bound self policy in addition to the platform user-management policy:
user:manageis required to list or create users, update another user (including itsenabledstate), and delete a user. It is currently granted by the platformadminrole.profile:manageallows an authenticated user to read or update only the user resource whose ID matches that principal. A profile update can change the user’s email and name, but not its role or enabled state.profile:managedoes not grant user collection access, access to another user’s profile, or deletion.user:managedoes not bypass the self policy when the target is the current user.
The coordinator rechecks the current principal and target for each operation;
the User API does not rely on a route-level permission shortcut. Missing or
inaccessible named users return 403 Forbidden rather than 404 Not Found.
Disabled users cannot authenticate and have no effective platform
assignments.
User deletion can return 409 Conflict when the target owns a service account
or is the sole owner of an organization or team. Reassign owned service
accounts and transfer ownership before retrying. The administrator invariant
also remains authoritative: disabling, demoting, or deleting the final
effective platform administrator is rejected atomically. An effective
administrator is an enabled User or enabled service account with the built-in
admin role and valid identity/owner state; credential expiry or revocation
does not remove its assignment from this count.
Important permission families
Section titled “Important permission families”Permission names use resource:action. Current delivery authorization includes:
| Area | Permission names |
|---|---|
| Organization and team context | organization:read, organization:write, team:read, team:write |
| Delivery resources | catalog:read, template:read, template:write, project:read, project:write, environment:read, environment:write |
| Workloads | workload:read |
| Runs | run:read, run:create, run:cancel, run:approve, run:delete |
| Assemblies | assembly:read, assembly:write, assembly:run, assembly:approve |
| Drift | drift_monitor:read, drift_monitor:write |
| Registry and connections | registry:read, registry:manage, connection:manage, connection:use, connection:test |
| Operations | Worker, audit, user, settings, service-account, secret, and webhook permissions |
Representative role behavior:
- A requester has organization, workload, run, assembly, template, project, environment, team, registry, catalog, and drift-monitor read access where membership also permits it. It can create runs and run assemblies.
- A maintainer adds resource writes, run cancellation and approval, and assembly write and approval.
- An operator adds
run:delete. - Human platform admins bypass the core platform-permission and team-action checks. Resource lifecycle invariants can still reject an invalid operation.
Plugin action permissions
Section titled “Plugin action permissions”Installing a plugin, administering settings, or holding the platform admin
role does not grant plugin execution. A registered action must have an explicit
assignment to the actual User, service account, or scoped background principal,
and it must fit the installation’s explicitly approved ceiling. Current identity,
membership, ownership, action eligibility and resource scope still apply.
Assignments name one registered action and an exact resource or declared scope selector. They do not cover future actions. New or reintroduced actions start unassigned. Revocation, identity disablement, membership removal or ownership changes can invalidate an assignment; restoring the previous state does not revive a stale binding.
An explicitly approved Organization/descendants assignment requires current Organization membership, not membership in each descendant Team. It can cover a named resource in a current descendant Team even after Team membership is removed. Team, Project, Environment and exact-resource assignments still require their owning-Team eligibility. Removing and rejoining the membership required by an assignment does not revive its stale binding. Team-owned service accounts stay within their owner Team, and background identities stay within their approved selector. This broad Organization scope is deliberate, not an installation default or an administrator execution bypass.
Grant administration uses scoped Organization or Team membership-administration
authority, separately from settings.manage and execution. The canonical
platform-admin administration override remains, but it is not an execution
bypass. Self-assignment requires the same checks as assignment to another
principal. Replacing an installation ceiling requires settings.manage and
does not assign actions to any subject.
A background principal is an approved installation identity with a scope and exact task purposes. It starts with no action assignments and has no public API key or implicit system authority. Child invocation authority can only narrow the root, ancestor and installation ceilings; it cannot substitute the callee’s background permissions.
The dedicated action check evaluates the authenticated caller, not a claimed actor, and is not an admission reservation. New operations and later task phases recheck current authority. An already admitted trusted plugin-data operation may finish after user-permission removal; that exception does not authorize core commands, protected inputs, external effects or commercial finalization.
Use the plugin permission commands
and the running coordinator’s /api/docs for supported interfaces. These core
records do not activate plugin code, provide authenticated host transport,
schedule work, provision accounts or expose a configuration UI.
Run and drift-monitor access
Section titled “Run and drift-monitor access”Unscoped Run reads require run:read, not platform-admin status. Omitting
team_id selects only unscoped Runs; it does not expose Team-owned Runs.
Drift-monitor reads require drift_monitor:read and team.metadata.read.
Creating, updating, or deleting a drift monitor requires drift_monitor:write
and team.metadata.write, with the platform-admin override retained. A Team
viewer or member cannot mutate drift monitors through a platform delivery-write
role alone. These rules apply to both resource reviews and actual operations.
The drift-monitor list and detail pages show Edit and lifecycle actions only
when you can update that monitor. Delete is shown only when you can delete it.
New Monitor appears only when an accessible instance in the current Team
selection has no monitor and passes the create check, including on an empty
monitor list. The new-monitor form excludes instances that already have a
monitor. The database still prevents duplicate monitors during concurrent
creation requests.
Authorization is checked again when you submit the action.
Assembly operation mapping
Section titled “Assembly operation mapping”Assembly authorization uses the canonical assemblies resource, with the owning Team as scope:
| Operation | Permission | Team action |
|---|---|---|
list, get |
assembly:read or workload:read |
team.metadata.read |
create, update, delete |
assembly:write |
team.metadata.write |
run |
assembly:run |
team.metadata.write |
approve |
assembly:approve |
team.metadata.write |
Drafts and publication inherit update; versions and nested Run views inherit get. Cancel and resume through Assembly endpoints inherit run, not direct Run cancellation permission. Thus a requester with Team admin membership can operate an Assembly but cannot cancel through a direct Run endpoint. A requester with only Team member membership cannot run an Assembly. A Team-owned requester service account likewise lacks team.metadata.write.
Missing, inaccessible, and wrong-Team named Assemblies share a generic 404 operation response. An authorized but no-longer-pending Assembly node approval returns 409; public access-review denials remain generic. Current lifecycle and execution constraints still apply, including for platform administrators.
Organization membership
Section titled “Organization membership”Organization membership uses three roles:
| Organization role | Meaning |
|---|---|
owner |
Full organization ownership authority, including owner-only lifecycle operations. |
admin |
Organization administration without owner-only powers. |
member |
Standard access to organization resources, subject to platform permissions and team membership. |
Organization membership is separate from the platform role. For example, organization:write is not enough to administer an organization in which the principal has no qualifying membership.
Team membership
Section titled “Team membership”Team membership uses owner, admin, member, and viewer:
owner: all team actions, including owner management and deletionadmin: metadata, membership, and invitation managementmember: metadata read and secret-adjacent team accessviewer: metadata read only
The corresponding team actions include team.metadata.read, team.metadata.write, team.membership.manage, team.invitation.manage, team.owner.manage, team.secret.read, and team.delete.
When a request includes both a platform permission and a team action, both checks must pass.
Team-owned service accounts
Section titled “Team-owned service accounts”Service accounts are independent Principals with their own platform role, credentials, and enabled/disabled lifecycle. A User owner supplies the ownership relationship used to manage the account; the User’s platform role, membership, or enabled state does not transfer to it. Disabling a User does not disable an independently assigned User-owned service account. Reassign all service accounts owned by a User before deleting that User.
A team-owned service account’s Team assignment applies only to its owner team. Explicit platform-administrator grants in the canonical catalog still apply. Its own platform role maps to a team role for team-scoped checks:
| Service-account role | Team role |
|---|---|
admin |
owner |
maintainer or operator |
admin |
requester |
member |
Managing a Team-owned service account requires the matching service-account
permission plus Team owner, or an explicit platform admin grant. Team
admin membership alone is not enough. A User-owned account requires the
authenticated User owner and the matching service-account permission, without
a platform-admin ownership bypass. Listing or mutating API credentials uses
the parent account’s manage operation.
Use the least-privileged role that covers the automation. Rotating an API key does not change the service account’s role or owner scope. See Service accounts for key ownership and rotation.
Diagnose access
Section titled “Diagnose access”Use the identity and permission endpoints before changing roles:
GET /api/v1/auth/whoamireports the current authenticated identity.POST /api/v1/auth/can-iaccepts a strictresource_attributesreview for the current User or service account. See the request and result contract.- Valid reviews return
200withstatus.allowedandstatus.denied. Both false means an indeterminateevaluation_error, not a definitive denial. 401means authentication is missing or invalid.- On an actual resource operation,
403means the principal is authenticated but an authorization or resource check failed; this is not the review endpoint’s denial status.
A valid API key can still receive 403 when its principal lacks the required scope. Check the organization, team, resource ownership, feature gate, and approval state before granting a broader platform role.
Consult the Coordinator API reference and /api/docs on the target coordinator for the declared request and response options in your release, then treat the actual server response and authorization decision as authoritative.