Skip to content

Fix identity resolution for ServiceAccount tokens behind OAuth proxy#1401

Draft
guzalv wants to merge 1 commit intoambient-code:mainfrom
guzalv:fix/non-fatal-credential-refresh
Draft

Fix identity resolution for ServiceAccount tokens behind OAuth proxy#1401
guzalv wants to merge 1 commit intoambient-code:mainfrom
guzalv:fix/non-fatal-credential-refresh

Conversation

@guzalv
Copy link
Copy Markdown

@guzalv guzalv commented Apr 21, 2026

Summary

  • Fix forwardedIdentityMiddleware to resolve the creating user's identity when X-Forwarded-User is a ServiceAccount subject
  • This enables API key-authenticated requests (mobile apps, CLI tools) to access integration credentials (GitHub, Jira, Google, GitLab)

Problem

When a mobile app or CLI tool uses a K8s ServiceAccount JWT (created via "Access Keys"), the OAuth proxy sets X-Forwarded-User to the SA subject: system:serviceaccount:stackrox-1:ambient-key-test-write-2b3908aa.

The middleware sanitizes this into system-serviceaccount-stackrox-1-ambient-key-test-write-2b3908aa and sets it as userID. The SA annotation fallback (created-by-user-id) was guarded by userID == "", which was never true — so the creating user's identity was never resolved.

This caused a cascade of failures:

  1. AG-UI proxy forwards the synthetic SA identity as X-Current-User-ID to the runner
  2. Runner uses it for credential requests (X-Runner-Current-User header)
  3. Backend RBAC rejects because SA identity ≠ session owner identity
  4. All credential providers fail → PermissionErrorRUN_ERROR → agent run aborted

The web UI doesn't hit this because the OAuth proxy sets X-Forwarded-User to the human username (e.g. userid), not a SA subject.

Fix

When X-Forwarded-User starts with system:serviceaccount:, also check the SA's ambient-code.io/created-by-user-id annotation and use the real human identity. This is the same annotation already set by the access key creation endpoint (permissions.go:420).

Test plan

  • Create an access key, send a prompt via API, verify agent responds with full credential access
  • Verify web UI sessions continue working as before (human X-Forwarded-User values are unchanged)
  • Verify SA tokens without the annotation still work (synthetic ID used as fallback)

🤖 Generated with Claude Code

@netlify
Copy link
Copy Markdown

netlify Bot commented Apr 21, 2026

Deploy Preview for cheerful-kitten-f556a0 canceled.

Name Link
🔨 Latest commit 1002f2b
🔍 Latest deploy log https://app.netlify.com/projects/cheerful-kitten-f556a0/deploys/69e7f5d9d3ee760008aa45c2

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 21, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 047b8715-bfb7-46bd-8d1f-04c01b73bec9

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
✨ Simplify code
  • Create PR with simplified code

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

When a request uses a K8s ServiceAccount token (API key), the OAuth
proxy sets X-Forwarded-User to the SA subject (e.g.
"system:serviceaccount:ns:sa-name"). The middleware sanitized this
into a synthetic userID, but the fallback that reads the SA's
created-by-user-id annotation was guarded by `userID == ""` — which
was never true because the proxy already set it.

This caused credential RBAC failures for API key-authenticated
requests (mobile apps, CLI tools) because the synthetic SA identity
didn't match the session owner's identity, so the runner couldn't
fetch GitHub/Jira/Google credentials.

Fix: also trigger the annotation lookup when X-Forwarded-User is a
ServiceAccount subject, overriding the synthetic ID with the real
creating user's identity.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@guzalv guzalv force-pushed the fix/non-fatal-credential-refresh branch from f70ab1f to 1002f2b Compare April 21, 2026 22:10
@guzalv guzalv changed the title Make credential refresh non-fatal for agent runs Fix identity resolution for ServiceAccount tokens behind OAuth proxy Apr 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant