Private Rust crates, signed for by GitHub

A Cargo registry for your GitHub organisation. Whoever can read a repository can use its crates; whoever can push to it can publish them. No new accounts, no keys to hand out, no access lists to keep in sync.

$100 per organisation per month after the trial. Unlimited developers, SSO included.

From repository to cargo build in three steps

  1. Install two GitHub Apps

    The reader App sees repository metadata, nothing more. The storage App writes to one private repository you create, which holds the index and every crate file.

  2. Point Cargo at your registry

    Three lines of config and our credential provider. The first build signs each developer in with GitHub; their existing access decides what they can use.

  3. Publish from CI with a tag

    Plain cargo publish in GitHub Actions. Every version becomes an immutable GitHub release with signed proof of the workflow that built it.

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

Security that was already yours

A registry is a supply-chain component. We built this one so that the answer to “what if PrivateCrates is compromised?” is short.

GitHub is your identity provider

Every permission decision is GitHub’s. SAML SSO, SCIM provisioning and offboarding apply with nothing to configure: remove someone from a team and their access to its crates ends within seconds. SSO is part of the one price, with no SSO tax.

We hold nothing that matters

Your index and crate files live in a repository your organisation owns. Developers hold tokens that can only read repository metadata; CI holds one-hour read tokens. We keep no database, and every write we make is a verified commit you can audit.

Don’t trust us, verify us

Every version is an immutable GitHub release carrying a GitHub-signed record of the workflow that built it. The open-source privatecrates-verify runs in your own CI and reports anything we should not have done, even if we are fully compromised.

Read the security model

CI with nothing to leak

GitHub Actions already issues each job a short-lived OIDC token. The credential provider trades it for a one-hour, read-only registry token. There is no secret to store, rotate or accidentally print in a log.

Workflows triggered from forks get no OIDC token, so they cannot read your private crates. That is the point.

Set up CI

.github/workflows/build.yml
name: build
on: [push, pull_request]
permissions:
  id-token: write   # for the OIDC token
  contents: read
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
      - uses: cargo-bins/cargo-binstall@<commit sha>   # pin to a commit
      - run: cargo binstall --no-confirm cargo-credential-privatecrates
      - run: cargo build --locked

Plain cargo publish, with a paper trail

Push a tag and CI publishes. The token it uses names one crate, one version and the SHA-256 of the exact bytes Cargo packaged, so it cannot be replayed for anything else.

Publishing from a laptop is refused by default, with the workflow ready to paste. Each crate’s owners file, in your repository, says which workflow may publish it and whether a GitHub environment’s reviewers must approve first.

Publishing guide

.github/workflows/publish.yml
name: publish
on:
  push:
    tags: ["v*"]
permissions:
  id-token: write
  contents: read
jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
      - uses: cargo-bins/cargo-binstall@<commit sha>   # pin to a commit
      - run: cargo binstall --no-confirm cargo-credential-privatecrates
      - run: cargo publish --registry acme

One price per organisation

$100 per GitHub organisation per month

  • Unlimited developers and CI jobs
  • SAML SSO and SCIM through GitHub, included
  • Provenance on every version, and the verifier
  • Search across your crates and crates.io

Questions

Do developers need a new account?

No. They sign in with GitHub the first time Cargo needs a token, and what they can read or publish follows their access to each crate’s repository.

Where are our crates stored?

In a private repository in your organisation: the index as files, and each version as an immutable GitHub release. We keep caches only. If you leave, everything is already in your repository.

Does it replace crates.io?

No. Public dependencies stay on crates.io. Search shows your private crates first, then crates.io results, and publishing a name that also exists on crates.io is refused by default to prevent dependency confusion.

Can outside collaborators use our crates?

Yes, the crates of the repositories they can read, and nothing else. A crate someone cannot read is a 404 to them, so its name is not revealed either.

What about CI outside GitHub Actions, or Docker builds?

At launch, only GitHub Actions can read the registry, so no long-lived credential exists anywhere. Build images in Actions using a BuildKit secret mount, or run cargo vendor in Actions and hand the vendored tree to the other system. See Docker builds and CI outside GitHub Actions.

Can we read the code?

The credential provider and the verifier, the parts that run on your machines and in your CI, are open source under MIT or Apache-2.0. The hosted service is source-available under the Business Source License 1.1, so your security team can read the code that handles your tokens.

What happens if we stop paying?

Publishing stops straight away. Builds keep reading crates for 14 days after the billing period ends, so nothing breaks overnight. Your crates and index stay in your repository either way.