← All docs
TensorOrigin — Git storage engine (Closed beta)Closed beta

TensorOrigin documentation.

TensorOrigin is an internal TensorPlane Git storage engine: a single daemon that serves Git protocol v2 smart-HTTP over TLS behind capability tokens, with object storage as the authoritative store and local Git directories as disposable caches. It is in Closed beta, it is not a product SKU, it is not billed, it is not a public Git host, and it is not a GitHub replacement.

Status

What TensorOrigin is today.

TensorOrigin is an internal Git storage engine, intended for dogfood use so TensorPlane can exercise the platform end to end. It is literally not a product SKU, not a billed surface, and not a public Git host. It is not a GitHub replacement for the money-path review and publication authority, and it is not tenant identity, authorization, entitlements, audit, billing, or a console — those stay in the Go control plane.

The dogfood serve path is implemented. tensororigin serve exposes the Git v2 smart-HTTP endpoints over TLS behind capability-token auth, backed by the durable-ack engine (ADR 0002 §4) and disposable local caches that rebuild from the object store (ADR 0002 §7). In this build git_protocol_enabled() is true and control_plane_integration_enabled() stays false — the daemon verifies capability tokens and never calls the control plane. This page documents the pinned commit f71931d9; interfaces can still change.

Concepts

The model to hold in your head.

  • org_id and repo_id — a repository is addressed by two opaque UUIDs. The clone path is /git/<org_id>/<repo_id>.git; both ids are allocated by the admin endpoint and carry no tenant meaning here.
  • Object storage is authoritative; local caches are disposable. A write is durable only once the required objects and the conditional index publication have committed. The local Git directories under --cache-dir are caches — complete cache loss still recovers every acknowledged write from the store.
  • Durable ack (ADR 0002 §4) — a push is acknowledged to the Git client only when all four hold: every named pack has a successful PutIfNoneMatch (or a Head proving the same digest exists); the generation document PutIfNoneMatch succeeded; the live-index CAS returned 2xx; and a confirming Get shows the new generation with a matching digest. Local ref updates happen after ack and are not part of it.
  • Capability tokens — every Git RPC requires a token in the wire form TO1.<org>.<repo>.<actions>.<expiry>.<hmac_hex>, bound to (org_id, repo_id, actions, expiry). Actions are r, w, c, a (read, write, create, admin). This is distinct from the daemon secret (--token), which signs tokens and gates the admin endpoint.
Prerequisites

What you need to build and run.

  • Rust 1.98.1, pinned in rust-toolchain.toml.
  • Stock git 2.39+ as the client (no libgit2 / JGit / go-git).
  • openssl and curl for the dogfood recipe.
  • An S3-compatible object store: MinIO for test and CI; an S3-compatible store in production.
  • Do not put CARGO_TARGET_DIR on /tmp (tmpfs OOM); use the repo-local target/.
Build

Build and test the binary.

The qualification tests download a static MinIO binary into target/githost-tools (or $CARGO_TARGET_DIR/githost-tools); override the path with GITHOST_MINIO_BIN. Docker is not required. Passing against MinIO does not certify any particular production object store.

Run

tensororigin serve.

The only subcommand is serve. A missing or unknown subcommand prints the usage line and exits 2; a runtime error prints tensororigin: <err> and exits 1. On startup the daemon logs one readiness line to stdout beginning tensororigin: listening on https:// with the bound address. The object store is configured for region us-east-1 with a 60-second request timeout.

FlagRequiredDefault / envMeaning
--listen ADDROptional127.0.0.1:0Address to bind. The default picks an ephemeral loopback port; the chosen port is printed on the readiness line.
--cert PRequired—PEM certificate. TLS is mandatory; there is no plaintext HTTP listener.
--key PRequired—PEM private key for the certificate.
--token SRequired—Daemon HMAC / admin secret. It signs capability tokens and is the credential the admin endpoint checks.
--cache-dir DRequired—Directory for the disposable local Git caches. Safe to wipe: caches rebuild from object storage.
--s3-endpoint URequired (or env)TENSORORIGIN_S3_ENDPOINTObject-store endpoint URL. Falls back to the env var of the same name.
--s3-bucket BRequired (or env)TENSORORIGIN_S3_BUCKETBucket that holds the authoritative packs and index. Env fallback of the same name.
--s3-access-key KRequired (or env)TENSORORIGIN_S3_ACCESS_KEYObject-store access key. Env fallback of the same name.
--s3-secret-key SRequired (or env)TENSORORIGIN_S3_SECRET_KEYObject-store secret key. Env fallback of the same name.
--threads NOptional8Worker thread count for the server.
--token-ttl-secs NOptional3600Lifetime, in seconds, of the capability tokens the admin endpoint mints.

The four object-store values may come from the flags or from their environment variables — TENSORORIGIN_S3_ENDPOINT, TENSORORIGIN_S3_BUCKET, TENSORORIGIN_S3_ACCESS_KEY, and TENSORORIGIN_S3_SECRET_KEY — but one of the two must be present or startup fails. Run the built binary directly:

Quickstart

The dogfood script, end to end.

scripts/dogfood.sh runs the whole loop. It needs openssl, curl, git 2.39+, and either a running S3-compatible store (set TENSORORIGIN_S3_*) or a minio binary on PATH or at $MINIO_BIN.

It generates a self-signed cert, launches the daemon, creates one repository through the admin endpoint, and prints a ready-to-run git clone command. You then commit and push main, clone again into a new directory to see the commit, and wipe the cache to prove the next clone rebuilds from the store. When no TENSORORIGIN_S3_* is set it starts MinIO at http://127.0.0.1:9000 with bucket and access key tensororigin. Everything lands under a /tmp/tensororigin-dogfood.XXXXXX directory that is not cleaned up, so you can inspect it.

Create a repository

POST /admin/repos.

The admin endpoint allocates a repository and mints a read+write token. The presented credential must equal the daemon secret (--token), as a Bearer token or a Basic password; otherwise it returns 401 admin authentication required.

The JSON response carries org_id, repo_id, clone_path (/git/<org_id>/<repo_id>.git), and token — capture the token, it is the capability token for that repository.

Clone and push

Clone, commit, push main.

Clone over HTTPS, passing the capability token as an extra header. The generated cert is self-signed: trust it with http.sslCAInfo, or, for a throwaway local run only, disable verification with http.sslVerify=false — never against a real backend. ABasic credential works too, with the token as the password.

Cache loss and rebuild

The caches are disposable.

The local Git directories under --cache-dir are disposable. Wipe the cache directory contents and clone again: the daemon reconstructs the repository from object storage (TENSORORIGIN_S3_ENDPOINT and the rest of the TENSORORIGIN_S3_* values). Every acknowledged write survives a complete cache loss.

At the pinned commit f71931d9 there is no fence and no pinned-generation read lifetime. Each smart-HTTP request re-reads the committed generation from the object store (read_committed) and rebuilds the cache directory from that generation’s named packs (ensure_generation) before serving; the cache is never treated as truth. If the object-store read fails, the request surfaces as HTTP 500 git error: … (see the status table) and the client should retry.

ADR 0002 §7 specifies the future design contract: reads that pin a generation, so a read starting after a durable ack of generation G observes at least G — catching lagging replicas up from the store before serving — with a bounded pin lifetime and a retryable service-unavailable response (HTTP 503) when the freshness read fails. That contract is not yet implemented at f71931d9.

Endpoints

Endpoints and status codes.

MethodPathAuthNotes
POST/admin/reposDaemon secretAllocate a repository (new org and repo UUIDs) and mint a read+write token. Localhost dogfood convenience.
GET/git/<org>/<repo>.git/info/refs?service=Capability tokenRef advertisement. service must be git-upload-pack or git-receive-pack; anything else (including dumb HTTP) is refused.
POST/git/<org>/<repo>.git/git-upload-packRead tokenFetch / clone. Requires a token granting Read.
POST/git/<org>/<repo>.git/git-receive-packWrite tokenPush. Requires a token granting Write, and passes the receive-pack admission gate first.
CodeWhen
400bad request body; or git protocol v1 is not supported; use v2 (an explicit Git-Protocol version=0/version=1); or a rejected ref name or pack (Rejected -> 400).
401authentication required on a Git RPC with no or an invalid token; admin authentication required on /admin/repos without the daemon secret.
403smart HTTP git protocol v2 required — info/refs without a known service= (dumb HTTP is refused).
404not found — a path outside /git/, a git-receive-pack (push) to a repository that does not exist (RepoNotFound), or /info/lfs (LFS is not served).
500git error: … — any other engine or object-store failure. A clone / fetch / info-refs of a missing or unreadable repository takes the read path and surfaces here as 500, not 404; create failed: … is returned when /admin/repos cannot allocate a repository.
503receive-pack admission queue full; retry with Retry-After: 1 — the per-repo depth (8) or per-replica ceiling (32) is saturated. Retry; no refs were touched.

A single pack is capped at 512 MiB (pack exceeds 512 MiB). The receive body ceiling is that plus 16 MiB, but a body over the ceiling is refused up front by the body reader with 400 bad request body — the internal receive body exceeds limit message is not what the client sees. Either overflow is a deterministic rejection, not a partial write.

Compatibility

What the protocol supports and rejects.

The baseline client is stock Git 2.39+ speaking protocol v2 over HTTPS. The matrix below is the ADR 0003 §1 target matrix: the ADR 0003 §1 target column is the planned disposition, and the At f71931d9 column is what the pinned build actually enforces. Only the refusals enforced in code fail deterministically before any effect — protocol v1 (400), dumb HTTP (403), a missing or invalid capability token (401), the partial-clone filter (uploadpack.allowFilter=false), and the absent SSH listener. Rows marked not implemented or not advertised are ADR targets, not behaviour you can rely on at this commit.

FeatureADR 0003 §1 targetAt f71931d9
HTTPS smart HTTP + TLS, Git protocol v2SupportEnforced — v2 required; a v1 request is refused 400
SHA-1 clone / fetch / pushSupportEnforced over HTTPS + v2
Atomic multi-ref push, report-status / report-status-v2SupportEnforced — all-or-nothing receive
ofs-delta / thin-pack on receiveSupport (with fsck)Enforced — receive.fsckObjects / transfer.fsckObjects = true
Partial clone / filterRejectRefused — uploadpack.allowFilter = false (sealed)
Git protocol v1, git:// and dumb HTTPRejectRefused — 400 (v1) / 403 (dumb HTTP)
SSH transportRejectNo SSH listener; the daemon binds HTTPS only
Anonymous accessRejectRefused — every RPC requires a capability token
Git LFS (/info/lfs)Reject/info/lfs returns 404
Server-side hooksReject (never execute)Sealed config; hooks stored as blobs only, never run
SHA-256 object formatRejectNot implemented / not advertised (ADR 0003 target: reject)
Shallow pushRejectNot implemented / not advertised (ADR 0003 target: reject)
bundle-URIRejectNot advertised (ADR 0003 target: reject)
Export (git bundle / archive via authorized API)Support (future, tensororigin#4)No export route — not available
Host import / mirror from another Git hostRejectNot implemented (no import path)

Ref names are constrained (ADR 0003 §4). Allowed by default: refs/heads/*, refs/tags/*, and symbolic HEAD. Rejected: refs/replace/*, refs/pull/*, names containing .., control characters, a leading or trailing /, a .lock suffix, the sequence @{, or a path component .git; the maximum ref name is 255 bytes of UTF-8.

Troubleshooting

Common errors.

  • TLS / self-signed cert errors on clone — trust the cert with -c http.sslCAInfo=<cert.pem>, or for a throwaway local run only, -c http.sslVerify=false. Never disable verification against a real backend.
  • 401 authentication required — the Git RPC had no token or an invalid one; 401 admin authentication required — the daemon secret did not match on /admin/repos.
  • 403 smart HTTP git protocol v2 required — the request hit info/refs without a known service= (dumb HTTP is not served).
  • 400 git protocol v1 is not supported; use v2 — a client asked for Git-Protocol: version=0 or version=1. Use a stock Git 2.39+ client.
  • 503 receive-pack admission queue full; retry — honor Retry-After: 1 and retry; the per-repo depth (8) or per-replica ceiling (32) was saturated. No refs were touched.
  • A ghp_/ghs_ or other GitHub-shaped credential is rejected before any HMAC work — mint a TO1. token from the admin endpoint instead.
  • Wrong-repo or expired token — the token is bound to (org_id, repo_id, actions, expiry); a token for another repository, or one past its TTL, is rejected.
  • Pack too large — a single pack over 512 MiB is rejected; split the push.
  • Cache directory wiped — expected and safe; the next clone rebuilds from object storage.
Not available

What this build does not do.

This dogfood scope is HTTPS + v2 only. The following are not implemented here:

  • SSH transport — SSH is not served; no sshd listens.
  • Git protocol v1, git://, and dumb HTTP.
  • Git LFS (/info/lfs returns 404), partial clone / filter, and the SHA-256 object format.
  • Replicas, compaction, garbage collection, and restore.
  • Export API — there is no git bundle / archive endpoint; export is an ADR 0003 target (tensororigin#4), not a route here.
  • Repository import or migration from another Git host.
  • Control-plane APIs — identity, entitlements, audit, and billing stay in the control plane.
  • Non-stock clients (libgit2, JGit, go-git) until they pass the HTTPS + v2 fixtures.
Access

How to get into the Closed beta.

TensorOrigin is invite-only in the Closed beta. Request early access, or contact us; the TensorPlane team provides build instructions and a pinned commit reference to Closed beta participants.

Billing

How TensorOrigin is priced.

TensorOrigin is not a product SKU and is not billed. The Git storage engine and its capability tokens carry no price. For the products that are billed, see billing.

Get early access to the platform.

Every product is included in one platform subscription. Request early access and we'll onboard your team hands-on — free while we build toward launch.