[Pre-RFC] DNS domains as package namespaces

I really don't think we should or want to extend that into a dependency system, where a domain expiry could easily lead to RCE on a dev machine unless cases like these are really solved.

The original proposal would not enable this -- permission to upload new versions of existing crates is controlled by crates.io package ownership, not domain registration.

Further, if people would be OK with it, the follow-up comment of tracking domain ownership in crates.io too would mean that gaining control of a pre-existing namespace wouldn't allow publishing new crates.

I don't see how the risk you describe exists given those safeguards.

1 Like

Clearer responsibility of each part, I'd say.

When it is just the allowing of the / character, you come into the discussion where you might (or not) want users to be able to "take" prefixes to fill the requirement of grouping crates, for example for organisational purposes. If you wouldn't, then I could publish a google.com/json crate, which seems bad. Say that you'd allow the claiming of prefixes in crate names, then the prefix part of a crate name can only be indicative of the identity of the publisher by convention. It is just as easily possible that you have prefixes indicative of functionality, such as http-, where now only one entity can publish crates that start with http- and those sound mighty official (I know they aren't).

But if you have the concept of a namespace as part of the crate name, the namespace is the clear link to the identity of the publisher. Both approaches could result in a jarrovgit/json package, but only if I was smart/fast enough to claim the jarrovgit/ prefix in case we'd go with allowing the character+prefix claiming option.

I think I disagree with this statement. If the example.com part was the namespace, there can be more reasons for it to be related other than supply chain risks from my (as user) perspective. This namespace could be famous for high quality no_std implementations, or have provide interoperability guarantees (functionally).

That's true, but the confusion can be fixed in other ways (and since the confusing feature already exists and can't be removed due to backward compat, it needs a fix regardless).

For example, crates.io could display the install boilerplate as:

serde_json = { package = "jmillikin-serde-json", version = "1.0.0" }

This overrides lib.name, so it works even if you choose a different dependency name locally.


However, I don't agree with the premise that different packages implementing the same thing should have the same name. It matters which (whose) implementation is it, and not only when picking packages, but while using them too.

For example, we have openssl, boring, aws-lc, libtls and ring. They're all derivatives of openssl, but they're not the same "ssl" library. There are differences in their APIs and feature sets. There's also rustls, native-tls, schannel, security-framework, and superboring and smaller pieces overlapping with RustCrypto crates.

Making code use ssl:: for all APIs of all of these libraries regardless of the implementation removes important context from the code, because ultimately it's not the same ssl library.

Replacing specific strictly-typed identifier in code with a generalized name that only broadly describes their purpose is incorrectly modeling the domain. They all being identifiable as an implementation of SSL is a job of a keyword in the metadata, not a Rust identifier. The code isn't referring to SSL as a concept, it's referring to a single specific implementation with its own API that is independent from the other ssl APIs.

That design error is counter-productive, because it obfuscates a specific name with abstract label, making it harder to find the real identity required to use the specific implementation correctly.

Out of all reasons for namespaces, this seems the weakest one to me. So weak, it has a negative value for me.

I would be genuinely annoyed if the same ssl was used for sfackler.github.io/ssl, sfackler.github.io/ssl and sfackler.github.io/ssl (AKA openssl, native-tls and security-framework in the global namespace - the same author created more than one SSL library). I'm also switching between projects using cloudflare.com/ssl and sfackler.github.io/ssl (some of which is now kornel.ski/ssl) and sometimes aws.amazon.com/ssl. Keeping so many similar-but-different interfaces in my head is already annoying, and it would be much worse if they were all cloaked behind the same vague ssl:: identifier.

So even if library-renaming namespacing was possible, it'd be annoying, and I'd advocate for keeping library names unique anyway, like aws.amazon.com/aws-lc, sfackler.github.io/native-tls, openssl.org/openssl, etc. There are some benefits to having extra identity and flexibility in naming, but ability to remove distinction between implementations is not a benefit, but a confusing downside of the proposal.

crates.io can add categories or more distinctive keyword tagging to help find which crates are for SSL and which ones for JSON. crates.io can more prominently display ownership and surface library renaming. Packages as namespaces or prefix reservations can let authors publish packages in their own namespace without making crate/library names so heavily generic and context-dependent.

8 Likes

The full name matters when you're doing a dependency audit and want to find out if tls:: is OpenSSL v3.6, OpenSSL v3.6.1, or BoringSSL v0.20260413.0, but for normal everyday programming it's nice to be able to look at some code and know that tls:: is a TLS library (vs being required to intuit that from superboring::.

This wouldn't be possible because the package names would be in conflict. You'd have to do something like sfackler.github.io/ssl and sfackler2.github.io/ssl -- the library names are non-unique, but package names are unique, otherwise there's no way for the registry to map the package name to a (urls, checksum) tuple (which is the whole point of a package registry).

For some domains, such as cryptography, the quality of the implementation matters enough that users might insist on branding. You can always just decide to refuse to use dependencies that have names you think are too generic. As long as I'm allowed (as a package author) to publish a package, I don't really care if some subset of people don't use it for non-technical reasons.

but for normal everyday programming it's nice to be able to look at some code and know that tls:: is a TLS library (vs being required to intuit that from superboring

I don't agree. Different TLS libraries have wildly different API surfaces and features (arguably OpenSSL is as much of a generalized cryptography library as a TLS library) that it's just gonna be more confusing instead of less confusing. You need knowledge of the ecosystem anyways, even in everyday programming, to know what you should choose and how things are different. I don't think it's good that people can just install the first library called tls that they see.

3 Likes

Note that this complaint is distinct to non-namespaced designs -- a namespaced design has package names like rusttls.dev/tls or joes-crab-shack-and-certificate-authority.xyz/tls, so the purpose of the library (implementing TLS) and any reputational assumptions about the author ("I trust Joe's Crab Shack, they have a great ChaCha20 implementation") are separate.

I agree that in your provided example, moving from openssl, boring, aws-lc etc to company-a.io/tls, cool-project.com/tls etc seems like a degredation in user experience.

I disagree that this is automatically the result (nor the goal, in my opinion) of the proposal though. Enabling something does not mean removing something else, and these crates will (probably) remain to be named as they are.

However, namespacing would allow me to publish a patched version of any of those (which I would never do for a cryptography-related crate, I know my limits :wink:). And it would be really clear I am using my patched version because I'd likely publish it as my-website.nl/boring. It would make it immediately clear that this is mine, not the official version. Just like if I were to publish it as jarrovgit-boring today with a lib.name = boring. The difference to me is that the namespace clearly conveys identity association, while using the currently possible workflow (lib.name) is only by convention.

Enabling publishers to name their package to the crate's domain (e.g. my-website.nl/xml, where the previous mentioned "domain" refers to xml in this example) does not make it required to do so. Just like all of the openssl, boring and aws-lc package owners could already name their libraries tls with their wildly different APIs and confuse everybody. They are not doing that today and I don't see a reason for expecting this to happen when such a proposal as this would ever see an implementation.

TL;DR of my reply: this is not an added confusion, this is current behavior already through the existence of lib.name.

Use of lib.name is avoided by convention. There are a lot of confusing things in Rust, but people's goodwill means not every .rs file is Rust quiz. The OP is encouraging everyone to use lib.name, and that's definitely not already the case.

Right now, people can read just the .rs files and can tell with reasonable confidence what crates are being used, though not what version of said crates. With the namespacing scheme proposed, we cannot hope to do that, instead we have to read Cargo.toml too.

This is certainly a disadvantage of this approach, but we will still disagree on how severe it is.

Lack of namespaces also has a cost. It ensures that crate names will ever increasingly be ridiculous, so that we cannot tell what a crate does, despite knowing its name.

And this:

sounds like we're still in 2014. We've been arguing for over a decade with no new ideas, while the rest of Rust have matured. I think it's time we leave the perfect design for Rust's successor and settle on whatever seems least bad at the moment.

1 Like