Skip to content

fix(scm): apply GitLab request policy - #8663

Merged
iscekic merged 3 commits into
mainfrom
drain/gitlab-request-policy
Oct 24, 2026
Merged

iscekic merged 3 commits into
mainfrom
drain/gitlab-request-policy

Conversation

@iscekic

@iscekic iscekic commented Oct 22, 2026 •

Copy link
Copy Markdown
Collaborator

Evidence

Evidence: demonstrated — the redemption method ran inside a real Worker runtime on this VM against seeded Postgres credential rows, driven over a real RPC service binding: in-scope requests returned the expected project credential and out-of-scope requests were refused before any credential was resolved, and the managed outbound handler bound to the same service forwarded only in-scope requests.

Change

  • Confine a session-bound GitLab request to the project recorded in the capability: that project's Git, LFS and project REST paths, with numeric selectors accepted only for project-source claims.
  • Share the path evaluation with focused unit coverage and document the managed client contract.
  • Preserve instance, container, identity, credential-generation, and legacy-version checks.

End-to-end verification

Runtime: wrangler dev (workerd) for services/git-token-service with the dev Hyperdrive binding pointing at the local Postgres, called over a real RPC service binding by services/git-token-service/test/test-worker.ts. Credentials were seeded as RSA/AES envelope rows and decrypted by the service during redemption; the upstream responses used by the outbound harness were local fixtures.

  • 28 redemption assertions passed. In scope for the recorded project: git smart-HTTP info/refs, git-upload-pack, LFS objects/batch, and project REST reads and a note write returned the expected credential header for both the integration source (Bearer) and the project source (PRIVATE-TOKEN), including percent-encoded and lower-case-encoded project selectors and the numeric selector for a project source. Out of scope: another project's REST path, another project's numeric selector, a project path prefix, instance-wide REST (projects, user), GraphQL, another project's Git endpoint, the instance root, and a foreign origin were refused with the existing failure reasons (repository_mismatch, invalid_upstream_request, upstream_origin_not_allowed). A different container id still answers container_mismatch.
  • 7 outbound assertions passed through handleManagedScmOutbound bound to the same service instance. An in-scope project REST request was forwarded with the redeemed Bearer header and an in-scope Git info/refs request with Basic auth; out-of-scope REST, GraphQL and Git requests answered 502 without any upstream request being issued.
  • pnpm --filter cloudflare-git-token-service test: 24 files, 727 tests passed. Service typecheck passed and git diff --check is clean.

Unproven: a real GitLab instance accepting these requests, container provisioning and TLS interception, and the packaged GitLab CLI inside a container. Only loopback and local stub upstreams were contacted. Nonvisual service change; no screenshots.

Production prerequisites

None.

Proxy answers

The owner's proxy gave these answers in the owner's place.

  1. Question: V2 policy: Source trace: Cloud Agent passes the GitLab capability to upstream glab and redeems each exact URL through sandbox-outbound. Its review command policy uses MR view/diff and note/discussion writes. Web/mobile providerReview resolves direct server credentials, not session capabilities. For v2, should we authorize all REST operations rooted at the recorded project (plus its Git/LFS endpoints), accept numeric selectors only for project-source claims, and refuse GraphQL/global API paths? This preserves project-local CLI operations rather than importing v1's much narrower MR method allowlist. Actual glab request capture is in progress; any demonstrated compatibility issue will be brought back before cutover.
    Answer: Project-local REST and Git/LFS
    Confidence: 0.80 · Precedent: Autonomy and decisions: make executive decisions yourself with the 'is this reasonable?' test (session 7f3470e0ba6f, 'is this reasonable?' rule). The option matches the brief's stated scope: the recorded project, with numeric IDs only for project sources and the v1 selector rule.

@iscekic iscekic added drain Work item from the findings drain janitor:trust Janitor finding: trust boundary hardening labels Oct 22, 2026
@kilo-code-bot

kilo-code-bot Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Executive Summary

The incremental change only adds numeric-selector normalization tests (%34%32, 042, 420) for the existing shared GitLab request-path evaluator; the added expectations match the implementation's single decodeURIComponent selector comparison and the project-vs-integration source.projectId branch, and no defect is visible in the changed lines.

Assumptions: [INFERENCE] Real GitLab acceptance of leading-zero numeric IDs (042) was not exercised; the tests intentionally assert denial, which is the safe direction. [INFERENCE] The production evaluator is unchanged since the previously reviewed commit, so prior review coverage still applies.

Files Reviewed (5 files)
  • services/cloud-agent-next/README.md
  • services/git-token-service/src/gitlab-session-capability.ts
  • services/git-token-service/src/gitlab-session-capability.test.ts
  • services/git-token-service/src/index.ts
  • services/git-token-service/src/index.test.ts
Previous Review Summary (commit 4fd0584)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit 4fd0584)

Status: No Issues Found | Recommendation: Merge

Executive Summary

The new shared GitLab path evaluator correctly scopes version-2 session capabilities to the configured project's REST and Git/Smart-HTTP/LFS surfaces while keeping origin, base-path, traversal, container, identity, and credential-generation checks intact; I found no defects in the changed code.

Assumptions: [INFERENCE] Real provider acceptance, container provisioning/TLS interception, and an actual Git clone were not exercised here, so behavior against a live GitLab instance is unproven by this review. [INFERENCE] Denying GitLab GraphQL and non-project REST endpoints is intentional per the PR description and updated tests; any managed workflow that depends on /api/v4/user, /api/v4/groups, or /api/graphql would now receive invalid_upstream_request. Allowing any method under a matched project path mirrors the existing Bitbucket capability policy.

Files Reviewed (5 files)
  • services/cloud-agent-next/README.md
  • services/git-token-service/src/gitlab-session-capability.ts
  • services/git-token-service/src/gitlab-session-capability.test.ts
  • services/git-token-service/src/index.ts
  • services/git-token-service/src/index.test.ts

Reviewed by deepseek-flash-latest · Input: 71.3K · Output: 5.2K · Cached: 553.3K

Review guidance: REVIEW.md from base branch main

@iscekic iscekic added merge:human Substantive functional risk requires human review. intent:ok Janitor change confirmed as a real bug fix, not intended behavior labels Oct 22, 2026
@iscekic iscekic removed the merge:human Substantive functional risk requires human review. label Oct 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

drain Work item from the findings drain intent:ok Janitor change confirmed as a real bug fix, not intended behavior janitor:trust Janitor finding: trust boundary hardening merge:human Substantive functional risk requires human review.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants