/ opencodehub / docs / features / federation.md
swadhinbiswas feat: optimize Docker CI/CD builds, refine site-wide UI aesthetic, and remediate secrets · 8/19/2026
3846c8b
96 lines · 6.1 KB
Raw Download

Federation & Cross-Instance PRs

Connect two self-hosted OpenCodeHub instances so contributors on one can fork, contribute, and open pull requests against repositories hosted on another.

Federation lets a user on instance A fork a repository hosted on instance B, push branches back to B, and open cross-instance pull requests whose head branch lives on A's fork. B pulls the head from A's fork URL, creates a normal PR (with headRepositoryId unset), and the usual review and merge pipeline applies.

Table of Contents

Overview

The two instances interoperate over HTTP. Instance A talks to B's REST API using a Personal Access Token belonging to the contributing user on B. All git traffic flows over the normal smart-HTTP protocol using basic auth with that PAT.

┌─────────────────┐   import (clone URL + PAT)   ┌─────────────────┐
│  Instance A     │ ───────────────────────────▶ │  Instance B     │
│  bob/fedbase    │                              │  alice/fedbase  │
│  (fork)         │ ◀─────────────────────────── │  (upstream)     │
│                 │   push-upstream (git push)   │                 │
│                 │ ───────────────────────────▶ │                 │
│                 │   federation/open-pull       │  external-pulls │
└─────────────────┘ ◀─────────────────────────── └─────────────────┘

How It Works

  1. Import (fork): On instance A, import https://B/alice/fedbase.git and authenticate with a PAT for the user on B. A detects that the source is another OpenCodeHub instance (GET /api/instance) and records the relationship as forkedFromUrl.
  2. Contribute back: A can push any branch on its fork back to B (federation/push-upstream). B's existing git-receive-pack authorizes the push via canWriteRepo — B controls who may contribute.
  3. Cross-instance PR: A calls federation/open-pull on B. B validates the fork URL (SSRF check), fetches the head branch from A's fork into the B repo, computes diff stats, and creates a PR whose head lives on A's fork.
  4. Review & merge: The PR is a normal PR on B. Reviews, approvals, CI, and the merge queue all apply. Merging fetches the head ref and merges it into the base branch.

Setting Up Federation

Federation is enabled out of the box. Two environment variables control SSRF behavior:

Variable Purpose
FEDERATION_ALLOW_LOCALHOST Set true to allow fetching from localhost/loopback URLs. Only for two-instance testing on a single host or a trusted private network. Never enable in production.

The upstream instance does not need any special config beyond the normal collaboration settings: the A user simply needs read access (to see the repo) and write access (to push branches and open PRs).

Forking a Repository from Another Instance

On instance A, use the normal Import Repository flow:

  1. Paste the upstream clone URL, e.g. http://instance-b.local/swadhinbiswas/fedbase.git.
  2. Enter the auth username and a PAT for the user on instance B (the username must match the B account, e.g. bob).
  3. Complete the import. Instance A records forkedFromUrl and stores an encrypted mirror PAT so it can push back later.

For cross-instance PRs the source URL must be fetchable by B — the fork must be on a host B can reach, and the fork repo must be readable by B (public, or accessible with the embedded PAT).

Contributing Back

From the fork's repository page on A, the Federation panel offers Push branch to upstream:

  • Pick a branch on the fork.
  • A pushes branch:branch to the upstream clone URL, authenticating with the stored B user's PAT.

B's permission model decides whether the push succeeds — the B user must be a collaborator (or the repo must allow external writes).

Cross-Instance Pull Requests

From the same Federation panel, Open cross-instance PR:

  1. A calls POST /api/repos/{owner}/{repo}/external-pulls on B (server-to-server) with the fork URL, head branch, base branch, title, and body.
  2. B validates the fork URL, fetches the head into the B repo, computes additions/deletions/changed files, and creates the PR.
  3. The PR's head branch resolves to the fetched ref on B, so the diff, comments, and merge all work normally.

Endpoints

Endpoint (on B) Purpose
POST /api/repos/{owner}/{repo}/external-pulls Create a PR whose head is fetched from an external fork URL
GET /api/instance Instance metadata probe used for detection

Permissions

  • Import on A: requires a valid PAT for the B user.
  • Push upstream: B's git-receive-pack requires the B user to have write access to the repo.
  • Open a cross-instance PR: B's external-pulls endpoint requires the caller to have read access plus either write access to the repo, or the repo must have Allow external pull requests enabled (repo → Settings → Federation).
  • Merge: normal PR merge gates apply (approvals, required checks, branch protection).

SSRF Protection

Every server-initiated fetch (import on A, external-pulls on B) runs through validateGitCloneUrl, which blocks private ranges, cloud metadata endpoints, and non-HTTP(S)/git/ssh schemes. The localhost bypass is only available when FEDERATION_ALLOW_LOCALHOST=true, and callers gate it explicitly.

Tokens embedded into fetch/push URLs are used transiently and never persisted.