From e825f6e1cbb7f2232b9326c486c8c69e866be023 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 19 Feb 2026 00:23:32 +0000 Subject: [PATCH 1/4] Initial plan From 3c5e9c57221ef19891db375221a17e64c36508c4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 19 Feb 2026 00:36:22 +0000 Subject: [PATCH 2/4] fix(permissions): reject invalid id-token: read permission in schema validation The id-token permission only supports "write" and "none" values, not "read". This is because id-token is used for OIDC token requests, which either allows requesting tokens (write) or doesn't (none) - there is no read-only mode. Changes: - Updated main_workflow_schema.json to only allow "write" and "none" for id-token - Updated github-workflow.json to use explicit enum instead of permissions-level ref - Added regression tests for id-token permission validation Co-authored-by: eaftan <4733401+eaftan@users.noreply.github.com> --- pkg/parser/schema_test.go | 33 ++++++++++++++++++++ pkg/parser/schemas/main_workflow_schema.json | 4 +-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/pkg/parser/schema_test.go b/pkg/parser/schema_test.go index 5bdc9eab3b3..240ccaefa63 100644 --- a/pkg/parser/schema_test.go +++ b/pkg/parser/schema_test.go @@ -1412,6 +1412,39 @@ func TestValidateMainWorkflowFrontmatterWithSchema(t *testing.T) { }, wantErr: false, }, + // id-token permission validation - id-token only supports "write" and "none", not "read" + // See: https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs#defining-access-for-the-github_token-scopes + { + name: "invalid: id-token: read is not allowed (only write and none)", + frontmatter: map[string]any{ + "on": "workflow_dispatch", + "permissions": map[string]any{ + "id-token": "read", + }, + }, + wantErr: true, + errContains: "id-token", + }, + { + name: "valid: id-token: write is allowed", + frontmatter: map[string]any{ + "on": "workflow_dispatch", + "permissions": map[string]any{ + "id-token": "write", + }, + }, + wantErr: false, + }, + { + name: "valid: id-token: none is allowed", + frontmatter: map[string]any{ + "on": "workflow_dispatch", + "permissions": map[string]any{ + "id-token": "none", + }, + }, + wantErr: false, + }, } for _, tt := range tests { diff --git a/pkg/parser/schemas/main_workflow_schema.json b/pkg/parser/schemas/main_workflow_schema.json index c2f6168f017..3f50865abbb 100644 --- a/pkg/parser/schemas/main_workflow_schema.json +++ b/pkg/parser/schemas/main_workflow_schema.json @@ -1534,8 +1534,8 @@ }, "id-token": { "type": "string", - "enum": ["read", "write", "none"], - "description": "Permission level for OIDC token requests (read/write/none). Allows workflows to request JWT tokens for cloud provider authentication." + "enum": ["write", "none"], + "description": "Permission level for OIDC token requests (write/none only - read is not supported). Allows workflows to request JWT tokens for cloud provider authentication." }, "issues": { "type": "string", From 91b8c0d546109c7d79ec25e9f3f93f90ad4963fe Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 19 Feb 2026 00:37:05 +0000 Subject: [PATCH 3/4] fix(permissions): also update github-workflow.json schema for id-token The github-workflow.json schema is the secondary schema used for GitHub Actions YAML validation. It also needs to be updated to only allow "write" and "none" for the id-token permission. Co-authored-by: eaftan <4733401+eaftan@users.noreply.github.com> --- pkg/workflow/schemas/github-workflow.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/workflow/schemas/github-workflow.json b/pkg/workflow/schemas/github-workflow.json index 4587e33ccad..f43bac7de3d 100644 --- a/pkg/workflow/schemas/github-workflow.json +++ b/pkg/workflow/schemas/github-workflow.json @@ -181,7 +181,8 @@ "$ref": "#/definitions/permissions-level" }, "id-token": { - "$ref": "#/definitions/permissions-level" + "type": "string", + "enum": ["write", "none"] }, "issues": { "$ref": "#/definitions/permissions-level" From 258f758fc776e4deceebd5141fa6804802bb0f01 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 19 Feb 2026 00:39:40 +0000 Subject: [PATCH 4/4] test(permissions): update integration test to expect id-token: read compilation failure The idtoken_write_warning_test.go integration test has a test case for id-token: read. Now that id-token: read is invalid, the test needs to be updated to expect compilation failure instead of checking for warnings. Co-authored-by: eaftan <4733401+eaftan@users.noreply.github.com> --- pkg/workflow/idtoken_write_warning_test.go | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/pkg/workflow/idtoken_write_warning_test.go b/pkg/workflow/idtoken_write_warning_test.go index e547ddb0fc8..0618618320b 100644 --- a/pkg/workflow/idtoken_write_warning_test.go +++ b/pkg/workflow/idtoken_write_warning_test.go @@ -16,9 +16,10 @@ import ( // TestIdTokenWriteWarning tests that id-token: write permission emits a warning func TestIdTokenWriteWarning(t *testing.T) { tests := []struct { - name string - content string - expectWarning bool + name string + content string + expectWarning bool + expectCompileFail bool }{ { name: "id-token write produces warning", @@ -35,7 +36,7 @@ permissions: expectWarning: true, }, { - name: "id-token read does not produce warning", + name: "id-token read is invalid and compilation fails", content: `--- on: workflow_dispatch engine: copilot @@ -46,7 +47,8 @@ permissions: # Test Workflow `, - expectWarning: false, + expectWarning: false, + expectCompileFail: true, }, { name: "no id-token does not produce warning", @@ -129,6 +131,14 @@ engine: copilot io.Copy(&buf, r) stderrOutput := buf.String() + // Handle cases where compilation is expected to fail + if tt.expectCompileFail { + if err == nil { + t.Errorf("Expected compilation to fail but it succeeded") + } + return + } + if err != nil { t.Errorf("Expected compilation to succeed but it failed: %v", err) return