docs(actions): document OIDC workload identity (#526)

Document the OpenID Connect tokens that Gitea Actions jobs can request since https://github.com/go-gitea/gitea/pull/39052, so they can sign in to cloud providers without long-lived secrets.

- Add an OpenID Connect page covering how to trust Gitea, request a token and match its claims
- Document the `id-token` permission scope and its maximum
- Translate both for zh-cn and zh-tw, which still listed `id-token` as unsupported

Co-authored-by: silverwind <[email protected]>
Co-authored-by: silverwind <[email protected]>
Reviewed-on: https://gitea.com/gitea/docs/pulls/526
Reviewed-by: silverwind <[email protected]>
Co-authored-by: Max P. <[email protected]>
This commit is contained in:
Max P.
2026-10-18 07:12:16 +00:00
committed by silverwind
co-authored by silverwind silverwind
parent db9e6f9f48
commit 2af7b60fd9
10 changed files with 212 additions and 14 deletions
+1 -1
View File
@@ -85,7 +85,7 @@ Service steps have no section of their own in the job log.
### Job token permissions (`permissions`)
`permissions` and `jobs.<job_id>.permissions` control the `GITEA_TOKEN` permissions, clamped by the repository and owner settings and further restricted for fork pull requests and cross-repository access.
GitHub-only scopes like `statuses`, `checks`, `deployments`, `id-token`, `security-events` and `pages` are not supported, while Gitea adds `code`, `releases`, `wiki` and `projects`.
GitHub-only scopes like `statuses`, `checks`, `deployments`, `security-events` and `pages` are not supported, while Gitea adds `code`, `releases`, `wiki` and `projects`. `id-token` works like on GitHub, see [OpenID Connect](openid-connect.md).
See [Actions job token permissions](token-permissions.md).
### Downloading actions
+60
View File
@@ -0,0 +1,60 @@
---
date: "2026-08-23T00:00:00+00:00"
slug: "openid-connect"
sidebar_position: 40
---
# OpenID Connect
Jobs can request short-lived OpenID Connect (OIDC) tokens to sign in to cloud providers and other services without storing long-lived secrets. The tokens use the GitHub Actions format, so actions like `aws-actions/configure-aws-credentials`, `google-github-actions/auth` and `azure/login` work unchanged.
## Trusting Gitea
Add Gitea as an OIDC identity provider in the service:
- Issuer: `<ROOT_URL>/api/actions/oidc`
- Audience: `<ROOT_URL>/<owner>`, unless the workflow requests another one
Then limit which workflows can sign in with a condition on the [`sub` claim](#claims).
Gitea signs the tokens with a key it creates at `<APP_DATA_PATH>/jwt/actions_oidc.pem`. Instances behind a load balancer must share this file.
## Requesting a token
Grant the `id-token` permission to the workflow or job:
```yaml
permissions:
id-token: write
```
Default permissions never include it, and jobs from fork pull requests never get it. Owners and repositories can disable it with their [maximum token permissions](token-permissions.md#maximum-token-permissions-clamping).
Actions like the ones above request the token themselves. In a script, use `ACTIONS_ID_TOKEN_REQUEST_URL` and `ACTIONS_ID_TOKEN_REQUEST_TOKEN`:
```shell
curl --fail --silent --show-error \
--header "Authorization: Bearer ${ACTIONS_ID_TOKEN_REQUEST_TOKEN}" \
"${ACTIONS_ID_TOKEN_REQUEST_URL}&audience=my-service"
```
The token is in the `value` field of the response and expires after five minutes.
## Claims
The `sub` claim names the owner and repository with their IDs, so a renamed or recreated repository cannot match an existing trust policy:
```text
repo:<owner>@<owner-id>/<repo>@<repo-id>:ref:<ref>
repo:<owner>@<owner-id>/<repo>@<repo-id>:pull_request
```
The `pull_request` event uses the second form, all other events use the first, including `pull_request_target`.
The other claims match GitHub's, like `repository`, `ref`, `sha`, `workflow_ref` and `job_workflow_ref`. The discovery document at `<ROOT_URL>/api/actions/oidc/.well-known/openid-configuration` lists them all.
Differences from GitHub Actions:
- There is no `environment` claim.
- Pull request runs use `refs/pull/<index>/head` and its commit, not the merge ref and merge commit.
- `run_number` counts runs per repository, not per workflow.
+7 -3
View File
@@ -53,13 +53,14 @@ Valid access mode values for each scope are `read`, `write`, and `none`.
- `wiki`
- `projects`
- `packages` (if supported by the target feature)
- `id-token` (`write` allows requesting [OpenID Connect tokens](openid-connect.md), `read` grants nothing)
If you specify both `contents` and a more granular scope (like `code` or `releases`), the granular scope wins for that unit.
### Compatibility notes
Gitea supports a subset of GitHub Actions permission scopes.
GitHub-only scopes such as `statuses`, `checks`, `deployments`, `id-token`, `security-events`, and `pages` are not currently supported by Gitea Actions.
GitHub-only scopes such as `statuses`, `checks`, `deployments`, `security-events`, and `pages` are not currently supported by Gitea Actions.
Gitea also exposes repository-unit scopes that do not exist as separate scopes in GitHub Actions:
@@ -75,15 +76,18 @@ If neither the workflow nor the job defines `permissions:`, Gitea uses the confi
- **Permissive**: read and write permissions for most units in the job's repository (backwards-compatible default).
- **Restricted**: read-only permissions for `code`, `releases`, and `packages` in the job's repository, and no access to other units by default.
Neither mode includes `id-token`.
## Maximum token permissions (clamping)
You can configure a maximum permission per repository unit.
You can configure a maximum permission per repository unit and for `id-token`.
The job's effective permissions are computed as:
`effective = min(requested, maximum)`
This means workflows can reduce permissions for a job, but cannot exceed your configured maximum.
If you don't configure a maximum, the maximum defaults to `write` for all scopes.
Maximums saved before Gitea supported `id-token` deny it until you set it to `write`.
## Where to configure
@@ -97,7 +101,7 @@ Note: Repository-level token permission settings are only shown once **Repositor
## Fork pull requests
For security reasons, workflows triggered by pull requests from forks are always restricted to read-only permissions for repository contents, regardless of workflow `permissions:` or settings.
For security reasons, workflows triggered by pull requests from forks are always restricted to read-only permissions for repository contents, regardless of workflow `permissions:` or settings. They also get no OpenID Connect tokens.
## Cross-repository access
+2 -2
View File
@@ -64,8 +64,8 @@ These are used internally by the runner and actions. They are typically not need
| Name | Description | Example |
|---|---|---|
| `ACTIONS_CACHE_URL` | URL for the actions cache service. | `http://192.168.1.10:8088/` |
| `ACTIONS_ID_TOKEN_REQUEST_TOKEN` | Token for OIDC requests. Only set when configured. | `***` |
| `ACTIONS_ID_TOKEN_REQUEST_URL` | URL to request OIDC tokens. Only set when configured. | `https://gitea.com/login/oauth/access_token` |
| `ACTIONS_ID_TOKEN_REQUEST_TOKEN` | Token for OIDC requests. Only set when `id-token: write` is granted. | `***` |
| `ACTIONS_ID_TOKEN_REQUEST_URL` | URL to request OIDC tokens. Only set when `id-token: write` is granted. | `https://gitea.com/api/actions/oidc/token?` |
| `ACTIONS_RESULTS_URL` | URL for storing artifacts. | `https://gitea.com` |
| `ACTIONS_RUNTIME_TOKEN` | Authentication token for the Actions pipeline API. | `***` |
| `ACTIONS_RUNTIME_URL` | URL for the Gitea Actions pipeline API. | `https://gitea.com/api/actions_pipeline/` |
@@ -88,7 +88,7 @@ Gitea Actions旨在与GitHub Actions兼容,差异如下。
### `permissions`和`jobs.<job_id>.permissions`
`permissions`和`jobs.<job_id>.permissions`控制`GITEA_TOKEN`的权限,该权限受仓库和所有者设置的限制,并在fork拉取请求和跨仓库访问时受到进一步限制。
不支持`statuses`、`checks`、`deployments`、`id-token`、`security-events`和`pages`等GitHub专有的权限范围,而Gitea额外提供了`code`、`releases`、`wiki`和`projects`。
不支持`statuses`、`checks`、`deployments`、`security-events`和`pages`等GitHub专有的权限范围,而Gitea额外提供了`code`、`releases`、`wiki`和`projects`。`id-token`与GitHub相同,请参阅[OpenID Connect](openid-connect.md)。
请参阅[Actions Job令牌权限](token-permissions.md)。
### 下载Actions
@@ -0,0 +1,63 @@
---
date: "2026-08-23T00:00:00+00:00"
slug: "openid-connect"
sidebar_position: 40
---
# OpenID Connect
Job可以请求短期有效的OpenID Connect(OIDC)令牌来登录云服务商和其他服务,无需存储长期有效的密钥。这些令牌采用GitHub Actions的格式,因此`aws-actions/configure-aws-credentials`、`google-github-actions/auth`和`azure/login`等Action无需修改即可使用。
<a id="trusting-gitea"></a>
## 信任Gitea
在服务中将Gitea添加为OIDC身份提供方:
- Issuer:`<ROOT_URL>/api/actions/oidc`
- Audience:`<ROOT_URL>/<owner>`,除非工作流请求了其他值
然后通过[`sub`声明](#claims)上的条件限制哪些工作流可以登录。
Gitea使用其在`<APP_DATA_PATH>/jwt/actions_oidc.pem`创建的密钥签名令牌。负载均衡器后的多个实例必须共享此文件。
<a id="requesting-a-token"></a>
## 请求令牌
为工作流或Job授予`id-token`权限:
```yaml
permissions:
id-token: write
```
默认权限从不包含此权限,来自fork拉取请求的Job也永远无法获得。所有者和仓库可以通过[最大令牌权限](token-permissions.md#maximum-token-permissions-clamping)禁用它。
上述Action会自行请求令牌。在脚本中,请使用`ACTIONS_ID_TOKEN_REQUEST_URL`和`ACTIONS_ID_TOKEN_REQUEST_TOKEN`:
```shell
curl --fail --silent --show-error \
--header "Authorization: Bearer ${ACTIONS_ID_TOKEN_REQUEST_TOKEN}" \
"${ACTIONS_ID_TOKEN_REQUEST_URL}&audience=my-service"
```
令牌位于响应的`value`字段中,五分钟后过期。
<a id="claims"></a>
## 声明
`sub`声明包含所有者和仓库的名称及ID,因此重命名或重新创建的仓库无法匹配已有的信任策略:
```text
repo:<owner>@<owner-id>/<repo>@<repo-id>:ref:<ref>
repo:<owner>@<owner-id>/<repo>@<repo-id>:pull_request
```
`pull_request`事件使用第二种格式,其他所有事件(包括`pull_request_target`)使用第一种。
其他声明与GitHub相同,例如`repository`、`ref`、`sha`、`workflow_ref`和`job_workflow_ref`。位于`<ROOT_URL>/api/actions/oidc/.well-known/openid-configuration`的发现文档列出了所有声明。
与GitHub Actions的区别:
- 没有`environment`声明。
- 拉取请求的运行使用`refs/pull/<index>/head`及其提交,而不是合并引用和合并提交。
- `run_number`按仓库计数,而不是按工作流计数。
@@ -58,6 +58,7 @@ permissions:
- `wiki`
- `projects`
- `packages`(如果目标功能支持)
- `id-token`(`write`允许请求[OpenID Connect令牌](openid-connect.md),`read`不授予任何权限)
如果同时指定了`contents`和更细粒度的权限范围(如`code`或`releases`),则该单元以更细粒度的权限范围为准。
@@ -65,7 +66,7 @@ permissions:
### 兼容性说明
Gitea支持GitHub Actions权限范围的一个子集。
Gitea Actions目前不支持`statuses`、`checks`、`deployments`、`id-token`、`security-events`和`pages`等GitHub专有的权限范围。
Gitea Actions目前不支持`statuses`、`checks`、`deployments`、`security-events`和`pages`等GitHub专有的权限范围。
Gitea还提供了一些仓库单元权限范围,它们在GitHub Actions中不作为独立的权限范围存在:
@@ -82,16 +83,19 @@ Gitea还提供了一些仓库单元权限范围,它们在GitHub Actions中不
- **宽松**:对Job所属仓库的大多数单元拥有读写权限(向后兼容的默认值)。
- **受限**:对Job所属仓库的`code`、`releases`和`packages`拥有只读权限,默认无权访问其他单元。
两种模式都不包含`id-token`。
<a id="maximum-token-permissions-clamping"></a>
## 最大令牌权限(限制)
您可以为每个仓库单元配置最大权限。
您可以为每个仓库单元以及`id-token`配置最大权限。
Job的实际权限按以下方式计算:
`effective = min(requested, maximum)`
这意味着工作流可以降低Job的权限,但不能超过您配置的最大权限。
如果未配置最大权限,则所有权限范围的最大权限默认为`write`。
在Gitea支持`id-token`之前保存的最大权限会拒绝`id-token`,直到您将其设为`write`。
<a id="where-to-configure"></a>
## 配置位置
@@ -107,7 +111,7 @@ Job的实际权限按以下方式计算:
<a id="fork-pull-requests"></a>
## Fork拉取请求
出于安全考虑,由fork拉取请求触发的工作流始终只拥有仓库内容的只读权限,与工作流的`permissions:`或设置无关。
出于安全考虑,由fork拉取请求触发的工作流始终只拥有仓库内容的只读权限,与工作流的`permissions:`或设置无关。这些Job也无法获取OpenID Connect令牌。
<a id="cross-repository-access"></a>
## 跨仓库访问
@@ -88,7 +88,7 @@ Gitea Actions 旨在與 GitHub Actions 相容,差異如下。
### `permissions`和`jobs.<job_id>.permissions`
`permissions` 和 `jobs.<job_id>.permissions` 控制 `GITEA_TOKEN` 的權限,其權限受儲存庫與所有者設定的限制,對於來自 fork 的拉取請求和跨儲存庫存取還會進一步受限。
不支援 `statuses`、`checks`、`deployments`、`id-token`、`security-events` 和 `pages` 等 GitHub 專屬範圍,而 Gitea 另外提供 `code`、`releases`、`wiki` 和 `projects`。
不支援 `statuses`、`checks`、`deployments`、`security-events` 和 `pages` 等 GitHub 專屬範圍,而 Gitea 另外提供 `code`、`releases`、`wiki` 和 `projects`。`id-token` 與 GitHub 相同,請參閱 [OpenID Connect](openid-connect.md)。
請參閱 [Actions Job 令牌權限](token-permissions.md)。
### 下載Actions
@@ -0,0 +1,63 @@
---
date: "2026-08-23T00:00:00+00:00"
slug: "openid-connect"
sidebar_position: 40
---
# OpenID Connect
Job 可以請求短期有效的 OpenID Connect(OIDC)令牌來登入雲端服務供應商和其他服務,不必儲存長期有效的密鑰。這些令牌採用 GitHub Actions 的格式,因此 `aws-actions/configure-aws-credentials`、`google-github-actions/auth` 和 `azure/login` 等 Action 不需修改即可使用。
<a id="trusting-gitea"></a>
## 信任 Gitea
在服務中將 Gitea 新增為 OIDC 身分提供者:
- Issuer:`<ROOT_URL>/api/actions/oidc`
- Audience:`<ROOT_URL>/<owner>`,除非工作流請求了其他值
接著透過 [`sub` 宣告](#claims)上的條件,限制哪些工作流可以登入。
Gitea 使用它在 `<APP_DATA_PATH>/jwt/actions_oidc.pem` 建立的金鑰簽署令牌。位於負載平衡器後方的多個執行個體必須共用此檔案。
<a id="requesting-a-token"></a>
## 請求令牌
為工作流或 Job 授予 `id-token` 權限:
```yaml
permissions:
id-token: write
```
預設權限一律不包含此權限,來自 fork 的拉取請求的 Job 也永遠無法取得。所有者和儲存庫可以透過[最大令牌權限](token-permissions.md#maximum-token-permissions-clamping)停用它。
上述 Action 會自行請求令牌。在指令碼中,請使用 `ACTIONS_ID_TOKEN_REQUEST_URL` 和 `ACTIONS_ID_TOKEN_REQUEST_TOKEN`:
```shell
curl --fail --silent --show-error \
--header "Authorization: Bearer ${ACTIONS_ID_TOKEN_REQUEST_TOKEN}" \
"${ACTIONS_ID_TOKEN_REQUEST_URL}&audience=my-service"
```
令牌位於回應的 `value` 欄位中,五分鐘後過期。
<a id="claims"></a>
## 宣告
`sub` 宣告包含所有者和儲存庫的名稱及 ID,因此重新命名或重新建立的儲存庫無法符合既有的信任政策:
```text
repo:<owner>@<owner-id>/<repo>@<repo-id>:ref:<ref>
repo:<owner>@<owner-id>/<repo>@<repo-id>:pull_request
```
`pull_request` 事件使用第二種格式,其他所有事件(包括 `pull_request_target`)使用第一種。
其他宣告與 GitHub 相同,例如 `repository`、`ref`、`sha`、`workflow_ref` 和 `job_workflow_ref`。位於 `<ROOT_URL>/api/actions/oidc/.well-known/openid-configuration` 的探索文件列出了所有宣告。
與 GitHub Actions 的差異:
- 沒有 `environment` 宣告。
- 拉取請求的執行使用 `refs/pull/<index>/head` 及其提交,而不是合併參考和合併提交。
- `run_number` 依儲存庫計數,而不是依工作流計數。
@@ -58,6 +58,7 @@ permissions:
- `wiki`
- `projects`
- `packages`(若目標功能支援)
- `id-token`(`write` 允許請求 [OpenID Connect 令牌](openid-connect.md),`read` 不授予任何權限)
如果同時指定 `contents` 和更細的範圍(例如 `code` 或 `releases`),該單元以更細的範圍為準。
@@ -65,7 +66,7 @@ permissions:
### 相容性說明
Gitea 支援 GitHub Actions 權限範圍的一個子集。
Gitea Actions 目前不支援 `statuses`、`checks`、`deployments`、`id-token`、`security-events` 和 `pages` 等 GitHub 專屬範圍。
Gitea Actions 目前不支援 `statuses`、`checks`、`deployments`、`security-events` 和 `pages` 等 GitHub 專屬範圍。
Gitea 另外提供一些儲存庫單元範圍,它們在 GitHub Actions 中並不是獨立的範圍:
@@ -82,16 +83,19 @@ Gitea 另外提供一些儲存庫單元範圍,它們在 GitHub Actions 中並
- **Permissive**(寬鬆):對 Job 所屬儲存庫的大多數單元具有讀取和寫入權限(向下相容的預設值)。
- **受限**(Restricted):對 Job 所屬儲存庫的 `code`、`releases` 和 `packages` 具有唯讀權限,預設無法存取其他單元。
兩種模式都不包含 `id-token`。
<a id="maximum-token-permissions-clamping"></a>
## 最大令牌權限(限縮)
您可以為每個儲存庫單元設定最大權限。
您可以為每個儲存庫單元以及 `id-token` 設定最大權限。
Job 的實際權限計算方式如下:
`effective = min(requested, maximum)`
也就是說,工作流可以降低 Job 的權限,但不能超過您所設定的最大值。
如果未設定最大值,所有範圍的最大值預設為 `write`。
在 Gitea 支援 `id-token` 之前儲存的最大值會拒絕 `id-token`,直到您將其設為 `write`。
<a id="where-to-configure"></a>
## 設定位置
@@ -107,7 +111,7 @@ Job 的實際權限計算方式如下:
<a id="fork-pull-requests"></a>
## 來自 fork 的拉取請求
基於安全考量,由來自 fork 的拉取請求觸發的工作流,對儲存庫內容一律只有唯讀權限,不受工作流 `permissions:` 或設定影響。
基於安全考量,由來自 fork 的拉取請求觸發的工作流,對儲存庫內容一律只有唯讀權限,不受工作流 `permissions:` 或設定影響。這些 Job 也無法取得 OpenID Connect 令牌。
<a id="cross-repository-access"></a>
## 跨儲存庫存取