Skip to content

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.

When an action is denied, check the boundaries in this order:

  1. confirm that the principal is authenticated;
  2. identify the platform role and organization membership;
  3. confirm team membership and the required team action;
  4. check resource ownership, lifecycle state, feature gates, and approval policy; and
  5. use whoami, a self-subject can-i resource review, and the actual operation to confirm authorization; use /api/docs on 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.

  1. Platform role grants coarse product permissions to the authenticated principal.
  2. Organization membership grants an organization role for organization-owned resources.
  3. Team membership grants team actions for resources scoped to a team.
  4. 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.

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.

  • Start automation with requester when it only needs delivery reads, run creation, assembly execution, and its own profile operations.
  • Use maintainer for an operator who must approve or cancel runs and manage delivery resources.
  • Reserve operator for controlled workflows that require run: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 operations use an identity-bound self policy in addition to the platform user-management policy:

  • user:manage is required to list or create users, update another user (including its enabled state), and delete a user. It is currently granted by the platform admin role.
  • profile:manage allows 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:manage does not grant user collection access, access to another user’s profile, or deletion. user:manage does 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.

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.

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.

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 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 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 uses owner, admin, member, and viewer:

  • owner: all team actions, including owner management and deletion
  • admin: metadata, membership, and invitation management
  • member: metadata read and secret-adjacent team access
  • viewer: 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.

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.

Use the identity and permission endpoints before changing roles:

  • GET /api/v1/auth/whoami reports the current authenticated identity.
  • POST /api/v1/auth/can-i accepts a strict resource_attributes review for the current User or service account. See the request and result contract.
  • Valid reviews return 200 with status.allowed and status.denied. Both false means an indeterminate evaluation_error, not a definitive denial.
  • 401 means authentication is missing or invalid.
  • On an actual resource operation, 403 means 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.