Skip to content

[WIP] Add support for OTLP export auth via Workload Identity Federation - #50184

Open
pelikhan with Copilot wants to merge 8 commits into
mainfrom
copilot/feature-otlp-export-auth-wif
Open

[WIP] Add support for OTLP export auth via Workload Identity Federation#50184
pelikhan with Copilot wants to merge 8 commits into
mainfrom
copilot/feature-otlp-export-auth-wif

Conversation

Copilot AI commented Aug 4, 2026

Copy link
Copy Markdown
Contributor
  • Inspect existing OTLP OIDC configuration, compilation, and tests
  • Add Google workload-identity federation configuration and per-job token exchange
  • Add focused coverage and validate generated workflow behavior
  • Run final review and security validation

Caution

agentic threat detected
Threat detection flagged this output in warn mode. Manual review is REQUIRED before any follow-up automation.

Details

Potential security threats were detected in the agent output.

Review the workflow run logs for details.

Run: https://github.com/github/gh-aw/actions/runs/30909334614
safeoutputs add_comment --pr_number 50184 --body $'
@copilot This PR needs a quick maintainer-ready refresh.

  • Unresolved review feedback: github-actions requested changes in the latest review; please address the noted issues before handoff.
  • Refresh the branch with the latest base changes.
  • Then run the skill and hand back when ready.

Run: 'https://github.com/github/gh-aw/actions/runs/30909334614

PR 50183 combined nudge

safeoutputs update_pull_request --pr_number 50183 --update_branch true --operation append --body $'

Run: 'https://github.com/github/gh-aw/actions/runs/30909334614

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 11.8 AIC · ⌖ 11.3 AIC · ⊞ 8.3K ·
Comment /souschef to run again


Run: https://github.com/github/gh-aw/actions/runs/30912825871

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 18.4 AIC · ⌖ 7.69 AIC · ⊞ 5.9K ·
Comment /souschef to run again

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Hey 👋 — thanks for kicking off the Workload Identity Federation support for OTLP export auth via the coding agent! This is a solid feature area (OTLP/OIDC auth) and fits well within the project's scope.

A few notes since this is still early/WIP:

  • Diff is very small so far (1 line in smoke-goose.lock.yml) — the checklist in the description (inspect OIDC config, add WIF config/token exchange, add coverage, run checks) is mostly unchecked, so this looks like an in-progress commit rather than a complete change yet.
  • No tests included yet — once the WIF token-exchange logic and generated workflow changes land, please add focused test coverage as outlined in the PR's own checklist.
  • Description is a checklist, not a summary — once implementation is closer to done, it'd help reviewers to add a short "what/why" summary alongside the task checklist.

Since this is marked [WIP] and is still a draft, no action is needed until the remaining checklist items are complete — just flagging so the final PR is easy to review.

Continue implementing Workload Identity Federation support for OTLP export auth in gh-aw:
1. Add Google WIF configuration options alongside the existing OTLP OIDC config.
2. Implement per-job token exchange for WIF-based auth.
3. Regenerate any affected .lock.yml workflow files.
4. Add unit/integration tests covering the new WIF auth path (success and failure cases).
5. Update the PR description with a concise summary of what changed and why, referencing issue #50013.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • patchdiff.githubusercontent.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "patchdiff.githubusercontent.com"

See Network Configuration for more information.

Generated by ✅ Contribution Check · auto · 72.9 AIC · ⌖ 3.94 AIC · ⊞ 8.8K ·

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Triage: feature (OTel) / high risk

  • Category: feature
  • Risk: high
  • Priority score: 75/100 (impact 40, urgency 20, quality 15)
  • Recommended action: fast_track — high-value OTLP/Workload Identity Federation feature, touches compiler/schema/validators (10 files, 221 additions)
  • Notes: OpenTelemetry-related — labeled otel per triage policy; flagging for @mnkeifer review. Draft/WIP, CI unstable, security review still pending per author checklist. Includes new tests (observability_otlp_test.go, setup_step_version_test.go).

Generated by 🔧 PR Triage Agent · auto · 28.5 AIC · ⌖ 2.46 AIC · ⊞ 8K ·

@pelikhan
pelikhan marked this pull request as ready for review August 4, 2026 12:17
Copilot AI balanced review requested due to automatic review settings August 4, 2026 12:17
@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Design Decision Gate 🏗️ completed the design decision gate check.

@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅

@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

PR Code Quality Reviewer completed the code quality review.

@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel completed test quality analysis.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds Google Workload Identity Federation authentication for OTLP exports.

Changes:

  • Adds WIF configuration, schema, and validation.
  • Generates GitHub OIDC-to-Google access-token exchange steps.
  • Adds firewall entries, tests, and documentation.
Show a summary per file
File Description
pkg/workflow/setup_step_version_test.go Tests token-exchange setup generation.
pkg/workflow/permissions_compiler_validator.go Validates WIF OIDC permissions.
pkg/workflow/observability_otlp.go Parses WIF and adds network domains.
pkg/workflow/observability_otlp_test.go Tests WIF OIDC detection.
pkg/workflow/frontmatter_types.go Defines WIF configuration types.
pkg/workflow/compiler_yaml_step_generation.go Generates Google token exchange steps.
pkg/workflow/compiler_validators.go Validates WIF fields and combinations.
pkg/parser/schemas/main_workflow_schema.json Adds the WIF frontmatter schema.
docs/src/content/docs/guides/open-telemetry.mdx Documents Google WIF configuration.
.github/workflows/smoke-goose.lock.yml Regenerates step capitalization.

Review details

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Suppressed comments (1)

pkg/workflow/compiler_yaml_step_generation.go:212

  • This error hides the IAM Credentials HTTP status, making an invalid service-account value indistinguishable from missing impersonation permissions. Include the status and the likely corrective action.
			"              if (!impersonationResponse.ok) throw new Error('Google service account impersonation failed');\n",
  • Files reviewed: 10/10 changed files
  • Comments generated: 5
  • Review effort level: Balanced

Comment on lines +151 to +155
var audience string
if workloadIdentity != nil {
audience = strings.TrimSpace(workloadIdentity.Audience)
} else {
audience = strings.TrimSpace(githubApp.Audience)
lines = append(lines, formatYAMLEnv(" ", "GH_AW_OTLP_OIDC_AUDIENCE", audience))
}

if workloadIdentity != nil {
Comment thread pkg/workflow/observability_otlp.go Outdated
Comment on lines +748 to +749
if workloadIdentity := getOTLPWorkloadIdentity(workflowData.ParsedFrontmatter, workflowData.RawFrontmatter); workloadIdentity != nil &&
strings.EqualFold(strings.TrimSpace(workloadIdentity.Provider), "google") {
Comment on lines +277 to +280
if !requiresIDTokenWrite && hasOTLPGitHubOIDCAuth(workflowData.ParsedFrontmatter, workflowData.RawFrontmatter) {
requiresIDTokenWrite = true
errorPrefix = "observability.otlp.github-app"
if getOTLPWorkloadIdentity(workflowData.ParsedFrontmatter, workflowData.RawFrontmatter) != nil {
errorPrefix = "observability.otlp.workload-identity"
" scope: 'https://www.googleapis.com/auth/cloud-platform',\n",
" }),\n",
" });\n",
" if (!response.ok) throw new Error('Google workload identity token exchange failed');\n",

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · sonnet46 · 36.5 AIC · ⌖ 12.3 AIC · ⊞ 5.4K

Comment thread pkg/workflow/observability_otlp.go Outdated
if workflowData.NetworkPermissions == nil {
workflowData.NetworkPermissions = &NetworkPermissions{}
}
workflowData.NetworkPermissions.Allowed = append(workflowData.NetworkPermissions.Allowed,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: WIF network domains appended once per OTLP endpoint (duplicates)

The sts.googleapis.com, iamcredentials.googleapis.com, and oauth2.googleapis.com domains are appended inside the for _, e := range entries loop. With multiple OTLP endpoints configured, these three domains are added to the allowlist N times — once per endpoint — producing duplicate entries in the network allowlist.

Move the WIF guard block outside (and after) the loop so it runs at most once.

@copilot please address this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The WIF host injection was hoisted out of the endpoint loop in 81768e1, so the hosts are added at most once regardless of endpoint count (and now also when the endpoint is an expression with no extractable domain).

Comment thread pkg/workflow/observability_otlp.go Outdated
workflowData.NetworkPermissions.Allowed = append(workflowData.NetworkPermissions.Allowed,
"sts.googleapis.com",
"iamcredentials.googleapis.com",
"oauth2.googleapis.com",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused domain: oauth2.googleapis.com is never called in generated code

The generated JavaScript in generateOTLPOIDCMintStep only calls (sts.googleapis.com/redacted) and (iamcredentials.googleapis.com/redacted) There is no call to oauth2.googleapis.com anywhere in the generated code. Adding it to the network allowlist widens the firewall surface unnecessarily.

Remove the oauth2.googleapis.com entry, or add a comment explaining why it is needed.

@copilot please address this.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skills-Based Review 🧠

Applied /codebase-design, /diagnosing-bugs, and /tdd — requesting changes on correctness and debuggability issues.

📋 Key Themes & Highlights

Issues Found

  • Duplicate network-domain injection (sts/iamcredentials appended N times when N endpoints are configured) — correctness bug
  • Dead redundant nil-check inside the endpoint loop — dead code left from merging two code paths
  • Unreferenced allowlist entry oauth2.googleapis.com — never used by the generated JS steps
  • Opaque error messages in the JS token-exchange steps — HTTP status and body are not surfaced, making IAM failures hard to diagnose
  • Always-emitted empty env var GH_AW_OTLP_WIF_SERVICE_ACCOUNT when service-account is unset
  • Missing test for service-account-omitted path — the optional impersonation branch has no negative assertion

Positive Highlights

  • ✅ Clean two-step design: mint OIDC token → exchange for GCP access token — follows the existing github-app pattern well
  • core.setSecret called on both the OIDC and access tokens — good hygiene
  • ✅ Validation correctly blocks combining workload-identity with github-app credentials
  • id-token: write permission error message updated to use the correct config path

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · sonnet46 · 49.1 AIC · ⌖ 8.56 AIC · ⊞ 7.1K
Comment /matt to run again

Comment thread pkg/workflow/observability_otlp.go Outdated
}
if workloadIdentity := getOTLPWorkloadIdentity(workflowData.ParsedFrontmatter, workflowData.RawFrontmatter); workloadIdentity != nil &&
strings.EqualFold(strings.TrimSpace(workloadIdentity.Provider), "google") {
if workflowData.NetworkPermissions == nil {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/codebase-design] Dead code: NetworkPermissions is already guaranteed non-nil at line 745 (inside the same if domain != "" block), so this inner nil-check at line 750 can never execute.

💡 Suggested fix

Remove lines 750–752 — the outer guard at line 745 covers it.

// before setup — just append directly:
workflowData.NetworkPermissions.Allowed = append(...)

@copilot please address this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved by hoisting the WIF block out of the endpoint loop; the remaining nil-check is now the only guard for that path. Commit 81768e1.

Comment thread pkg/workflow/observability_otlp.go Outdated
workflowData.NetworkPermissions.Allowed = append(workflowData.NetworkPermissions.Allowed,
"sts.googleapis.com",
"iamcredentials.googleapis.com",
"oauth2.googleapis.com",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/diagnosing-bugs] oauth2.googleapis.com is added to the network allowlist but never contacted by the generated exchange steps — only sts.googleapis.com and iamcredentials.googleapis.com are used. This either allows unnecessary network egress or is a dead entry left from an earlier design.

💡 Suggested fix

Remove "oauth2.googleapis.com" from the Allowed list unless a concrete future use is planned and documented. Unnecessary firewall holes widen the attack surface.

@copilot please address this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed oauth2.googleapis.com from the allowlist — only sts.googleapis.com and iamcredentials.googleapis.com are contacted. Commit 34ff26b.

Comment thread pkg/workflow/observability_otlp.go Outdated
if workflowData.NetworkPermissions == nil {
workflowData.NetworkPermissions = &NetworkPermissions{}
}
if workloadIdentity := getOTLPWorkloadIdentity(workflowData.ParsedFrontmatter, workflowData.RawFrontmatter); workloadIdentity != nil &&

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/codebase-design] The Google WIF network-domain injection is nested inside the for _, e := range entries loop, so sts.googleapis.com and iamcredentials.googleapis.com are appended once per OTLP endpoint. If multiple endpoints are configured the allowlist will contain duplicates.

💡 Suggested fix

Hoist the WIF domain injection above the for loop — it only depends on workload-identity config, not on each individual endpoint:

if wi := getOTLPWorkloadIdentity(...); wi != nil && strings.EqualFold(...) {
    if workflowData.NetworkPermissions == nil { ... }
    workflowData.NetworkPermissions.Allowed = append(..., "sts.googleapis.com", "iamcredentials.googleapis.com")
}
for _, e := range entries { ... }

@copilot please address this.

" scope: 'https://www.googleapis.com/auth/cloud-platform',\n",
" }),\n",
" });\n",
" if (!response.ok) throw new Error('Google workload identity token exchange failed');\n",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/diagnosing-bugs] When the STS token exchange fails, the error message "Google workload identity token exchange failed" does not include the HTTP status code or response body, making it hard to diagnose IAM misconfiguration in CI logs.

💡 Suggested fix
if (!response.ok) {
  const body = await response.text().catch(() => "");
  throw new Error(`Google WIF token exchange failed: ${response.status} ${body}`);
}

Apply the same pattern to the impersonation response at line 212.

@copilot please address this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both the STS and impersonation error paths now include the HTTP status/statusText plus configuration guidance. Commit 81768e1.

}
if !strings.Contains(combined, "https://sts.googleapis.com/v1/token") || !strings.Contains(combined, "iamcredentials.googleapis.com") {
t.Fatalf("expected setup step to include Google STS and service account exchange, got:\n%s", combined)
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/tdd] The new test checks happy-path output strings but has no coverage for the WIF-without-service-account case (i.e. service-account is omitted). The impersonation branch at compiler line 206 would silently be skipped and a regression there would go undetected.

💡 Suggested additional test

Add a second test TestGenerateSetupStepExchangesGoogleOTLPWorkloadIdentityTokenWithoutServiceAccount that omits service-account and asserts the iamcredentials.googleapis.com call is NOT present in the generated output, confirming the optional-impersonation path is correct.

@copilot please address this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added TestGenerateSetupStepExchangesGoogleOTLPWorkloadIdentityTokenWithoutServiceAccount, which omits service-account and asserts the impersonation env var is not emitted. Commit 34ff26b.

" env:\n",
" GH_AW_OTLP_OIDC_TOKEN: ${{ steps.mint-otlp-oidc-token.outputs.token }}\n",
)
lines = append(lines, formatYAMLEnv(" ", "GH_AW_OTLP_WIF_AUDIENCE", workloadIdentity.Audience))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/codebase-design] GH_AW_OTLP_WIF_SERVICE_ACCOUNT is always emitted as an env var even when service-account is empty, injecting a blank environment variable into every WIF exchange step. Use formatYAMLEnv conditionally.

💡 Suggested fix
if sa := strings.TrimSpace(workloadIdentity.ServiceAccount); sa != "" {
    lines = append(lines, formatYAMLEnv("          ", "GH_AW_OTLP_WIF_SERVICE_ACCOUNT", sa))
}

@copilot please address this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GH_AW_OTLP_WIF_SERVICE_ACCOUNT is now emitted only when service-account is non-empty. Commit 34ff26b.

@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Design Decision Gate — ADR Required

This PR makes significant changes to core business logic (203 new lines in pkg/) but does not have a linked Architecture Decision Record (ADR).

Draft ADR committed: docs/adr/50184-otlp-export-auth-via-google-workload-identity-federation.md — review and complete it before merging.

This PR cannot merge until an ADR is linked in the PR body.

What to do next
  1. Review the draft ADR committed to your branch — it was generated from the PR diff
  2. Complete the missing sections — add context the AI could not infer, refine the decision rationale, and list real alternatives you considered
  3. Commit the finalized ADR to docs/adr/ on your branch
  4. Reference the ADR in this PR body by adding a line such as:

    ADR: ADR-50184: OTLP Export Authentication via Google Workload Identity Federation

Once an ADR is linked in the PR body, this gate will re-run and verify the implementation matches the decision.

Why ADRs Matter

ADRs create a searchable, permanent record of why the codebase looks the way it does. Future contributors (and your future self) will thank you.

Michael Nygard ADR Format Reference

An ADR must contain these four sections to be considered complete:

  • Context — What is the problem? What forces are at play?
  • Decision — What did you decide? Why?
  • Alternatives Considered — What else could have been done?
  • Consequences — What are the trade-offs (positive and negative)?

All ADRs are stored in docs/adr/ as Markdown files numbered by PR number.

🏗️ ADR gate enforced by Design Decision Gate 🏗️ · sonnet46 · 59.7 AIC · ⌖ 33.1 AIC · ⊞ 9.6K ·
Comment /review to run again

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧪 Test Quality Sentinel Report

Test Quality Score: 100/100 — Excellent

Analyzed 2 test(s): 2 design, 0 implementation, 0 violation(s).

📊 Metrics (2 tests)
Metric Value
Analyzed 2 (Go: 2, JS: 0)
✅ Design 2 (100%)
⚠️ Implementation 0 (0%)
Edge/error coverage 2 (100%)
Duplicate clusters 0
Inflation No (1.1:1 test:prod ratio)
🚨 Violations 0
Test File Classification Coverage
Added to TestHasOTLPGitHubOIDCAuth (raw map) observability_otlp_test.go:283 design_test / high_value Google workload-identity configuration parsing
TestGenerateSetupStepExchangesGoogleOTLPWorkloadIdentityToken setup_step_version_test.go:359 design_test / high_value STS exchange + token passing validation

Verdict

Passed. 0% implementation tests (threshold: 30%). All tests verify external user-visible behavior with comprehensive assertions and no forbidden patterns detected. Test inflation ratio 1.1:1 (well below 2:1 threshold).

Key strengths:

  • All 2 tests are design tests verifying configuration parsing and code generation
  • Comprehensive error assertions with descriptive context messages
  • Tests edge cases: raw frontmatter map parsing and Google-specific STS endpoints
  • No mocking libraries, proper build tags, clean assertions
  • Excellent test:production ratio (1.1:1)

@pelikhan

pelikhan commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

@copilot run pr-finisher skill (local skill, no agent finder)

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: Request changes

The WIF token-exchange flow is a reasonable design, but the implementation has a correctness bug (domain duplication per endpoint) and a maintainability/correctness inconsistency (hardcoded step-id reference next to a step-id abstraction that exists specifically to avoid this).

Themes
  1. Domain duplication: sts.googleapis.com, iamcredentials.googleapis.com, and oauth2.googleapis.com are appended inside the per-endpoint loop, so a workflow with N OTLP endpoints gets these three domains added N times to the firewall allowlist.
  2. Inconsistent step-id reference: getOTLPAuthTokenStepID was introduced to abstract which step produced the OIDC/WIF token, but the workload-identity exchange step itself still references steps.mint-otlp-oidc-token directly instead of using the helper (or being colocated with it), which is fragile if the mint step is ever renamed or conditionally skipped.
  3. Missing dedicated unit test for validateOTLPWorkloadIdentity covering provider mismatch, missing audience, and github-app conflict cases.
  4. Error handling in the generated STS/IAM exchange script discards the response body, making CI failures hard to diagnose.

🔎 Code quality review by PR Code Quality Reviewer · auto · 101.4 AIC · ⌖ 4.53 AIC · ⊞ 7.9K
Comment /review to run again

Comment thread pkg/workflow/observability_otlp.go Outdated
Comment on lines +748 to +753
if workloadIdentity := getOTLPWorkloadIdentity(workflowData.ParsedFrontmatter, workflowData.RawFrontmatter); workloadIdentity != nil &&
strings.EqualFold(strings.TrimSpace(workloadIdentity.Provider), "google") {
if workflowData.NetworkPermissions == nil {
workflowData.NetworkPermissions = &NetworkPermissions{}
}
workflowData.NetworkPermissions.Allowed = append(workflowData.NetworkPermissions.Allowed,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Google WIF domains are appended inside the endpoint loop, so they get duplicated once per configured OTLP endpoint entry.

Comment on lines +174 to +181
if workloadIdentity != nil {
compilerYamlStepGenerationLog.Print("Generating Google OTLP workload identity token exchange step before setup")
lines = append(lines,
" - name: Exchange OTLP workload identity token\n",
" id: exchange-otlp-workload-identity-token\n",
fmt.Sprintf(" uses: %s\n", getCachedActionPin("actions/github-script", data)),
" env:\n",
" GH_AW_OTLP_OIDC_TOKEN: ${{ steps.mint-otlp-oidc-token.outputs.token }}\n",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This step references the mint step output by hardcoded id steps.mint-otlp-oidc-token, bypassing the getOTLPAuthTokenStepID abstraction added right below — if the mint step id ever changes this silently breaks.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The exchange step reads the mint step output via fmt.Sprintf(..., otlpOIDCMintStepID), not a hardcoded literal — getOTLPAuthTokenStepID is a separate concern (which step downstream consumers read the final token from).

}
return nil
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No unit test exercises validateOTLPWorkloadIdentity directly (missing provider, missing audience, or combined with github-app) — only the OIDC-auth detection test was extended.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added TestValidateOTLPWorkloadIdentity covering non-google provider, missing audience, the github-app combination, and the valid/absent cases. Commit 34ff26b.

" scope: 'https://www.googleapis.com/auth/cloud-platform',\n",
" }),\n",
" });\n",
" if (!response.ok) throw new Error('Google workload identity token exchange failed');\n",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Error paths swallow the STS/IAM response body, so failures only say "exchange failed" with no diagnostic detail — this will be painful to debug in CI logs.

@pelikhan

pelikhan commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

@copilot run pr-finisher skill (local skill, not agent finder)

… firewall hosts, error detail

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Warning

Threat Detection Engine Failure — The analysis engine could not complete. This is a tooling failure, not a security finding.

What happened

The threat detection results could not be parsed.

Review the workflow run logs for details.

Triage update: feature (OTel) / high risk

  • Category: feature
  • Risk: high (unchanged — WIF/OIDC auth path, credential handling, 267 additions, ADR requested by Design Decision Gate)
  • Score: 82 (impact 40 + urgency 22 + quality 20)
  • Recommended action: fast_track — high value, needs maintainer + security review; ADR still outstanding.
  • Assignment: @mnkeifer (OpenTelemetry-related change per triage policy).

Generated by 🔧 PR Triage Agent · auto · 29.9 AIC · ⌖ 2.62 AIC · ⊞ 8K ·

…vice-account env, add validator and no-service-account tests

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot This PR needs a quick maintainer-ready refresh.

  • Please address the latest review themes: dedupe the Google firewall domains, remove the hardcoded mint-otlp-oidc-token step reference in favor of the shared abstraction, and improve STS/IAM error reporting.
  • Also complete the ADR linkage expected by the design-decision gate if it is still missing from the PR body.
  • Refresh the branch with the latest base changes.
  • Then run the pr-finisher skill and hand back with a concise summary of remaining blockers.

Run: https://github.com/github/gh-aw/actions/runs/30912825871

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 18.4 AIC · ⌖ 7.69 AIC · ⊞ 5.9K ·
Comment /souschef to run again

Copilot AI commented Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

@copilot This PR needs a quick maintainer-ready refresh.

  • Please address the latest review themes: dedupe the Google firewall domains, remove the hardcoded mint-otlp-oidc-token step reference in f...

All four items are now done:

  • Dedupe Google firewall domains — the WIF host injection was hoisted out of the for _, e := range entries loop, so sts.googleapis.com / iamcredentials.googleapis.com are added at most once regardless of endpoint count, and now also when the endpoint is an expression with no statically extractable domain. The unused oauth2.googleapis.com entry was removed (81768e1, 34ff26b).
  • Hardcoded step reference — there is no hardcoded mint-otlp-oidc-token literal left; all references go through the otlpOIDCMintStepID / otlpWIFExchangeStepID constants and getOTLPAuthTokenStepID.
  • STS/IAM error reporting — both the STS exchange and the impersonation call now throw with the HTTP status/statusText plus guidance pointing at the relevant observability.otlp.workload-identity field (81768e1).
  • ADR linkageADR-50184 is committed in 8819829 and is now linked from the PR body.

Branch is up to date with main (merge 621ac59). Local validation is green: make fmt, make lint, make recompile (271/271), and the full unit suite.

Remaining blockers: CI on the current HEAD is stale — my pushes don't trigger workflows, so a maintainer needs to re-trigger it (close/reopen, workflow_dispatch, or a push). The PR also still needs @pelikhan's review approval.

Copilot AI requested a review from gh-aw-bot August 4, 2026 13:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

4 participants