Skip to content

Permissions

The Permissions class controls the access levels for each GITHUB_TOKEN scope. It can be used at the workflow level or on individual jobs.

Each scope can be set to "read", "write", or "none" using the PermissionLevel enum. Only set the scopes you need; unset scopes are omitted from the output.

from ghagen.models.permissions import Permissions
from ghagen.models.common import PermissionLevel
permissions = Permissions(
contents=PermissionLevel.READ,
pull_requests=PermissionLevel.WRITE,
id_token=PermissionLevel.WRITE,
)
ParameterTypeDefaultDescription
actionsPermissionLevel | Raw[str] | NoneNonePermission for the actions scope.
artifact_metadataPermissionLevel | Raw[str] | NoneNonePermission for the artifact-metadata scope. Serialized as artifact-metadata.
attestationsPermissionLevel | Raw[str] | NoneNonePermission for the attestations scope.
checksPermissionLevel | Raw[str] | NoneNonePermission for the checks scope.
contentsPermissionLevel | Raw[str] | NoneNonePermission for the contents scope.
deploymentsPermissionLevel | Raw[str] | NoneNonePermission for the deployments scope.
discussionsPermissionLevel | Raw[str] | NoneNonePermission for the discussions scope.
id_tokenPermissionLevel | Raw[str] | NoneNonePermission for the id-token scope. Serialized as id-token.
issuesPermissionLevel | Raw[str] | NoneNonePermission for the issues scope.
modelsPermissionLevel | Raw[str] | NoneNonePermission for the models scope. GitHub accepts only read or none here.
packagesPermissionLevel | Raw[str] | NoneNonePermission for the packages scope.
pagesPermissionLevel | Raw[str] | NoneNonePermission for the pages scope.
pull_requestsPermissionLevel | Raw[str] | NoneNonePermission for the pull-requests scope. Serialized as pull-requests.
repository_projectsPermissionLevel | Raw[str] | NoneNonePermission for the repository-projects scope. Serialized as repository-projects.
security_eventsPermissionLevel | Raw[str] | NoneNonePermission for the security-events scope. Serialized as security-events.
statusesPermissionLevel | Raw[str] | NoneNonePermission for the statuses scope.

An enum of valid permission access levels.

from ghagen.models.common import PermissionLevel
ValueString
PermissionLevel.READ"read"
PermissionLevel.WRITE"write"
PermissionLevel.NONE"none"

The type of both Workflow.permissions and Job.permissions. The canonical schema gives the two fields one $ref to the same node, so ghagen gives them one alias:

from ghagen import PermissionsValue
PermissionsValue = OrRaw[Permissions | Literal["read-all", "write-all"] | Raw[str]]

That admits:

  • a Permissions object, for fine-grained control;
  • "read-all" or "write-all" — the blanket shorthand, a closed two-member set;
  • a Raw[str] to emit a string the closed set does not contain;
  • a CommentedMap (the OrRaw arm), the standard escape hatch for a hand-assembled mapping with comments attached.

A plain dict[str, str] is not accepted; build a Permissions, or reach for raw() / a CommentedMap if you need something the model cannot express. The accepted and rejected values are pinned for both ports by the job.permissions and workflow.permissions rows of schema/conformance-inputs.yml.

The TypeScript peer is PermissionsValue in models/permissions.ts, exported from the package root.

Anywhere permissions is accepted — on the workflow and on a job alike — you can pass the string shorthand instead of a full Permissions object. It emits as a bare scalar (permissions: read-all), never as a mapping:

from ghagen import Workflow
# Blanket read-only
workflow = Workflow(
name="CI",
permissions="read-all",
# ...
)
# Fine-grained
workflow = Workflow(
name="CI",
permissions=Permissions(contents=PermissionLevel.READ),
# ...
)
# Same union on a job
job = Job(runs_on="ubuntu-latest", permissions="write-all", steps=[...])