Skip to content

feat: add external repository credential resolver - #564

Open
jholm117 wants to merge 2 commits into
truefoundry:mainfrom
jholm117:feat/external-repository-credential-resolver
Open

feat: add external repository credential resolver#564
jholm117 wants to merge 2 commits into
truefoundry:mainfrom
jholm117:feat/external-repository-credential-resolver

Conversation

@jholm117

@jholm117 jholm117 commented Sep 2, 2026

Copy link
Copy Markdown

Summary

Adds an opt-in, provider-neutral HTTP adapter for resolving short-lived Git credentials in packaged server deployments.

Depends on #559. Once that PR merges, this diff will contain only the external resolver follow-up.

Closes #562

Changes

  • configure the resolver endpoint, optional Authorization header, timeout, and response-size limit through environment variables
  • send only the opaque provider reference and repository authorization context on each turn
  • validate bounded Git credential-store responses and return redaction-safe failures without logging or persisting resolver bodies
  • preserve the existing injectable in-process resolver and unconfigured rejection behavior
  • document the resolver protocol and add unit coverage for refresh, authentication, cancellation, timeouts, size limits, invalid responses, and secret-safe errors

How was this tested?

  • pnpm format:check
  • pnpm typecheck
  • pnpm lint:ci
  • pnpm build
  • pnpm test (Node 24)

Checklist

  • I have read the contributing guidelines
  • pnpm build, pnpm test, pnpm typecheck, pnpm lint:ci, and pnpm format:check pass locally
  • Tests added/updated where it makes sense
  • No hand-edits to generated code
  • Docs / .env.example updated for the new configuration

Note

High Risk
Changes span private Git credential handling, external HTTP trust boundaries, and sandbox git exec during session init—security-sensitive paths where misconfiguration or resolver bugs could leak or mishandle credentials.

Overview
Sessions can optionally bind a persistent Git checkout in the sandbox via a new repository field (HTTPS URL, ref, sandbox path, read_only / read_write, optional credential_provider_ref). Checkout metadata is stored on the session; secrets are resolved each turn and are not persisted. Session create/get-or-create APIs accept repository, admission requires a configured sandbox provider, and SQLite/Postgres migrations add a repository column.

Sandbox behavior provisions the repo idempotently on init (fetch/update without wiping resumed work), applies read-only push blocking when configured, writes Git credential-store content before checkout, and TurnResourceResolver can force a sandbox when a session has a repository even if the agent disables sandbox in spec.

TrueForge server adds an optional HTTP repository credential resolver (REPOSITORY_CREDENTIAL_RESOLVER_*): per turn it POSTs provider ref plus tenant/session/user and repository context, validates bounded Git credential-store responses, and fails closed with redaction-safe errors. When unset, sessions with credential_provider_ref still reject via the existing injectable rejectUnconfiguredRepositoryCredentials path. Docs and .env.example describe the protocol.

Reviewed by Cursor Bugbot for commit a71e47f. Bugbot is set up for automated code reviews on this repo. Configure here.

@changeset-bot

changeset-bot Bot commented Sep 2, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: a71e47f

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@truefoundry/trueforge Minor
@truefoundry/trueforge-core Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

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.

Support external repository credential resolvers in standalone deployments

1 participant