This action requests a temporary token from the Permissionizer App.
The token can be used in places where
GITHUB_TOKEN
or a
Personal Access Token (PAT)
would normally be used to perform actions on a different repository.
The Permissionizer App must be installed in the target repository, which must define a policy allowing access from the repository requesting the token (see Zero Trust Policy).
Name | Required | Description |
---|---|---|
target-repository |
required | The repository (or repositories) for which the token is to be requested, in the format owner/repo . Multiple values can be provided, separated by commas or newlines. |
permissions |
required | The permissions that should be assigned to the token when it is issued. For available scopes and details, refer to the GitHub documentation. |
permissionizer-server |
optional | URL of permissionizer-server for self-hosted deployments. Default: https://permissionizer.app (free cloud version, subject to the rate limit of 10 tokens per minute) |
Before requesting a token, a repository must define a policy that allows access
from the repository requesting the token. The policy is defined in the
.github/permissionizer.yaml
file in the root of your repository, for example:
self: permissionizer/permissionizer-server
allow:
- repository: permissionizer/request-token
permissions:
contents: read
issues: write
After a policy is defined, the requesting repository
permissionizer/request-token
can request the token from a GitHub Actions
workflow. Only permissions allowed in the policy can be requested.
steps:
- id: request-token
uses: permissionizer/request-token@v1
with:
target-repository: permissionizer/permissionizer-server
# see all available permissions
# https://docs.github.com/en/actions/security-for-github-actions/security-guides/automatic-token-authentication#permissions-for-the-github_token
permissions: |
contents: read
issues: write
with this token, the workflow can now clone the
permissionizer/permissionizer-server
repository and create an issue in it.
- uses: actions/checkout@v4
with:
repository: permissionizer/permissionizer-server
token: ${{ steps.request-token.outputs.token }}
- name: Create new issue in permissionizer-server
uses: actions/github-script@v7
with:
github-token: ${{ steps.request-token.outputs.token }}
script: |
await github.rest.issues.create({
owner: 'permissionizer',
repo: 'permissionizer-server',
title: 'Cross-repository automation with permissionizer/request-token',
body: `π This issue was created by `permissionizer/request-token` β showing just how simple secure cross-repo workflows can be!`
});
By default, any task performed using
GITHUB_TOKEN
will not trigger most workflows, including those with push
or
pull_request
triggers.
This is a GitHub restriction designed to prevent infinite automation loops.
However, by requesting a token via the Permissionizer App, you can bypass this limitation even within the same repository β securely and with explicit policy control.
This is especially useful for actions that make automated commits or pull requests and expect follow-up workflows to run:
- Git Auto Commit
- Dependabot Auto Merge
- GitHub Activity in readme
- Auto Update
- GitHub Prettier Action
- Super-Linter
- GitHub Actions Version Updater
- Homebrew bump formula
- Update Gradle Wrapper Action
- GitHub cherry pick action
or any other action that relies on push
events to trigger downstream workflows
after making changes.
To enable this behavior, simply request a token for the current repository
by setting target-repository: ${{ github.repository }}
.
Even in this case, the target repository must define a policy with explicitly
allowed permissions β ensuring safe, auditable access without unintended
privilege escalation.
Policy example:
self: permissionizer/request-token
allow:
- repository: permissionizer/request-token
permissions:
contents: read
pull-requests: write
Workflow:
jobs:
update-gradle-wrapper:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@v4
- id: request-token
uses: permissionizer/request-token@v1
with:
target-repository: ${{ github.repository }}
permissions: |
contents: read
pull-requests: write
- uses: gradle-update/update-gradle-wrapper-action@v2
with:
repo-token: ${{ steps.request-token.outputs.token }}
labels: dependencies
When requesting a token for multiple repositories, a policy must be defined inside each of the target repositories, allowing all the requested permissions.
For example:
steps:
- id: request-token
uses: permissionizer/request-token@v1
with:
target-repository: |
permissionizer/permissionizer-server
permissionizer/request-token
permissions: |
contents: read
issues: write
requires the following policy in both permissionizer/permissionizer-server
and
permissionizer/request-token
:
# .github/permissionizer.yaml in permissionizer/permissionizer-server
self: permissionizer/permissionizer-server
allow:
- repository: permissionizer/permissionizer-server
permissions:
contents: read
issues: write
# .github/permissionizer.yaml in permissionizer/request-token
self: permissionizer/request-token
allow:
- repository: permissionizer/permissionizer-server
permissions:
contents: read
issues: write
After installing Permissionizer App into your repository, you need to
define a policy that allows the access from the repository requesting the token.
The policy is defined in the .github/permissionizer.yml
file in the root of
your repository.
Here is an example policy that allows access to the
permissionizer/request-token
repository:
# Current repository to make sure the policy isn't automatically applied to forks
self: permissionizer/request-token
allow:
# (required)
# Repository requesting the token
- repository: permissionizer/permissionizer-server
# (required)
# Permissions that can be requested by 'permissionizer/permissionizer-server'
# Only permissions listed here are allowed to be requested, except 'metadata: read', which is added
# automatically if any other permission is defined.
# Requestor can always request less permissions or lower access than allowed
# (e.g. `issues: read` even if `contents: write`, `issues: write` are allowed)
permissions:
contents: read
issues: write
# (optional)
# Restricts requesting token to specific branches of the requesting repository
# Uses GitHub format of `ref` (e.g. `refs/heads/main`, `refs/tags/v1.0.0`, `refs/tags/v*`)
ref: refs/heads/main
# (optional)
# Restricts requesting token only from a specific workflow of the requesting repository
workflow_ref: .github/workflows/release.yaml
following this policy, only the permissionizer/permissionizer-server
repository can request a token with access to the permissionizer/request-token
repository. This token will only have issues: write
and metadata: read
(added automatically) permissions.
To harden the security, the token can only be requested from the main
branch,
making sure that the repository cannot be accessed from the unreviewed branches
or Pull Requests. Additionally, the token can only be requested from the
release.yaml
workflow, making sure that the token cannot be requested from any
other workflow.
Multiple policies can be defined in the .github/permissionizer.yml
file,
including multiple policies for the same repository. The policies are evaluated
in the order they are defined, returning the token with permissions of the first
allowed policy.
For example:
self: permissionizer/request-token
allow:
- repository: permissionizer/permissionizer-server
permissions:
contents: read
- repository: permissionizer/permissionizer-server
permissions:
contents: write
ref: refs/heads/main
the requesting repository can request a token with contents: read
from any
branch, but can only request a token with contents: write
from the main
branch.