Skip to main content

GraphQL Permission Reference

This page maps every operation in the Massdriver GraphQL API to the ABAC permission(s) it requires. Use it when authoring policies for groups, debugging forbidden errors, or planning the minimum permission set for a service account.

How to read this table​

  • Operation — the GraphQL operation name (camelCase, as it appears in the schema).
  • Type — Query, Mutation, or Subscription.
  • Required permission(s) — every ABAC action the resolver checks. When more than one is listed, all are required (sequential AND). Operations that read attributes through filtered list queries instead of explicit can_i? checks are noted as visibility-filtered.
  • Notes — non-obvious behavior: which entity the permission is checked against, conditional permissions, and lifecycle constraints.

If you're building a least-privilege policy, scan the table for the operations the principal needs and assemble the union of required permissions. List queries (projects, instances, resources, etc.) are visibility-filtered: a caller only sees what their group policies and grants make visible — there's no explicit list permission to grant.

organization:manage is a one-level umbrella: a single policy granting organization:manage on a custom group satisfies any organization:manageServiceAccounts, organization:manageGroups, organization:manageBilling, organization:manageIntegrations, organization:manageCustomAttributes, organization:manageResourceTypes, or organization:manageProfile query below. Grant the umbrella when you want full org-level administrative authority on a custom group; grant a single sub-action when you want to scope authority to one capability.


Project​

OperationTypeRequired permission(s)Notes
projectsQueryvisibility-filteredReturns only projects the caller has project:view on.
projectQueryproject:view
createProjectMutationproject:createChecked against the proposed effective attributes, including md-project (the project's local identifier).
cloneProjectMutationproject:view, project:createView on source, then create on the proposed clone.
updateProjectMutationproject:update
deleteProjectMutationproject:deleteProject must have no environments, components, or instances.
addComponentMutationproject:designAlso requires a repo grant on the bundle covering the destination project (view + grant gate).
updateComponentMutationproject:design
removeComponentMutationproject:designComponent must have no provisioned instances.
linkComponentsMutationproject:design
unlinkComponentsMutationproject:design
setComponentPositionMutationproject:design
componentQueryproject:viewLoaded via parent project.

Environment​

OperationTypeRequired permission(s)Notes
environmentsQueryvisibility-filtered
environmentQueryproject:view
compareEnvironmentsQueryproject:view (both source and target)
createEnvironmentMutationproject:view, environment:createView the parent project, then environment:create on the proposed environment (md-environment is the new env's identifier).
forkEnvironmentMutationproject:view, environment:createSame shape as createEnvironment.
updateEnvironmentMutationenvironment:update
deleteEnvironmentMutationenvironment:deleteEnvironment must have no provisioned instances.
setEnvironmentDefaultMutationenvironment:configure, resource:viewConfigure the env, view the resource being defaulted in. Also requires a resource grant covering the destination environment.
removeEnvironmentDefaultMutationenvironment:configure

Instance​

Deployments are an action on an instance — createDeployment, planDeployment, proposeDeployment, approveDeployment, rejectDeployment, and abortDeployment are listed here. The two listing queries (deployments, deployment) are in the Deployment section below.

OperationTypeRequired permission(s)Notes
instancesQueryvisibility-filtered
instanceQueryproject:view
paramDimensionsQueryvisibility-filteredAggregates over instances the caller can see.
updateInstanceMutationinstance:configureSets version constraints, release strategy.
setInstanceSecretMutationinstance:configure
removeInstanceSecretMutationinstance:configure
setRemoteReferenceMutationinstance:configure, resource:viewConfigure the destination instance, view the resource being wired in. Also requires a resource grant covering the instance's environment.
removeRemoteReferenceMutationinstance:configure
copyInstanceMutationproject:view, instance:configureView on source instance, configure on destination.
orphanInstanceMutationinstance:decommissionBreak-glass reset to INITIALIZED. Clears state locks, bulk-aborts in-flight deployments, and (with deleteState: true) deletes the remote Terraform/OpenTofu state files.
createDeploymentMutationinstance:deploy, instance:plan, or instance:decommissionPermission depends on input.action: PROVISION → instance:deploy, PLAN → instance:plan, DECOMMISSION → instance:decommission.
planDeploymentMutationinstance:planRe-runs a PLAN against a source deployment's params on the same instance. Source may be in any status.
proposeDeploymentMutationinstance:proposeOnly PROVISION and DECOMMISSION are proposable.
approveDeploymentMutationinstance:deploy
rejectDeploymentMutationinstance:deploySame permission as approve — both close out a proposal.
abortDeploymentMutationinstance:deploy, instance:plan, or instance:decommissionPermission mirrors the deployment's original action: PROVISION → instance:deploy, PLAN → instance:plan, DECOMMISSION → instance:decommission. Only PENDING, APPROVED, or RUNNING deployments are abortable — use rejectDeployment to discard a PROPOSED deployment.

Deployment​

OperationTypeRequired permission(s)Notes
deploymentsQueryvisibility-filtered
deploymentQueryproject:view
compareDeploymentsQueryproject:view (both deployments' projects)Source and target need not be on the same instance.

Instance Alarm​

OperationTypeRequired permission(s)Notes
instanceAlarmsQueryvisibility-filtered
instanceAlarmQueryproject:view
createInstanceAlarmMutationenvironment:updateAlarms attach to an instance but the gate is on the surrounding environment. A deployment subject that owns the underlying instance is also allowed.
updateInstanceAlarmMutationenvironment:updateA deployment subject that owns the underlying instance is also allowed.
deleteInstanceAlarmMutationenvironment:updateA deployment subject that owns the underlying instance is also allowed.

Resource​

OperationTypeRequired permission(s)Notes
resourcesQueryvisibility-filteredHonors group policies on resource:view plus project cascade plus grants.
resourceQueryresource:view
createResourceMutationresource:importImported resource only; provisioned resources are emitted by deployments.
updateResourceMutationresource:updateImported resource only.
deleteResourceMutationresource:deleteImported resource only.
exportResourceMutationresource:exportReturns the unmasked sensitive payload; recorded in the audit log.

Resource Type​

OperationTypeRequired permission(s)Notes
resourceTypesQueryno explicit gateAvailable to any authenticated member.
resourceTypeQueryno explicit gate
publishResourceTypeMutationorganization:manageResourceTypesCovered by the organization:manage umbrella. Deprecated bridge from V0 publishArtifactDefinition.
deleteResourceTypeMutationorganization:manageResourceTypesCovered by the organization:manage umbrella. Deprecated bridge from V0 deleteArtifactDefinition.

OCI Repo / Bundle​

OperationTypeRequired permission(s)Notes
ociReposQueryvisibility-filteredUnion of repo:view policies and matching grants.
ociRepoQueryrepo:view
bundlesQueryvisibility-filtered
bundleQueryrepo:view
createOciRepoMutationrepo:createChecked against the proposed OCI repo's attributes (including md-repo).
updateOciRepoMutationrepo:update
deleteOciRepoMutationrepo:deleteRepo must have no published bundle versions.

Grant​

OperationTypeRequired permission(s)Notes
createRepoGrantMutationrepo:grantOn the source repo.
createResourceGrantMutationresource:grantOn the source resource.
deleteGrantMutationrepo:grant or resource:grantDispatch on grant kind: repo:grant for repo-source grants, resource:grant for resource-source grants.

There is no updateGrant — grants are immutable; delete and re-create to change recipient_conditions or action.

Group​

OperationTypeRequired permission(s)Notes
groupsQueryvisibility-filtered
groupQuerygroup:view
createGroupMutationorganization:manageGroupsCovered by the organization:manage umbrella. Editing an existing group's membership or policies is gated separately by group:manage on that group.
updateGroupMutationgroup:manage
deleteGroupMutationgroup:manage
addAccountToGroupMutationgroup:manage
deleteGroupMemberMutationgroup:manage
addServiceAccountToGroupMutationgroup:manage
removeServiceAccountFromGroupMutationgroup:manage
deleteGroupInvitationMutationgroup:manage

Policy​

OperationTypeRequired permission(s)Notes
policyEntitiesQueryno explicit gateCatalog of entity types that can carry policies.
policyActionsQueryno explicit gateCatalog of available actions.
evaluatePolicyQueryno explicit gateEvaluation runs against the caller's own effective permissions.
evaluatePoliciesQueryno explicit gateBatched form of evaluatePolicy.
explainPolicyQueryno explicit gateRenders a policy spec (same shape as createGroupPolicy input) as plain-English sentences. Open to every org member; does not require the policy to exist.
createGroupPolicyMutationgroup:managePolicies attach to groups.
updatePolicyMutationgroup:manage
deletePolicyMutationgroup:manage

Custom Attribute​

OperationTypeRequired permission(s)Notes
customAttributeSchemaQueryno explicit gateSchema is org-public.
customAttributeValuesQueryno explicit gate
createCustomAttributeMutationorganization:manageCustomAttributesCovered by the organization:manage umbrella.
updateCustomAttributeMutationorganization:manageCustomAttributesCovered by the organization:manage umbrella.
deleteCustomAttributeMutationorganization:manageCustomAttributesCovered by the organization:manage umbrella.

Organization​

OperationTypeRequired permission(s)Notes
organizationQueryno explicit gatePublic profile fields (name, logo, identifier) are open to every org member. Sensitive subfields gate individually: members requires organization:manageProfile, billing requires organization:manageBilling, customAttributes requires organization:manageCustomAttributes. Each resolves to null with a top-level FORBIDDEN error when the caller lacks the sub-action. All three are covered by the organization:manage umbrella.
createOrganizationMutationauthenticated onlyCaller becomes the org's first owner; no ABAC permission since the org doesn't exist yet.
updateOrganizationMutationorganization:manageProfileCovered by the organization:manage umbrella.
setOrganizationLogoMutationorganization:manageProfileCovered by the organization:manage umbrella.
removeOrganizationLogoMutationorganization:manageProfileCovered by the organization:manage umbrella.
deleteOrganizationMemberMutationorganization:manageProfileCovered by the organization:manage umbrella.

Service Account​

OperationTypeRequired permission(s)Notes
serviceAccountsQueryorganization:manageServiceAccountsCovered by the organization:manage umbrella.
serviceAccountQueryorganization:manageServiceAccountsCovered by the organization:manage umbrella.
createServiceAccountMutationorganization:manageServiceAccountsCovered by the organization:manage umbrella.
updateServiceAccountMutationorganization:manageServiceAccountsCovered by the organization:manage umbrella.
deleteServiceAccountMutationorganization:manageServiceAccountsCovered by the organization:manage umbrella.

Access Token​

OperationTypeRequired permission(s)Notes
accessTokensQueryno explicit gateOpen to every org member; only returns your own tokens — admins cannot list other principals' tokens.
createAccessTokenMutationno explicit gateOpen to every org member; issues a token for the calling subject.
revokeAccessTokenMutationowner-onlyOwner-scoped: only the token's owning subject can revoke; admins cannot revoke another user's personal tokens.

Integration​

OperationTypeRequired permission(s)Notes
integrationsQueryorganization:manageIntegrationsCovered by the organization:manage umbrella.
integrationQueryorganization:manageIntegrationsCovered by the organization:manage umbrella.
integrationTypesQueryno explicit gate
createIntegrationMutationorganization:manageIntegrationsCovered by the organization:manage umbrella.
enableIntegrationMutationorganization:manageIntegrationsCovered by the organization:manage umbrella.
disableIntegrationMutationorganization:manageIntegrationsCovered by the organization:manage umbrella.
deleteIntegrationMutationorganization:manageIntegrationsCovered by the organization:manage umbrella.

Audit Log​

OperationTypeRequired permission(s)Notes
auditLogsQueryproject-scoped rows: no explicit gate; org-level rows: organization:manageProject-scoped audit rows cascade from project:view — a caller sees the entries on every project they can view. Org-level rows (billing, integrations, service accounts, profile changes, etc.) are only included when the caller holds the organization:manage umbrella.
auditLogQueryproject-scoped: no explicit gate; org-level: organization:manageSame split as the list query. Project-scoped entries are reachable through project:view on the entry's project; org-level entries require the umbrella.
auditLogEventTypesQueryno explicit gateCatalog query.

Event Catalog​

OperationTypeRequired permission(s)Notes
eventTypesQueryno explicit gateStatic catalog of event identifiers.

Subscriptions​

OperationTypeRequired permission(s)Notes
organizationEventsSubscriptionno explicit gateOpen to every org member.
projectEventsSubscriptionproject:view
environmentEventsSubscriptionproject:viewInherits the surrounding project's view permission.
instanceEventsSubscriptionproject:view
deploymentEventsSubscriptionproject:view
deploymentLogsSubscriptionproject:viewStreams log lines for a single deployment.

Viewer (Self-context)​

OperationTypeRequired permission(s)Notes
viewerQueryauthenticated onlyReturns the current account or service account. No ABAC check.
acceptGroupInviteMutationinvitation-scopedCaller must be the invite's recipient.
setAccountAvatarMutationself-onlyEdits your own profile.
removeAccountAvatarMutationself-only

Server​

OperationTypeRequired permission(s)Notes
serverQueryunauthenticatedPublic endpoint exposing build/version metadata.

Visibility filtering, in detail​

A visibility-filtered list query is not gated by a single ABAC permission. Instead, the resolver folds in the caller's group policies and any matching grants when building its query, and the result set is whatever the caller can already see through other permissions:

  • projects returns the union of projects matched by the caller's project:view policies.
  • ociRepos returns repos matched by repo:view policies plus repos with grants whose recipient_conditions match a project the caller has project:view on.
  • resources returns resources matched by resource:view policies plus the project cascade for provisioned resources, plus grants.

The single-entity counterpart (project, ociRepo, resource) explicitly checks the corresponding :view permission and returns not_found to obscure existence on denial.

Conventions​

  • forbidden is masked as not_found for read paths that need to obscure existence (e.g., project, environment). Mutations return an explicit forbidden error.
  • Proposed-attribute checks apply to create* mutations: the resolver synthesizes the would-be entity's effective attributes (cascaded parent attrs + the entity's own md-id and local identifier) and checks ABAC against that map. This lets policies gate creation by name (md-environment: [dev, staging, prod]).
  • Built-in admin group has full access. Members of the built-in organization.admin group pass every gate on this page. The built-in admin and viewer groups are fixed — you can't author policies on them, rename them, or delete them. Use a custom group for everything else.

See also​