Module

Artifacts

Git repositories for your own customers, backed by Cloudflare Artifacts. Owned by a person or an organization, read in the Worker or cloned over the wire, with short-lived tokens the kit mints against a grant you control.

@pithy-sh/artifacts

terminal
pithy add artifacts

What it is for

Handing your customers a real git repository without running a git server. A content product that versions documents, a tool that gives each team its own repository of configuration, or an app that keeps its own history in git and never shows anybody a clone URL.

A repository is owned by a person, or by an organization when organization is composed. Everybody else gets a grant, read or write, which you write. An owner always has write, and nothing else gives access.

A git client gets a token through a credential helper: a page of shell that calls your Worker with your app's own credential and mints a fresh token for every clone, fetch and push. The token lives fifteen minutes by default and never more than an hour, so the only long-lived credential is the one you already revoke in auth.

A management client can see who holds a key. It reads every repository with its grants and history, and every token on one with the person it was minted for, and it can revoke one token or every live one, each with a reason and an audit event. When a person is purged, every repository they own goes with them, with its contents and every grant on it, and every grant they hold on somebody else's.

What it sits on

Cloudflare Artifacts, with the records in your D1.

Cloudflare Artifacts is versioned storage that speaks git. It holds the repositories and answers every git client. Your Worker reads history, commits, trees, blobs and files through the binding, so an app that versions its own content never has to expose git at all.

Owners, grants and a record of every token the kit mints live in four pithy_artifacts_* tables. The record holds the token's id, its repository, the person, its scope and its expiry, and never its value, because Cloudflare's own token list names no holder.

Each environment gets its own namespace, so production's rate limit is production's alone, and pithy feature destroy deletes a feature's repositories with it.

  • Artifacts
  • D1

The honest bit

Workers Paid only, and a removed grant is not a revoked token.

Artifacts runs on the Workers Paid plan and nowhere else. On a Free plan the Worker deploys and the first create is refused, at runtime, in production. Cloudflare bills it from 14 October 2026: $0.15 per 1,000 operations past 10,000 a month, and $0.50 per GB-month past 1 GB.

Taking away somebody's grant does not end a token they already hold. It keeps working until it expires, which is why the ceiling is an hour. To stop them now, remove the grant and then revoke the tokens.

It does not decide what your roles mean in git terms, does not fork or import a repository, and does not meter storage. A repository is capped at 1 GB and an account at 1 TB, and what to do about a large one is your call. It is not for your own source code either. That is what your own git host is for.

If you build it yourself

Cloudflare removed the git server. It did not remove the work on top.

Storage that speaks git is the easy half. Every product that hands out repositories builds the same four things around it.

A name nobody can probe

A namespace is flat, so one tenant's docs collides with another's. Every repository here is named with a random UUID, and a caller with no grant gets a 404 byte-identical to the one for a repository that does not exist.

Roles that map onto two scopes

A git token is read or write, and nothing in between. Somebody has to decide what each of your roles means in those terms, and write it down per person.

A revocation window you chose

Cloudflare answers a create with a day-long write token. The kit revokes it before it answers, and every token it mints after that lives as long as you said.

Knowing who holds a key

Cloudflare lists a repository's tokens without saying whose they are. Answering who can still push means recording every mint yourself, and saying so when a token was minted somewhere else.

A credential helper that refuses cleanly

git asks for a credential on every operation. A helper has to mint each time, keep your app's credential off the command line, and stop git cold when the mint is refused.

terminal
pithy add artifacts

In the dashboard

The management routes are there. The pane is not yet.

Reading repositories and tokens, and revoking a token, are control-plane routes behind their own scopes. The dashboard has no artifacts pane yet, so today they are for a management client you write yourself.

Add it, and get on with the feature.

One command installs the package, wires its bindings into every environment your project declares, and runs its migrations.