Skip to content

feat(git-token-service): add opaque SCM session capabilities#3701

Open
eshurakov wants to merge 3 commits into
mainfrom
chalk-winterberry
Open

feat(git-token-service): add opaque SCM session capabilities#3701
eshurakov wants to merge 3 commits into
mainfrom
chalk-winterberry

Conversation

@eshurakov
Copy link
Copy Markdown
Contributor

@eshurakov eshurakov commented Jun 3, 2026

Summary

Why

The staged SCM-containment rollout needs a token-service boundary that can issue short-lived, repository-scoped capabilities without returning raw GitHub or GitLab credentials during session setup. This PR ships that additive Worker slice first so the capability contract can be reviewed and deployed independently before the dependent Cloud Agent caller and outbound broker adopt it.

What was done

  • Add encrypted one-hour GitHub and GitLab capability issue/redeem RPCs that return opaque capabilities during issuance and credential-bearing headers only after validating a specific outbound request.
  • Restrict redemption to the pinned repository or project and a narrow Git smart HTTP, LFS control, and code-review API allowlist; re-resolve the current credential source and fail closed when its identity drifts or disappears.
  • Support container-bound v2 capabilities when outboundContainerId is supplied while retaining unbound v1 issuance as a temporary compatibility path for older callers.
  • Tighten self-managed GitLab handling to canonical HTTPS instance URLs across the Web integration boundary and Worker runtime parsing, including nested base-path validation.
  • Add the dedicated capability encryption-key binding while preserving the existing plaintext token RPCs for the staged dependent rollout.
  • Expose explicit local-only Wrangler bridge routes for manually exercising GitHub and GitLab capability issuance and redemption over the real Worker RPC binding.

High-level architecture

sequenceDiagram
  participant Caller as Future SCM session caller<br/>(not in this PR)
  participant Broker as Future outbound broker<br/>(not in this PR)
  participant Token as git-token-service RPC
  participant Store as Authorized integration storage
  participant SCM as GitHub or GitLab

  rect rgb(245, 245, 245)
    Note over Caller,SCM: Capability issuance
    Caller->>Token: issue...(user, org?, repository, container?)
    Token->>Store: Resolve authorized SCM source
    opt Mint or refresh current credential
      Token->>SCM: Resolve current credential
    end
    Token-->>Caller: Opaque capability + non-secret session metadata
  end

  rect rgb(245, 245, 245)
    Note over Caller,SCM: Per-request redemption
    Broker->>Token: redeem...(capability, container?, method, URL)
    Token->>Token: Check expiry, binding, origin, repository, and allowlist
    Token->>Store: Re-read pinned source and verify identity
    opt Mint or refresh current credential
      Token->>SCM: Resolve current credential
    end
    Token-->>Broker: Credential-bearing header for approved request
    Broker->>SCM: Forward approved request
  end

  Note over Broker,SCM: Broker adoption and redirect re-redemption are follow-up work
Loading

Verification

  • Started the existing local Wrangler service-binding bridge and called POST /getTokenForRepo against the live local git-token-service Worker for an active organization-owned GitHub App integration; confirmed a successful standard installation-token lookup with the returned token redacted.
  • Started an isolated, uniquely named local git-token-service Worker with a throwaway capability key and exercised the local bridge end to end: POST /issueGitHubSessionCapability returned a redacted bound kgh2 capability, then POST /redeemGitHubSessionCapability returned a redacted authorization header for an allowed Git transport URL.

Visual Changes

N/A

Reviewer Notes

  • Provision SCM_SESSION_CAPABILITY_ENCRYPTION_KEY_PROD before deploying the production Worker and the DEV counterpart before deploying git-token-service-dev; rotating the key invalidates outstanding capabilities.
  • Existing plaintext RPC methods remain available for staged adoption, but self-managed GitLab HTTP instance URLs are intentionally no longer accepted. A production audit found two active HTTP integrations that require migration or reconnection before rollout.
  • The local-only Wrangler test bridge now exposes explicit GitHub and GitLab capability issue/redeem routes for manual RPC smoke testing. The dependent Cloud Agent caller and outbound broker remain follow-up work.
  • Redemption returns usable authorization headers to the future broker. That broker must avoid logging or persisting them and must redeem redirected URLs again before forwarding credentials.
  • Review the temporary unbound v1 capability path and the GitLab Web/Worker trust boundary for self-managed origins; v2 container binding is enforced only when callers supply outboundContainerId.

Comment thread services/git-token-service/src/index.ts Outdated
Comment thread services/git-token-service/src/index.ts
@kilo-code-bot
Copy link
Copy Markdown
Contributor

kilo-code-bot Bot commented Jun 3, 2026

Code Review Summary

Status: 1 Issue Remaining | Recommendation: Address before merge

Executive Summary

The DELETE/PUT allowlist issue is fixed in c9080e226; the only remaining open issue is the intentional second DB round-trip in issueGitLabSessionCapability at line 729, which the author has acknowledged as a known TOCTOU window for this slice.

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
services/git-token-service/src/index.ts 729 issueGitLabSessionCapability performs a second DB lookup for the same integration already resolved by resolveGitLabRuntimeToken — creates a small TOCTOU window between token resolution and identity capture. Author has marked intentional for this slice.
Resolved Issues
File Line Resolution
services/git-token-service/src/index.ts 206 Fixed in c9080e226DELETE and PUT removed from GitHub REST method allowlist
Files Reviewed (29 files)
  • apps/web/src/app/api/integrations/gitlab/callback/route.test.ts
  • apps/web/src/app/api/integrations/gitlab/connect/route.test.ts
  • apps/web/src/lib/integrations/gitlab-service.test.ts
  • apps/web/src/lib/integrations/gitlab-service.ts
  • apps/web/src/lib/integrations/oauth/platforms/gitlab-callback.ts
  • apps/web/src/lib/integrations/platforms/gitlab/adapter.test.ts
  • apps/web/src/lib/integrations/platforms/gitlab/instance-url.test.ts
  • apps/web/src/lib/integrations/platforms/gitlab/instance-url.ts
  • apps/web/src/lib/integrations/platforms/gitlab/oauth-state.test.ts
  • apps/web/src/lib/integrations/platforms/gitlab/oauth-state.ts
  • services/git-token-service/.dev.vars.example
  • services/git-token-service/src/github-session-capability.test.ts
  • services/git-token-service/src/github-session-capability.ts
  • services/git-token-service/src/gitlab-lookup-service.test.ts
  • services/git-token-service/src/gitlab-lookup-service.ts
  • services/git-token-service/src/gitlab-runtime-token-resolver.ts
  • services/git-token-service/src/gitlab-session-capability.test.ts
  • services/git-token-service/src/gitlab-session-capability.ts
  • services/git-token-service/src/gitlab-token-service.test.ts
  • services/git-token-service/src/gitlab-token-service.ts
  • services/git-token-service/src/gitlab-url.ts
  • services/git-token-service/src/index.test.ts
  • services/git-token-service/src/index.ts — 1 issue remaining
  • services/git-token-service/test/test-worker.ts
  • services/git-token-service/worker-configuration.d.ts
  • services/git-token-service/wrangler.jsonc

Fix these issues in Kilo Cloud


Reviewed by claude-sonnet-4.6 · 355,238 tokens

Review guidance: REVIEW.md from base branch main

@eshurakov eshurakov force-pushed the chalk-winterberry branch from 748bb09 to a67a4a8 Compare June 3, 2026 17:58
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