diff --git a/.github/workflows/ace-editor.lock.yml b/.github/workflows/ace-editor.lock.yml index 2064fd45062..371d60f9ef3 100644 --- a/.github/workflows/ace-editor.lock.yml +++ b/.github/workflows/ace-editor.lock.yml @@ -165,9 +165,9 @@ jobs: const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs'); await main(core, context); - name: Enforce strict mode policy - if: ${{ contains(toJSON(vars), '"GH_AW_POLICY_STRICT":') }} + if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }} run: | - echo "::error::GH_AW_POLICY_STRICT is set but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." + echo "::error::GH_AW_POLICY_STRICT=true but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." exit 1 - name: Restore daily AIC usage cache id: restore-daily-aic-cache diff --git a/.github/workflows/blog-auditor.lock.yml b/.github/workflows/blog-auditor.lock.yml index 5aecf272a27..6ce887e0e69 100644 --- a/.github/workflows/blog-auditor.lock.yml +++ b/.github/workflows/blog-auditor.lock.yml @@ -163,9 +163,9 @@ jobs: const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs'); await main(core, context); - name: Enforce strict mode policy - if: ${{ contains(toJSON(vars), '"GH_AW_POLICY_STRICT":') }} + if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }} run: | - echo "::error::GH_AW_POLICY_STRICT is set but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." + echo "::error::GH_AW_POLICY_STRICT=true but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." exit 1 - name: Restore daily AIC usage cache id: restore-daily-aic-cache diff --git a/.github/workflows/cli-consistency-checker.lock.yml b/.github/workflows/cli-consistency-checker.lock.yml index ad81c26e5a0..17f192a5bba 100644 --- a/.github/workflows/cli-consistency-checker.lock.yml +++ b/.github/workflows/cli-consistency-checker.lock.yml @@ -155,9 +155,9 @@ jobs: const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs'); await main(core, context); - name: Enforce strict mode policy - if: ${{ contains(toJSON(vars), '"GH_AW_POLICY_STRICT":') }} + if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }} run: | - echo "::error::GH_AW_POLICY_STRICT is set but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." + echo "::error::GH_AW_POLICY_STRICT=true but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." exit 1 - name: Restore daily AIC usage cache id: restore-daily-aic-cache diff --git a/.github/workflows/cli-version-checker.lock.yml b/.github/workflows/cli-version-checker.lock.yml index 060fb146e3d..5521b918250 100644 --- a/.github/workflows/cli-version-checker.lock.yml +++ b/.github/workflows/cli-version-checker.lock.yml @@ -160,9 +160,9 @@ jobs: const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs'); await main(core, context); - name: Enforce strict mode policy - if: ${{ contains(toJSON(vars), '"GH_AW_POLICY_STRICT":') }} + if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }} run: | - echo "::error::GH_AW_POLICY_STRICT is set but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." + echo "::error::GH_AW_POLICY_STRICT=true but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." exit 1 - name: Restore daily AIC usage cache id: restore-daily-aic-cache diff --git a/.github/workflows/copilot-pr-merged-report.lock.yml b/.github/workflows/copilot-pr-merged-report.lock.yml index 8b275aab671..1412de095a8 100644 --- a/.github/workflows/copilot-pr-merged-report.lock.yml +++ b/.github/workflows/copilot-pr-merged-report.lock.yml @@ -160,9 +160,9 @@ jobs: const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs'); await main(core, context); - name: Enforce strict mode policy - if: ${{ contains(toJSON(vars), '"GH_AW_POLICY_STRICT":') }} + if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }} run: | - echo "::error::GH_AW_POLICY_STRICT is set but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." + echo "::error::GH_AW_POLICY_STRICT=true but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." exit 1 - name: Restore daily AIC usage cache id: restore-daily-aic-cache diff --git a/.github/workflows/daily-team-evolution-insights.lock.yml b/.github/workflows/daily-team-evolution-insights.lock.yml index 34daf45a20a..4766f5759ee 100644 --- a/.github/workflows/daily-team-evolution-insights.lock.yml +++ b/.github/workflows/daily-team-evolution-insights.lock.yml @@ -161,9 +161,9 @@ jobs: const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs'); await main(core, context); - name: Enforce strict mode policy - if: ${{ contains(toJSON(vars), '"GH_AW_POLICY_STRICT":') }} + if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }} run: | - echo "::error::GH_AW_POLICY_STRICT is set but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." + echo "::error::GH_AW_POLICY_STRICT=true but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." exit 1 - name: Restore daily AIC usage cache id: restore-daily-aic-cache diff --git a/.github/workflows/dev.lock.yml b/.github/workflows/dev.lock.yml index 3364736d814..8212f7b262e 100644 --- a/.github/workflows/dev.lock.yml +++ b/.github/workflows/dev.lock.yml @@ -178,9 +178,9 @@ jobs: const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs'); await main(core, context); - name: Enforce strict mode policy - if: ${{ contains(toJSON(vars), '"GH_AW_POLICY_STRICT":') }} + if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }} run: | - echo "::error::GH_AW_POLICY_STRICT is set but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." + echo "::error::GH_AW_POLICY_STRICT=true but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." exit 1 - name: Restore daily AIC usage cache id: restore-daily-aic-cache diff --git a/.github/workflows/example-permissions-warning.lock.yml b/.github/workflows/example-permissions-warning.lock.yml index 917a60564df..582b40ee80a 100644 --- a/.github/workflows/example-permissions-warning.lock.yml +++ b/.github/workflows/example-permissions-warning.lock.yml @@ -154,9 +154,9 @@ jobs: const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs'); await main(core, context); - name: Enforce strict mode policy - if: ${{ contains(toJSON(vars), '"GH_AW_POLICY_STRICT":') }} + if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }} run: | - echo "::error::GH_AW_POLICY_STRICT is set but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." + echo "::error::GH_AW_POLICY_STRICT=true but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." exit 1 - name: Restore daily AIC usage cache id: restore-daily-aic-cache diff --git a/.github/workflows/gpclean.lock.yml b/.github/workflows/gpclean.lock.yml index 53269f18b23..dd210b0d32a 100644 --- a/.github/workflows/gpclean.lock.yml +++ b/.github/workflows/gpclean.lock.yml @@ -161,9 +161,9 @@ jobs: const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs'); await main(core, context); - name: Enforce strict mode policy - if: ${{ contains(toJSON(vars), '"GH_AW_POLICY_STRICT":') }} + if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }} run: | - echo "::error::GH_AW_POLICY_STRICT is set but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." + echo "::error::GH_AW_POLICY_STRICT=true but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." exit 1 - name: Restore daily AIC usage cache id: restore-daily-aic-cache diff --git a/.github/workflows/mcp-inspector.lock.yml b/.github/workflows/mcp-inspector.lock.yml index 082429d7dfd..ee2e51d5a3c 100644 --- a/.github/workflows/mcp-inspector.lock.yml +++ b/.github/workflows/mcp-inspector.lock.yml @@ -206,9 +206,9 @@ jobs: const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs'); await main(core, context); - name: Enforce strict mode policy - if: ${{ contains(toJSON(vars), '"GH_AW_POLICY_STRICT":') }} + if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }} run: | - echo "::error::GH_AW_POLICY_STRICT is set but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." + echo "::error::GH_AW_POLICY_STRICT=true but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." exit 1 - name: Restore daily AIC usage cache id: restore-daily-aic-cache diff --git a/docs/src/content/docs/reference/permissions.md b/docs/src/content/docs/reference/permissions.md index ffe5c47746e..483041513b8 100644 --- a/docs/src/content/docs/reference/permissions.md +++ b/docs/src/content/docs/reference/permissions.md @@ -24,6 +24,7 @@ Key read permission scopes include: - `contents` (code access) - `issues` (issue management) +- `issue-fields` (org issue field definitions and values — see below) - `pull-requests` (PR management) - `discussions` (discussions and comments) - `actions` (workflow control) @@ -40,6 +41,27 @@ See [GitHub's permissions reference](https://docs.github.com/en/actions/using-jo - **`read-all`**: Read access to all scopes (useful for inspection workflows) - **`{}`**: No permissions (for computation-only workflows) +### Permission: `issue-fields: read` + +The `issue-fields: read` permission grants read access to organization issue field definitions and issue-specific field values. It is required when your workflow uses the GitHub API to: + +- Query org-scoped issue field metadata (e.g., `list_issue_fields`, `list_issue_types`) +- Read issue field values for a specific issue (e.g., `GET /repos/{owner}/{repo}/issues/{issue_number}/issue-field-values`) + +Without this permission, those API calls will return empty results or permission errors even when `issues: read` is present. + +```yaml wrap +# Example: Read issue field definitions and values +permissions: + contents: read + issues: read + issue-fields: read +``` + +> **Least-privilege guidance:** Only request `issue-fields: read` when the workflow needs to discover or read org issue field definitions or values. For workflows that only manage issue text, labels, or comments, `issues: read` or `issues: write` is sufficient. + +See [GitHub's documentation on issue fields](https://docs.github.com/en/rest/orgs/issue-fields) for the REST API reference. + ### GitHub App-Only Permissions Certain permission scopes require [additional authentication](/gh-aw/reference/github-tools/#additional-authentication-for-github-tools). These include: diff --git a/pkg/workflow/dangerous_permissions_validation_test.go b/pkg/workflow/dangerous_permissions_validation_test.go index 80e2a450678..6ffa09b2adf 100644 --- a/pkg/workflow/dangerous_permissions_validation_test.go +++ b/pkg/workflow/dangerous_permissions_validation_test.go @@ -153,7 +153,7 @@ func TestFindWritePermissions(t *testing.T) { { name: "write-all shorthand", permissions: NewPermissionsWriteAll(), - expectedWriteCount: 15, // All GitHub Actions permission scopes except id-token and metadata (which are excluded) + expectedWriteCount: 16, // All GitHub Actions permission scopes except id-token and metadata (which are excluded) expectedScopes: nil, // Don't check specific scopes for shorthand }, { diff --git a/pkg/workflow/permissions.go b/pkg/workflow/permissions.go index 0b6ef5d95be..7191d684892 100644 --- a/pkg/workflow/permissions.go +++ b/pkg/workflow/permissions.go @@ -66,6 +66,7 @@ const ( PermissionDiscussions PermissionScope = "discussions" PermissionIdToken PermissionScope = "id-token" PermissionIssues PermissionScope = "issues" + PermissionIssueFields PermissionScope = "issue-fields" PermissionMetadata PermissionScope = "metadata" PermissionModels PermissionScope = "models" PermissionPackages PermissionScope = "packages" @@ -138,6 +139,7 @@ func GetAllPermissionScopes() []PermissionScope { PermissionDiscussions, PermissionIdToken, PermissionIssues, + PermissionIssueFields, PermissionMetadata, PermissionModels, PermissionPackages, diff --git a/pkg/workflow/permissions_enum_test.go b/pkg/workflow/permissions_enum_test.go index 273beb40ef6..076dcbb55c3 100644 --- a/pkg/workflow/permissions_enum_test.go +++ b/pkg/workflow/permissions_enum_test.go @@ -365,6 +365,7 @@ func TestPermissionsScopeEnumValidation(t *testing.T) { "deployments", "discussions", "id-token", + "issue-fields", "issues", "packages", "pages", diff --git a/pkg/workflow/permissions_operations_test.go b/pkg/workflow/permissions_operations_test.go index 8fdbc3d9601..d88aee29841 100644 --- a/pkg/workflow/permissions_operations_test.go +++ b/pkg/workflow/permissions_operations_test.go @@ -429,6 +429,7 @@ func TestPermissionsMerge(t *testing.T) { PermissionChecks: PermissionRead, PermissionDeployments: PermissionRead, PermissionDiscussions: PermissionRead, + PermissionIssueFields: PermissionRead, PermissionIssues: PermissionRead, PermissionMetadata: PermissionRead, PermissionPackages: PermissionRead, @@ -455,6 +456,7 @@ func TestPermissionsMerge(t *testing.T) { PermissionDeployments: PermissionWrite, PermissionDiscussions: PermissionWrite, PermissionIdToken: PermissionWrite, // id-token supports write + PermissionIssueFields: PermissionWrite, PermissionIssues: PermissionWrite, PermissionMetadata: PermissionWrite, PermissionPackages: PermissionWrite, @@ -479,6 +481,7 @@ func TestPermissionsMerge(t *testing.T) { PermissionChecks: PermissionRead, PermissionDeployments: PermissionRead, PermissionDiscussions: PermissionRead, + PermissionIssueFields: PermissionRead, PermissionIssues: PermissionRead, PermissionMetadata: PermissionRead, PermissionPackages: PermissionRead, @@ -506,6 +509,7 @@ func TestPermissionsMerge(t *testing.T) { PermissionDeployments: PermissionWrite, PermissionDiscussions: PermissionWrite, PermissionIdToken: PermissionWrite, // id-token supports write + PermissionIssueFields: PermissionWrite, PermissionMetadata: PermissionWrite, PermissionPackages: PermissionWrite, PermissionPages: PermissionWrite, diff --git a/pkg/workflow/permissions_scope_validation_test.go b/pkg/workflow/permissions_scope_validation_test.go index 8a70cd4c14f..fce454e21e2 100644 --- a/pkg/workflow/permissions_scope_validation_test.go +++ b/pkg/workflow/permissions_scope_validation_test.go @@ -40,6 +40,14 @@ pull-requests: read`, issues: write`, wantErr: false, }, + { + name: "issue-fields read is a valid scope", + yaml: `permissions: + contents: read + issues: read + issue-fields: read`, + wantErr: false, + }, { name: "typo in scope name suggests correction", yaml: `contnts: read`,