Trust centre

What we hold, who else touches it, and how you can check us. The short answer: your crates live in your own GitHub organisation. We store only a record of who accepted our terms, and requests to join the private preview.

Held by PrivateCrates

Stored durably
Only terms acceptances
Which organisation, which GitHub user, which terms version, when. No registry data, no code, no tokens.
In transit
Callers’ GitHub and registry tokens, and crate files while they are being published.
In memory
Caches keyed by a hash of the token, never the token: who can read what, index files, crate metadata for search, member counts.
In logs
GitHub logins, organisation and registry names, crate names and versions, errors. Never tokens.

What we hold

PrivateCrates runs the Cargo registry protocol in front of a repository your organisation owns. The index and every crate file are stored there, by GitHub, as commits and immutable releases. The service itself keeps two kinds of record, terms acceptances and invitation requests; everything else it knows is on GitHub, or can be rebuilt from it.

Stored: terms acceptances

When an admin accepts the terms for an organisation, we record the organisation’s GitHub ID and login, the admin’s GitHub ID and login, the terms version, the time, whether they accepted on the website or with the CLI, and the exact statement they accepted. The record holds no secrets and is never shared.

It is kept in a Postgres database in the same Railway project and region as the service (US East), with Railway’s backups, for as long as the organisation uses PrivateCrates and then for 6 years, as evidence of the agreement.

Stored: invitation requests

When someone asks to join the private preview, we record their GitHub ID and login, the organisation they named, the email address they gave and their note, in the same database. We use them only to decide on the invitation and to reply, and delete them once we have replied, or at the latest after 12 months.

Passes through, not kept

  • Tokens. Developers’ GitHub tokens and CI’s one-hour registry tokens arrive with each request. We use them only to ask GitHub what the caller may access, and never store, log or forward them anywhere else.
  • Crate files during cargo publish: we check the file, compute its SHA-256 and upload it to your storage repository.
  • Your website sign-in lives in an encrypted cookie in your browser for 8 hours. Nothing is kept on our side.

Cached in memory

Caches make the registry fast and are lost on every restart. They are keyed by a hash of the token, never the token itself: which repositories a token can read (5 minutes, and dropped by webhook when membership changes), index files, crate metadata for cargo search, and each organisation’s member count (up to 24 hours, a number only).

Logged

The service writes structured logs: GitHub logins of people who set up or publish, organisation and registry names, crate names and versions, the workflow that published them, and error codes and messages. Tokens and crate contents are never logged.

Logs are kept for 30 days, Railway’s retention period, then deleted.

Where it runs

PartRuns on
The service and this websiteRailway, one replica per environment, in the US East (Virginia) region, close to GitHub’s API. Railway terminates TLS for our domains.
DNSCloudflare, DNS only. Records are not proxied, so requests go straight to Railway and Cloudflare never sees their contents.
Your crates and indexGitHub, in a private repository in your own organisation, under your agreement with GitHub. Deleting that repository deletes your registry’s data.
Terms acceptancesA Postgres database at Railway, in the same project and region as the service, with Railway’s backups.
BillingStripe, from general availability. Billing is off during the private preview, so Stripe is listed but not yet used. Card details will be entered on Stripe’s pages and never reach us.
Status pageA Cloudflare Worker at status.privatecrates.dev, deliberately separate from Railway so it stays up when we are down.

Subprocessors

The companies that process customer data on our behalf. We announce a new subprocessor here at least 30 days before it starts, and, once billing is on, email each organisation’s billing address too. If you object and we cannot accommodate it, you may cancel and get a prorated refund of anything prepaid. An urgent replacement, after a failure or a breach, may happen at once, with notice as soon as we can give it.

SubprocessorPurposeDataLocation
RailwayHosts the PrivateCrates service: it runs the server, terminates TLS for our domains, keeps its logs, and runs the Postgres database (with backups) that holds terms acceptances and invitation requests.Everything in transit through the service (tokens, crate files during publishing), the in-memory caches, the service’s logs, the terms acceptance records, and invitation requests.United States, US East (Virginia) region
GitHubIdentity, permissions and storage. Your crates and index live in your own organisation’s repository; GitHub Actions signs provenance.Your crates, index and release history (in your repository, under your agreement with GitHub); the API calls we make on your behalf.Under your organisation’s GitHub agreement
StripeSubscriptions, invoices, card payments and the trial-ending reminder email, from general availability. Billing is off during the private preview, so Stripe receives nothing yet.The organisation’s GitHub name and ID, the billing email you give us, and card details (entered on Stripe; we never see them).United States and elsewhere, under Stripe’s terms
CloudflareDNS for privatecrates.dev (not proxied: traffic goes straight to Railway), and the status page at status.privatecrates.dev.DNS lookups for our domains. The status page probes only our public endpoints and holds no customer data.Global network

When a service we depend on fails

PrivateCrates runs on these services and cannot work without them, GitHub above all: it stores every registry, signs everyone in and decides who may read and publish. When one of them is down or degraded, parts of PrivateCrates, or all of it, may stop working, and there may be nothing we can do until it recovers. We do not control them and are not responsible for them; the terms say so formally. The status page checks their public status every minute and says when a problem is theirs rather than ours.

Security controls

GitHub is the root of trust. The service is designed so that stealing our keys, or taking it over, does not let anyone change a published crate without your own verifier noticing. The security model has the threat table in full.

Access

  • Permissions are GitHub’s. A caller may read a crate if they can read the repository that owns it, and publish if they can push to it. Removing someone on GitHub cuts off their access by webhook within seconds.
  • Two least-privilege GitHub Apps. The reader App has metadata read and members read. The storage App can write only to your storage repository. Neither has repository administration, so neither can turn immutable releases off.
  • Narrow tokens. Developers hold reader App tokens that can list metadata and nothing else. CI holds one-hour registry tokens with no GitHub access at all.

Integrity

  • Immutable releases: a published crate file can never be changed or deleted, whoever holds our keys.
  • Checksums at publish: we compare our SHA-256 with the digest GitHub computes before the release goes live.
  • Provenance: each CI publish stores a token signed by GitHub, not by us, naming the repository, workflow, crate, version and checksum.
  • Append-only index, and every write a verified commit in your repository, with the publisher in the message.
  • The open-source verifier checks all of this from your own CI. Set up the verifier.

Transport, sessions and secrets

  • HTTPS only, with HSTS for a year on every subdomain. The website sends a strict Content-Security-Policy with no inline scripts, and refuses to be framed.
  • Session cookie pc_session: encrypted with AES-256-GCM, HttpOnly, Secure, SameSite=Lax, 8 hours.
  • Secrets (GitHub App keys, signing and session keys, Stripe keys) are generated per environment and held as encrypted Railway variables, never in the repository. Each has a rotation procedure. Moving the App keys and the token signing key into a cloud key management service is on the roadmap below; today they are not in one.
  • Limits: capped request sizes, a publish rate limit per token, and timeouts on every call to GitHub.
  • Changes: production deploys only from a protected branch, after CI passes on the exact commit.

Source code

The credential provider, the set-up CLI and the verifier are open source under MIT or Apache-2.0. The hosted service is source-available under the Business Source License 1.1, so you can audit what runs.

Certifications

None yet. PrivateCrates has no SOC 2 report, no ISO 27001 certificate and has not had an independent penetration test. We would rather say so than imply otherwise. Until then, the design is the assurance: your data stays on GitHub, whose own reports cover it, and the verifier lets you check our writes yourself.

The penetration test and SOC 2 are on the roadmap to general availability, below.

GitHub’s and Stripe’s own reports cover the data they hold: see the GitHub Security and Stripe security pages.

Roadmap to general availability: 2027, subject to demand

PrivateCrates is in preview: free, run by one person, and provided as is. This is what has to happen before general availability, in order. We will do it if there is enough interest.

OrderItemWhy
1Form a company; publish its name, number and addressThe operator for terms, DPA and billing
2Legal review of the terms, privacy notice and DPA (governed by the law of England and Wales)Terms fit for paying customers
3International transfer mechanism (EU SCCs and the UK addendum)EU customers’ data processed in the US
4Turn on billing (Stripe live mode), with at least 30 days’ notice to existing organisationsRevenue
5Incident commitments: time to first status update, breach notification deadline (72 hours)Enterprise reviews ask
6Security response targets by severity; a PGP key or other encrypted channelDisclosure policy completeness
7App keys and the token-signing key in a KMSLeast exposure of the most sensitive keys
8Independent penetration test, with a summary on the trust centreEvidence for reviewers
9SOC 2 Type I, then Type IIThe usual enterprise gate

Incident response

  • Detection: the status page probes the website, the account API and a registry from outside Railway every minute, and watches GitHub’s and Stripe’s own status.
  • Communication: incidents are posted on status.privatecrates.dev, with an Atom feed to subscribe to. When GitHub is the cause, the page says so and links GitHub’s incident. For a security incident affecting your organisation, we will also email its billing address once billing is on; during the private preview there is none, so the status page is where we say it.
  • Target times: none are committed during the private preview. Time to first status update and a 72-hour breach notification deadline are on the roadmap.
  • Limiting the damage: the only durable data is the terms acceptance record, which holds no secrets. Your verifier reports any write we could not have made honestly. Rotating the token signing key revokes every outstanding CI token at once.

Vulnerability disclosure

Report security problems to security@privatecrates.dev. Our disclosure policy covers scope, safe harbour and what to include. The same contact is published in security.txt (RFC 9116).

Documents

Need something else for a security review, such as a questionnaire? Email security@privatecrates.dev.