fix: end-to-end credential flow fixes#1208
Merged
markturansky merged 7 commits intoalphafrom Apr 4, 2026
Merged
Conversation
## Summary
- Seeds `credential:token-reader` and `credential:reader` roles via
migration `202603311216`
- Mounts runner BOT_TOKEN as file with 10-min background refresh loop in
control-plane
- Authorizes runner OIDC service account in `WatchSessionMessages`
- Adds exponential backoff retry in informer error handler
- Adds `acpctl apply -f` credential manifest support and role-binding
commands to CLI
## Test plan
- [ ] Deploy to OSD `ambient-s0` via ArgoCD (gitops MR \!94 already
merged)
- [ ] Verify `credential:token-reader` and `credential:reader` appear in
`acpctl get roles`
- [ ] Create role binding for `github-agent` in `credential-test`
project
- [ ] Start agent session and confirm runner pod retrieves token via
`GET /credentials/{id}/token`
🤖 Generated with [Claude Code](https://claude.ai/code)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Release Notes
* **New Features**
* Added role seeding and management capabilities to credentials system.
* Enhanced CLI with updated login, project context, and resource
management commands.
* Introduced declarative manifest application via `acpctl apply`.
* Added agent creation and session messaging commands.
* **Bug Fixes**
* Strengthened authorization validation for session message access.
* **Documentation**
* Expanded CLI reference with comprehensive command examples and usage
patterns.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Ambient Code Bot <bot@ambient-code.local>
Co-authored-by: Claude <noreply@anthropic.com>
## Summary The `BackendURL` config field defaulted to `http://backend-service.ambient-code.svc:8080/api` — a legacy service that no longer exists. Runner pods need `BACKEND_API_URL` set to call `GET /credentials/{id}/token`. Since `AMBIENT_API_SERVER_URL` is already set in all deployments, default `BackendURL` to it. Discovered during E2E testing of the credential flow on OSD `ambient-s0`: runner logs showed DNS failures fetching credentials from the old backend URL. ## Test plan - [ ] Runner pod logs show `Successfully fetched github credentials from backend` instead of DNS failure on `backend-service.ambient-code.svc` - [ ] Agent can retrieve GitHub token via `/credentials/{id}/token` and use it 🤖 Generated with [Claude Code](https://claude.ai/code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Chores** * Backend URL configuration now uses environment variable fallback logic (`BACKEND_API_URL` → `AMBIENT_API_SERVER_URL` → default to `http://localhost:8000`), enabling more flexible configuration across different deployment environments. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Ambient Code Bot <bot@ambient-code.local> Co-authored-by: Claude <noreply@anthropic.com>
refreshAllRunningTokens called ForProject(ctx, "") which the SDK rejects with "project is required". Sessions are project-scoped so the cross-project list requires iterating all projects first, then listing running sessions per project. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
The token refresh ticker fires every 10 minutes. If the control-plane restarts during an active session, existing runner BOT_TOKENs can expire before the first ticker tick fires. Trigger an immediate refresh on startup so any in-flight sessions get fresh tokens right away. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
K8s service names are lowercased by the control-plane (safeResourceName), but StreamRunnerEvents was using the raw mixed-case session ID in the svc.cluster.local hostname, causing DNS resolution to fail with i/o timeout and a 502 to the client. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
OIDC tokens from Red Hat SSO have a 15-minute TTL. With a 10-minute refresh interval the Secret update and the runner's reconnect can race such that the runner reads an already-expired token. Reducing to 4 minutes ensures the mounted token always has ≥11 minutes of remaining lifetime when the runner reads it on reconnect. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Contributor
|
Caution Review failedPull request was closed or merged during review 📝 WalkthroughWalkthroughSeeds built-in roles via a new DB migration; tightens session-watch authorization and normalizes runner CR names; adds JWT-based username extraction fallback for bearer tokens; updates CLI docs and backend URL fallback; and refactors token refresh to run per-project more frequently with immediate startup refresh. Changes
Important Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional. ❌ Failed checks (1 error, 2 warnings)
✅ Passed checks (3 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
✨ Simplify 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. Comment |
Adds JWT fallback in bearerTokenGRPCUnaryInterceptor and bearerTokenGRPCStreamInterceptor so CLI users sending OIDC JWTs get their username extracted via jwt.ParseUnverified and set in context via auth.SetUsernameContext, enabling WatchSessionMessages to authorize them correctly. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Contributor
Author
|
hello world |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Six commits fixing the full credential flow from control-plane provisioning through runner token auth and session event streaming.
< /dev/null | Commit | Component | Fix |
|--------|-----------|-----|
|
085028b7| control-plane | Credential rolebinding and project delete ||
a4cf9427| control-plane | DefaultBackendURLtoAMBIENT_API_SERVER_URLso runner pods reach the correct API server ||
f82422a2| control-plane | Token refresh loop: iterate all projects (was callingForProject("")→ SDK rejected empty project) ||
49dcf935| control-plane | Refresh runner tokens immediately on startup (eliminates expiry gap after CP restart) ||
2faf4424| api-server | Lowercase session ID in runner service DNS hostname (session-{ID}.svc.cluster.localmust be lowercase) ||
c16abb1d| control-plane | Reduce token refresh interval 10m → 4m (OIDC TTL is 15m; 10m left too small a margin for runner reconnects) |Root Causes Fixed
BACKEND_API_URLdefaulted to wrong value; now falls back toAMBIENT_API_SERVER_URLForProject("")was rejected by SDK; fixed by listing projects firstsession eventsalways 502: API server built DNS name with raw mixed-case session ID; K8s service names are lowercased by the control-planeTest plan
Successfully fetched github credentials from backend)acpctl session events <id>streams without 502UNAUTHENTICATED: Token is expiredon gRPC🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Documentation
apply, and credentials/role-binding guides.Bug Fixes
Chores