Skip to content

Build An HTTP Remote

An HTTP remote lets Graft clients synchronize through infrastructure you operate. The protocol defines repository discovery, immutable object transfer, and atomic ref updates. Your service defines identity, access control, tenancy, limits, and storage.

PackageChoose it when
@eidos.space/graft-remoteYou need the framework-neutral Fetch protocol engine and will write a routing adapter.
@eidos.space/graft-remote-honoThe service already uses Hono.
@eidos.space/graft-remote-cloudflareThe service will use R2 and SQLite Durable Objects.
Terminal window
pnpm add @eidos.space/graft-remote-hono hono
import { Hono } from "hono";
import {
GraftProtocolError,
createGraftRemote,
} from "@eidos.space/graft-remote-hono";
const app = new Hono();
const remote = createGraftRemote({
async authenticate({ request }) {
const principal = await authenticateRequest(request);
if (!principal) {
throw new GraftProtocolError(401, "unauthorized", "Authentication required");
}
return principal;
},
async authorize({ action, principal, repository }) {
if (!(await canAccess(principal, action, repository))) {
throw new GraftProtocolError(403, "forbidden", "Repository access denied");
}
},
backend({ repository }) {
return repositories.open(repository.id);
},
});
app.route("/graft", remote);
export default app;

This example serves repositories below https://example.com/graft/<namespace>/<repository>. The backend must provide atomic compare-and-swap and compare-and-delete for mutable refs, create-only writes for immutable objects, byte-range reads, and bounded sorted listing.

Start from the Cloudflare reference service

Section titled “Start from the Cloudflare reference service”

The repository includes a deployable composition under services/graft-remote-cloudflare.

Terminal window
cd services/graft-remote-cloudflare
pnpm install --frozen-lockfile
cp .dev.vars.example .dev.vars
pnpm types
pnpm dev

Before deployment, create or rename the configured R2 buckets, store the token as a Worker secret, and run the checks documented in the service README.

The reference service uses one deployment-wide bearer token. Replace its authentication and authorization callbacks before using it for multiple users or tenants.

Use HTTPS in production and pass credentials through the process environment:

Terminal window
export GRAFT_REMOTE_TOKEN='grt_...'
graft remote add origin 'https://example.com/graft/acme/archive'
graft ls-remote origin
graft push origin main

Never put the token in the URL or .graft/config.toml. Use graft+http:// only for a local service you control.