{
"$type": "site.standard.document",
"bskyPostRef": {
"cid": "bafyreiacs4nhzatyadxp3nvvvacb657eugggv6w2nknyg7j2qk2cuzdz2e",
"uri": "at://did:plc:ivbknywyskln22er3nkssdhl/app.bsky.feed.post/3mkcfibhbepd2"
},
"path": "/t/pre-rfc-dns-domains-as-package-namespaces/24202#post_1",
"publishedAt": "2026-04-25T05:23:57.000Z",
"site": "https://internals.rust-lang.org",
"tags": [
"GitHub - jmillikin/upstream__cargo at domain-namespaces-raw-llm-output · GitHub",
"crates.io",
"GitHub - jmillikin/upstream__crates.io at domain-namespaces-raw-llm-output · GitHub"
],
"textContent": "Package namespacing is one of those perennial topics that seems to attract designs but not much implementation. I took my own preferred approach (DNS domains) and got some robots to implement a proof-of-concept.\n\nThe code isn't great (and the robots hallucinate various minor details) but overall it's enough to get a feel for how DNS-based namespacing would work.\n\nCargo branch (raw LLM output): GitHub - jmillikin/upstream__cargo at domain-namespaces-raw-llm-output · GitHub\n\ncrates.io branch (raw LLM output): GitHub - jmillikin/upstream__crates.io at domain-namespaces-raw-llm-output · GitHub\n\nI want to get a feeling for how the Cargo / crates.io team feel about the overall concept before I put any effort into cleaning up the proof-of-concept code.\n\n * My impression from past discussions is that those teams have historically objected to namespaces for aesthetic reasons (\"why name your crate `boring.com/base64` when you could just name it `base64inator9000`?\").\n * But also opinions may currently be different than they were a year or two ago.\n\n\n\nRough outline of the design:\n\n * Package names are allowed (not required) to start with a `{namespace}/` prefix, where the namespace is a DNS-style dotted name like `example.com` or `jdoe.github.io`.\n * This is designed to address name squatting (\"I want to publish my `wasm` crate but there's already an empty crate named `wasm`\").\n * Control over subsets of the global namespace (\"My project is named `cool` so I want to prevent someone else from publishing a crate named `cool-wasm`) is out of scope.\n * You can use your own domain as a namespace if you care about this, but it doesn't prevent someone else from registering packages with a given prefix either in the global namespace or their own domain.\n * Cargo strips off the namespace prefix before passing the crate name to `rustc`, so `example.com/base64` is `base64` to the compiler.\n * If you want to depend on `base64` and `example.com/base64` in the same crate then you'll need to use existing Cargo mechanisms to rename one in the local compilation context.\n * When a crate is first created on crates.io, if it has a namespace then that namespace will be interpreted as a DNS name and verified by fetching a list of authorized user keys.\n * The URL of the file is `https://{namespace}/.well-known/rust-lang.org/package-namespace.json`.\n * This file contains a list of keys that identify who is allowed to create packages in that namespace.\n * The key format is determined by the registry. In the case of crates.io it's computed as approximately `sha256((namespace, user_id))` -- see `gen-auth-key.py` for details. Note that `user_id` part of existing API responses, so no part of this key is secret.\n * The use of `https://{namespace}/.well-known/` as opposed to DNS TXT records (etc) is to enable users to publish namespaced crates without having to first pay for a domain.\n * Specifically they can put something on `{username}.github.io`.\n * Domain verification only happens when a crate is first created. Subsequent uploads use the existing permissions (either a crate owner, or a TrustedPub key).\n * This means that if control of a domain is lost then the new owner can't use that access to publish new versions of existing crates.\n * Whenever the crate name needs to be encoded somewhere that a `/` is semantically meaningful (URLs, file paths) it gets encoded to `%2F`.\n * This includes the paths in source archives.\n * Yes this means the crates.io URLs for namespaced crates are kinda ugly. I think this doesn't matter.\n\n\n\nScreenshots:\n\nExample `package-namespace.json`:\n\n\n {\n \t\"authorized_keys\": [\n \t\t\"sha256-kdRCstHTc6I8OxwyuW+QC8gFkn4tT8/g4a0M//cvCXk=\"\n \t]\n }\n\n\nExample `Cargo.toml`:\n\n\n cargo-features = [\"domain-namespaces\"]\n\n [package]\n name = \"example.com/hello\"\n version = \"0.1.0\"\n edition = \"2024\"\n\n description = \"Hello, world!\"\n license = \"0BSD\"\n repository = \"https://github.com/example/hello\"\n homepage = \"https://example.com/hello\"\n documentation = \"https://example.com/hello-docs\"\n",
"title": "[Pre-RFC] DNS domains as package namespaces"
}