-
Notifications
You must be signed in to change notification settings - Fork 229
Add compilation warning for id-token: write permission #15026
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -255,6 +255,22 @@ func (c *Compiler) validateWorkflowData(workflowData *WorkflowData, markdownPath | |||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| // Emit warning if id-token: write permission is detected | ||||||||||||||
| log.Printf("Checking for id-token: write permission") | ||||||||||||||
| if workflowData.Permissions != "" { | ||||||||||||||
| permissions := NewPermissionsParser(workflowData.Permissions).ToPermissions() | ||||||||||||||
| if permissions != nil { | ||||||||||||||
|
Comment on lines
+260
to
+262
|
||||||||||||||
| level, exists := permissions.Get(PermissionIdToken) | ||||||||||||||
| if exists && level == PermissionWrite { | ||||||||||||||
| warningMsg := `This workflow grants id-token: write permission | ||||||||||||||
| OIDC tokens can authenticate to cloud providers (AWS, Azure, GCP). | ||||||||||||||
| Ensure proper audience validation and trust policies are configured.` | ||||||||||||||
|
Comment on lines
+265
to
+267
|
||||||||||||||
| warningMsg := `This workflow grants id-token: write permission | |
| OIDC tokens can authenticate to cloud providers (AWS, Azure, GCP). | |
| Ensure proper audience validation and trust policies are configured.` | |
| warningMsg := "This workflow grants id-token: write permission\n" + | |
| "OIDC tokens can authenticate to cloud providers (AWS, Azure, GCP).\n" + | |
| "Ensure proper audience validation and trust policies are configured." |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,228 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| //go:build integration | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| package workflow | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "bytes" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "io" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "os" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "path/filepath" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "strings" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "testing" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "github.com/github/gh-aw/pkg/testutil" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // TestIdTokenWriteWarning tests that id-token: write permission emits a warning | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func TestIdTokenWriteWarning(t *testing.T) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| tests := []struct { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name string | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| content string | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| expectWarning bool | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name: "id-token write produces warning", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| content: `--- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| on: workflow_dispatch | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| engine: copilot | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| permissions: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| contents: read | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| id-token: write | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Test Workflow | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| `, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| expectWarning: true, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name: "id-token read does not produce warning", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| content: `--- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| on: workflow_dispatch | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| engine: copilot | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| permissions: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| contents: read | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| id-token: read | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Test Workflow | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| `, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| expectWarning: false, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name: "no id-token does not produce warning", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| content: `--- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| on: workflow_dispatch | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| engine: copilot | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| permissions: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| contents: read | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| issues: read | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Test Workflow | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| `, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| expectWarning: false, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name: "id-token write with other permissions produces warning", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| content: `--- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| on: workflow_dispatch | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| engine: copilot | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| permissions: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| contents: read | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| issues: read | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pull-requests: read | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| id-token: write | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Test Workflow | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| `, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| expectWarning: true, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name: "id-token write only produces warning", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| content: `--- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| on: workflow_dispatch | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| engine: copilot | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| permissions: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| id-token: write | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Test Workflow | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| `, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| expectWarning: true, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name: "no permissions does not produce warning", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| content: `--- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| on: workflow_dispatch | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| engine: copilot | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Test Workflow | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| `, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| expectWarning: false, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for _, tt := range tests { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| t.Run(tt.name, func(t *testing.T) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| tmpDir := testutil.TempDir(t, "idtoken-warning-test") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| testFile := filepath.Join(tmpDir, "test-workflow.md") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if err := os.WriteFile(testFile, []byte(tt.content), 0644); err != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| t.Fatal(err) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Capture stderr to check for warnings | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| oldStderr := os.Stderr | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| r, w, _ := os.Pipe() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| r, w, _ := os.Pipe() | |
| r, w, pipeErr := os.Pipe() | |
| if pipeErr != nil { | |
| t.Fatalf("failed to create stderr pipe: %v", pipeErr) | |
| } |
Copilot
AI
Feb 11, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The read end of the pipe (r) is never closed and io.Copy errors are ignored. Close r (typically with defer r.Close() after successful os.Pipe()) and check the io.Copy return error to avoid FD leaks and silent read failures in CI.
This issue also appears on line 208 of the same file.
| r, w, _ := os.Pipe() | |
| os.Stderr = w | |
| compiler := NewCompiler() | |
| compiler.SetStrictMode(false) | |
| err := compiler.CompileWorkflow(testFile) | |
| // Restore stderr | |
| w.Close() | |
| os.Stderr = oldStderr | |
| var buf bytes.Buffer | |
| io.Copy(&buf, r) | |
| r, w, err := os.Pipe() | |
| if err != nil { | |
| t.Fatalf("failed to create stderr pipe: %v", err) | |
| } | |
| defer r.Close() | |
| os.Stderr = w | |
| compiler := NewCompiler() | |
| compiler.SetStrictMode(false) | |
| err = compiler.CompileWorkflow(testFile) | |
| // Restore stderr | |
| w.Close() | |
| os.Stderr = oldStderr | |
| var buf bytes.Buffer | |
| if _, copyErr := io.Copy(&buf, r); copyErr != nil { | |
| t.Fatalf("failed to read from stderr pipe: %v", copyErr) | |
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
log.Printf("Checking for id-token: write permission")will be written to stderr by the standard logger, and it contains the exact substringid-token: write. That makes stderr-based warning detection (including the new tests) flaky and also pollutes compiler output. Please remove this log line or gate it behind an explicit verbose/debug flag and avoid emittingid-token: writeverbatim in logs.See below for a potential fix: