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.
- 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.
- 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. - Install the storage App on that one repository only. It has contents write there, which it uses to add releases and index files.
- Choose your registry name. It becomes your hostname,
your-name.privatecrates.dev, and is saved asprivatecrates.tomlin the storage repository. - 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.
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 forgetsregistry = "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.
cargo install cargo-credential-privatecrates --locked2. Add the registry
Commit this to the repository of every project that uses private crates, or put it in ~/.cargo/config.toml.
[registries.acme]
index = "sparse+https://acme.privatecrates.dev/index/"
credential-provider = ["cargo-credential-privatecrates"]3. Depend on private crates
[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.
# Sign in now (optional: the first build does it too)
cargo login --registry acme
# Forget the stored token
cargo logout --registry acmeWhat 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.
[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”.