Set up a registry

About ten minutes for an organisation admin, then one config file and one install for each developer.

Works with AI coding agents

A coding agent such as Claude Code can do most of this for you with the cargo privatecrates CLI, and stops to give you a link where GitHub needs a person. See Set up with an AI agent.

For the organisation

Sign in on the account page with GitHub and pick your organisation. The checklist there walks through these steps and ticks each one off as GitHub reports it done. Only organisation admins can complete them.

  1. Install the reader App on all repositories, or on those that own crates. It can read repository metadata and organisation membership, nothing else. PrivateCrates uses it to sign developers in and to ask GitHub what each person can access.
  2. Choose the storage repository: a new private repository, conventionally crates-store, or an existing empty one. It holds your registry and nothing else: the index, and every crate file as a release. Enable immutable releases in Settings → General → Releases. Immutability means that once a version is published, nobody (including us) can change its bytes.
  3. Install the storage App on that one repository only. It has contents write there, which it uses to add releases and index files.
  4. Choose your registry name. It becomes your hostname, your-name.privatecrates.dev, and is saved as privatecrates.toml in the storage repository.
  5. Choose a plan. Organisations with 5 or fewer members are free, with nothing to choose. Larger ones start a 3-month free trial with one click and no card; see pricing.

The settings file

Settings live in your repository, not in our database, so you change them with a pull request and the git history is the audit log.

privatecrates.toml
slug = "acme"             # your hostname
name_clash = "refuse"     # or "warn"
ci_read = "organisation"  # or "same-access"
  • name_clash: publishing a crate whose name also exists on crates.io is refused by default, because a developer who forgets registry = "acme" would get the public crate.
  • ci_read: with "organisation", any workflow in the organisation can read every crate. With "same-access", a workflow can read only the crates whose owning repository its own repository could read.

For each developer

1. Install the credential provider

cargo-credential-privatecrates is open source and implements Cargo’s credential provider protocol, so every Cargo command works unchanged.

shell
cargo install cargo-credential-privatecrates --locked

2. Add the registry

Commit this to the repository of every project that uses private crates, or put it in ~/.cargo/config.toml.

.cargo/config.toml
[registries.acme]
index = "sparse+https://acme.privatecrates.dev/index/"
credential-provider = ["cargo-credential-privatecrates"]

3. Depend on private crates

Cargo.toml
[dependencies]
story_engine = { version = "0.2", registry = "acme" }

The first time Cargo needs a token, the provider prints a code and opens GitHub’s device sign-in. Approve it in the browser and you are done: the refresh token goes into your operating system’s keyring, and the 8-hour access token is refreshed silently from then on.

shell
# Sign in now (optional: the first build does it too)
cargo login --registry acme
# Forget the stored token
cargo logout --registry acme

What that token can do

The token comes from the reader App, so it can list repository metadata and nothing more. If it were stolen, it could not read code, crates or anything else.

4. Make crates publishable

Set publish so a crate can only ever go to your registry, and repository so its first publish knows which repository owns it.

Cargo.toml
[package]
name = "story_engine"
version = "0.2.0"
# The owning repository: it must be in your organisation.
# In a monorepo, a link to the crate's directory works too.
repository = "https://github.com/acme/story-engine"
# Publish only to your registry, never to crates.io by accident.
publish = ["acme"]

Then set up CI and publish from a tag.

Using gh or a personal access token instead

Tokens from gh auth token, and classic or fine-grained personal access tokens, also work through Cargo’s cargo:token-from-stdout provider. We recommend the credential provider instead, because those tokens are usually far broader than the registry needs.

SAML single sign-on

If your organisation enforces SAML SSO, GitHub requires an active SSO session for the token. When it is missing, the registry answers with an error saying so and the URL to authorise, rather than a confusing “not found”.