# \[Pre-RFC\] Domains as namespaces

**URL:** <https://internals.rust-lang.org/t/pre-rfc-domains-as-namespaces/8688>\
**Category:** cargo\
**Created:** [October 27, 2018, 12:00am UTC](https://internals.rust-lang.org/t/pre-rfc-domains-as-namespaces/8688 "2018-10-27T00:00:07Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![anon2808951](https://avatars.discourse-cdn.com/v4/letter/a/67e7ee/32.png) [@anon2808951](https://internals.rust-lang.org/u/anon2808951)\
**Post date:** [October 27, 2018, 12:00am UTC](https://internals.rust-lang.org/t/pre-rfc-domains-as-namespaces/8688/1 "2018-10-27T00:00:07Z")

</div>

**Summary**

Provide a namespacing facility which addresses the following requirements:

1. Allow claiming a namespace exclusively, thereby restricting which crates can be published under this namespace. This allows addressing the squatting issue.

2. Avoid disputes over namespaces, which can take massive amounts of time and resources to manage.

3. Guarantee that namespaces are unique, solving the issue of "clashing" namespaces. Non-unique namespaces work poorly and cause disputes, as demonstrated by npm's `kik` conflict.

4. Avoid creating a hard dependency on external services. The recent GitHub service interruption is a good example why this is important.

5. Make receiving a namespace as seamless as possible for users. Namespaces should be an additional benefit crate authors receive, not some annoying bureaucratic hurdle they have to jump over.

**Design**

- Use (sub)domains as namespaces. _Maven_ has shown that this approach has been working exceedingly well for more than a decade.
- Control of a (sub)domain is established using domain validation (DV) and [RFC5785](https://tools.ietf.org/html/rfc5785). _Let's Encrypt_ is successfully using this approach to generate millions of certificates each year.
- [Crates.io](http://Crates.io) maintainer will never need to get involved in namespace disputes, as ICANN's _Uniform Domain-Name Dispute-Resolution Policy_ deal with this.

**Basic User Experience**

Basic task: I want to publish my `abc` crate under `xyz.github.io`.

1. I add `organization = "xyz.github.io"` to my Cargo.toml.
2. I run `cargo publish`.
3. The command prints the following text to the console:

> [Crates.io](http://Crates.io) couldn't verify that you own `xyz.github.io`. To prove ownership, place a file with the following contents
> 
> ZG2ioiTY3tMgwDYfmb6p
> 
> at [https://xyz.github.io/.well-known/cargo-publishers](https://xyz.github.io/.well-known/cargo-publishers)

4. I place the file "cargo-publishers" with the randomly generated string from [crates.io](http://crates.io) at the specified address.
5. I rerun `cargo publish`. [crates.io](http://crates.io) checks that the string matches and publishes the crate under the namespace.

**Details**

Upon the first request to publish a crate with a namespace, [crates.io](http://crates.io) generates a random string that is user-, crate- and domain-specific.

On each following request [crates.io](http://crates.io) checks whether a file named "domain-owner" at the given domain exists and verifies that the contents are identical to what [crates.io](http://crates.io) has on file for the specific user/crate/domain combination.

The ability to publish a crate is not limited to one person: If a different person wants to publish a crate to a domain, [crates.io](http://crates.io) returns a similar reply:

> [Crates.io](http://Crates.io) couldn't verify that you own `xyz.github.io`. To prove ownership, add the following text to the "domain-owner" file at your domain root: Io3487xY3tjg54Ef9Opz

This person would then contact the owner of the domain, who could decide whether to accept or reject this request (by adding or not adding the line to his "domain-owner" file).

This also serves as a very easy way to allow external contributors to publish add-on crates to a crate in an organization, without allowing them to publish to the main crate. E.g. authors of serde could publish their own crate under `serde.rs/serde` and allow vetted, "official" add-on crates to be published by external contributors under e. g. `serde.rs/serde-abc` or `serde.rs/serde-xyz` by adding those users' verification line to their "domain-owner" file.

**Changes**

This requires some changes to cargo and [crates.io](http://crates.io):

- cargo needs to support

- [crates.io](http://crates.io) needs to be extended

No changes to the language are required. Source code of crates does not need to be changed to enable namespaces.

**Further Suggestions**

It is recommended that `/` is used as a separator between the namespace and the crate name.

This would mean that a fully-qualified crate would look like an URL, making it easy to find further documentation or the project's homepage:

Consider a crate called `abc` with the namespace `xyz.github.io`. The fully-qualified name would be `xyz.github.io/abc`. The namespace owner could then place documentation under this URL, forward to the crates GitHub page, or redirect to doc.rs.

**Future Tasks**

This proposal does not discuss what should happen with the global namespace. This is intentional – there are plenty of policy decisions that can be made with various advantages and disadvantages.

There are valuable discussions to be had about this, but I think it makes sense to discuss this separately, so that disagreement about how to handle the global namespace doesn’t impede the debate about making namespaces as good as possible.

**FAQ**

This FAQ is not meant as a complete enumeration of all possible scenarios, but is intended to show how this proposal functions, and which potential policy decisions can be made:

_Do I need my own domain?_

No. Any subdomain is sufficient. Everyone participating here already owns one, and they are not hard to come by.

_I no longer care about maintaining the domain, what should I do?_

Ask your maintainers or contributors to take over the domain. (This is not much different from a situation where the original author loses interest in maintaining his/her crate.)

_My domain was hacked!_

Use your domain registry's support channels to resolve this issue. In the meantime, it might make sense to let [crates.io](http://crates.io) maintainers know, so that the publication of new crates or versions can be disabled until the issue is resolved. (This is not much different from your [crates.io](http://crates.io) account being compromised.)

_Someone else owns my domain now!_

Pick a new domain. If there is an acute danger of misuse, let [crates.io](http://crates.io) maintainers know, so that publications of newer versions of existing crates under that namespace can be blocked.

---

<div class="post-metadata">

**Author:** ![ivandardi](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/ivandardi/32/4845_2.png) [@ivandardi](https://internals.rust-lang.org/u/ivandardi)\
**Post date:** [October 27, 2018, 7:24am UTC](https://internals.rust-lang.org/t/pre-rfc-domains-as-namespaces/8688/2 "2018-10-27T07:24:43Z")

</div>

That’s an interesting approach. I have a few questions, though: Would new crates necessarily need a domain associated with them? And what about existing crates? Would it go effective the first time they publish with the domain?

---

<div class="post-metadata">

**Author:** ![Nemo157](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nemo157/32/11585_2.png) [@Nemo157](https://internals.rust-lang.org/u/Nemo157)\
**Post date:** [October 27, 2018, 9:01am UTC](https://internals.rust-lang.org/t/pre-rfc-domains-as-namespaces/8688/3 "2018-10-27T09:01:19Z")

</div>

Is there a standard for domain verification available anywhere? The only one I can find is just the general [ACME draft standard](https://ietf-wg-acme.github.io/acme/draft-ietf-acme-acme.html#rfc.section.8.3), but that’s a much more complicated protocol than what your example shows.

Personally if domains are to be used as namespaces (which I’m not really for or against), I would much prefer to use DNS validation than have to update files on my HTTP server.

---

<div class="post-metadata">

**Author:** ![TimNN](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/timnn/32/11461_2.png) [@TimNN](https://internals.rust-lang.org/u/TimNN)\
**Post date:** [October 27, 2018, 9:22am UTC](https://internals.rust-lang.org/t/pre-rfc-domains-as-namespaces/8688/4 "2018-10-27T09:22:20Z")

</div>

My main concern would be that domains can expire and change owners. Let’s say I publish my crates under my domain, then loose interest in Open Source work. My domain expires and someone else buys it. Do they now control my crates? Will I ever be able to publish new versions of my crates?

* * *

Also, as mentioned on reddit as well, the “domain owners” file should use a more specific name and go into “.well-known”.

Additionally, I believe that the “domain owners” file should have a more defined structure, or at least support some kind of comments, so that when editing the file, one can know which verification code corresponds to which user or crate (in case one wants to revoke specific permissions).

* * *

Another note: While maven uses domains to identify packages, I don’t think they actually validate that one owns the domain.

---

<div class="post-metadata">

**Author:** ![anon2808951](https://avatars.discourse-cdn.com/v4/letter/a/67e7ee/32.png) [@anon2808951](https://internals.rust-lang.org/u/anon2808951)\
**Post date:** [October 27, 2018, 11:23am UTC](https://internals.rust-lang.org/t/pre-rfc-domains-as-namespaces/8688/5 "2018-10-27T11:23:54Z")

</div>

(post deleted by author)

---

<div class="post-metadata">

**Author:** ![OZ\_](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/oz_/32/4298_2.png) [@OZ\_](https://internals.rust-lang.org/u/OZ_)\
**Post date:** [October 27, 2018, 12:00pm UTC](https://internals.rust-lang.org/t/pre-rfc-domains-as-namespaces/8688/7 "2018-10-27T12:00:41Z")

</div>

I hope it will never be accepted.

Right now I don’t own any domain - I don’t deserve to publish a crate?

If domain of my project is “nudebeachgirls.fun”, will users use my crates for cryptography?

If domain is expired I can’t update crates anymore - it’s just ridiculous.

If I buy domain “rustlang” in some exotic tld, will it increase my chances for phishing activity?

It’s bad idea.

---

<div class="post-metadata">

**Author:** ![storyfeet](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/storyfeet/32/4461_2.png) [@storyfeet](https://internals.rust-lang.org/u/storyfeet)\
**Post date:** [October 27, 2018, 12:22pm UTC](https://internals.rust-lang.org/t/pre-rfc-domains-as-namespaces/8688/8 "2018-10-27T12:22:20Z")

</div>

I really like the idea of a play/test namespaqe that’s easy to get permission to write under that won’t clog the main scope

---

<div class="post-metadata">

**Author:** ![storyfeet](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/storyfeet/32/4461_2.png) [@storyfeet](https://internals.rust-lang.org/u/storyfeet)\
**Post date:** [October 27, 2018, 12:24pm UTC](https://internals.rust-lang.org/t/pre-rfc-domains-as-namespaces/8688/9 "2018-10-27T12:24:36Z")

</div>

the global scope can remain open, along with many other semi official, open domain scopes. that are easy for users to publish to

---

<div class="post-metadata">

**Author:** ![matthieum](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/matthieum/32/4023_2.png) [@matthieum](https://internals.rust-lang.org/u/matthieum)\
**Post date:** [October 27, 2018, 12:53pm UTC](https://internals.rust-lang.org/t/pre-rfc-domains-as-namespaces/8688/10 "2018-10-27T12:53:08Z")

</div>

I admire the enthusiasm, but I have some reserve with the process with regard to long-term maintenance and security.

1. If the “owner” loses access to the domain, which happens relatively often, then what? Do they have to acquire a new domain, move the crate over to that domain, and ask all clients to migrate over (manually)? That’s a lot of churn!

2. There are several issues around security/authentication that I can of:

I do agree that some what of having “organizations” or “namespaces” would be great; but I am not clear that your proposal is significantly better than just letting users claim organizations and namespaces (like Maven does).

---

<div class="post-metadata">

**Author:** ![mammothbane](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/mammothbane/32/1143_2.png) [@mammothbane](https://internals.rust-lang.org/u/mammothbane)\
**Post date:** [October 27, 2018, 2:04pm UTC](https://internals.rust-lang.org/t/pre-rfc-domains-as-namespaces/8688/11 "2018-10-27T14:04:59Z")

</div>

> The core point is that [crates.io](http://crates.io/) would be a collection of facts along the lines of “at the point in time crate X was published, the author Y controlled domain Z”

I fail to see what the domain information actually adds to the picture. Another way to frame what you're saying is that [crates.io](http://crates.io) would maintain a time-varying mapping of domain aliases to [crates.io](http://crates.io) accounts—you'd be using a (domain name, time) tuple to look up an account, then retrieving the crate with the given name.

Why not just use the `crates.io` account name for namespacing directly? That would eliminate that extra layer of indirection and vastly simplify the implementation. It still hits all of your requirements, as GitHub usernames are already namespaced, and doesn't appreciably increase our dependency on GitHub, since [crates.io](http://crates.io) uses GitHub OAuth already. A service interruption might affect the community's capacity to publish new packages, but it wouldn't affect the namespacing information we would already store.

---

<div class="post-metadata">

**Author:** ![Soni](https://avatars.discourse-cdn.com/v4/letter/s/a3d4f5/32.png) [@Soni](https://internals.rust-lang.org/u/Soni)\
**Post date:** [October 27, 2018, 2:18pm UTC](https://internals.rust-lang.org/t/pre-rfc-domains-as-namespaces/8688/12 "2018-10-27T14:18:38Z")

</div>

domains as namespaces without domains as independent, federated registries isn’t a very good solution IMO.

I’ve said it before: federated means you can use [crates.io](http://crates.io) as a caching proxy for other, official project registries.

by using .well-known, we would also allow the registry to exist on the main website, e.g. diesel.rs could setup a registry on diesel.rs so that you don’t have to use a subdomain when specifying the crates.

the main benefit is that you get official registries, rather than using rust’s generic/general purpose registry. as a side effect, you also get independent moderation, and the [crates.io](http://crates.io) moderation team would no longer be overwhelmed with moderation tasks. in the end, both of these contribute to a better organized registry “fediverse”, and IMO it would be more efficient than simply “domains as namespaces”.

the main risks (which IMO are benefits) is that [crates.io](http://crates.io) loses some control over crate availability. however, the fact that [crates.io](http://crates.io) would work as a caching proxy for the other registries, means [crates.io](http://crates.io) could run whatever malware filters they want on the crates, as well as disallowing the mutation of published crates.

---

<div class="post-metadata">

**Author:** ![bluejekyll](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/bluejekyll/32/1779_2.png) [@bluejekyll](https://internals.rust-lang.org/u/bluejekyll)\
**Post date:** [October 27, 2018, 2:29pm UTC](https://internals.rust-lang.org/t/pre-rfc-domains-as-namespaces/8688/13 "2018-10-27T14:29:21Z")

</div>

> [@matthieum](#):
>
> If I have an official looking domain (rustaceans.cam, rustlang.cam), it really opens up phishing.

How is this any different than existing possibility of phishing on existing crates, like `serde` vs. `serdi`, for a bad example. It seems like this doesn't make it better or worse, does it?

I really like this idea, but I'm a little biased. I think working through the concerns about domain transfers as they relate to ownership is an important detail. Not a blocker in my opinion, but definitely the biggest issue I see with this idea. In addition to that, I wonder about management in large organizations. Let's randomly pick `google.com` as an example. How do things work in the event that there are multiple groups inside the same large organization, but each independently owning their own set of crates? Would they need separate sub-domains?

---

<div class="post-metadata">

**Author:** ![anon2808951](https://avatars.discourse-cdn.com/v4/letter/a/67e7ee/32.png) [@anon2808951](https://internals.rust-lang.org/u/anon2808951)\
**Post date:** [October 27, 2018, 2:37pm UTC](https://internals.rust-lang.org/t/pre-rfc-domains-as-namespaces/8688/14 "2018-10-27T14:37:17Z")

</div>

(post deleted by author)

---

<div class="post-metadata">

**Author:** ![ethanpailes](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/ethanpailes/32/4812_2.png) [@ethanpailes](https://internals.rust-lang.org/u/ethanpailes)\
**Post date:** [October 27, 2018, 2:49pm UTC](https://internals.rust-lang.org/t/pre-rfc-domains-as-namespaces/8688/15 "2018-10-27T14:49:05Z")

</div>

What's the plan for referring to namespaced crates in rust code? There was a lot of focus on this issue over on the [packages as namespaces](https://internals.rust-lang.org/t/pre-rfc-packages-as-namespaces/8628) thread, which alternative proposals could mine for ideas. The one that I'm going to move forward for for that proposal is mapping `/` to `::>`, which would probably work fine here as well. There does need to be some way to mangle the `.` that can show up in domains.

I guess one alternative would be to say "You can't depend on both `ethanpailes.github.io/somecrate` and `soc.github.io/somecrate` at the same time. Then you name `somecrate` in rust code with the word `somecrate`. I worry that such an approach erases some of the benefits of namespacing.

> Avoid creating a hard dependency on external services. The recent GitHub service interruption is a good example why this is important.

It sounds like we would end up encouraging many users to use their github pages subdomain as a namespace. That wouldn't create a hard dependency in theory, but it might in practice. It's worth considering at least.

---

<div class="post-metadata">

**Author:** ![OZ\_](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/oz_/32/4298_2.png) [@OZ\_](https://internals.rust-lang.org/u/OZ_)\
**Post date:** [October 27, 2018, 2:55pm UTC](https://internals.rust-lang.org/t/pre-rfc-domains-as-namespaces/8688/17 "2018-10-27T14:55:14Z")

</div>

> [@anon2808951](#):
>
> This addresses the squatting issue.

> [@anon2808951](#):
>
> This proposal gives you _more_ options to publish your crate, not fewer.

Then it doesn't address anything.

---

<div class="post-metadata">

**Author:** ![IsaacWoods](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/isaacwoods/32/4767_2.png) [@IsaacWoods](https://internals.rust-lang.org/u/IsaacWoods)\
**Post date:** [October 27, 2018, 3:24pm UTC](https://internals.rust-lang.org/t/pre-rfc-domains-as-namespaces/8688/18 "2018-10-27T15:24:29Z")

</div>

> [@OZ\_](#):
>
> Then it doesn’t address anything.

You're being somewhat counterproductive here, imo.

Regardless of whether they're tied to domain names, what I'd idealistically like to see is the addition of namespaces on top of what would become the 'default' namespace (all the packages that are on [crates.io](http://crates.io) at the moment). This would only add options - you would be able to either publish a crate in the default namespace (exactly the same process as at the moment), or under a namespace tied to an established project that may have lots of crates within it. This proposal provides one option along these lines.

This addresses a lot of the concerns I've seen raised about squatting, including the legitimate case of squatting crates with a prefix such as the `win32-` crates

---

<div class="post-metadata">

**Author:** ![OZ\_](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/oz_/32/4298_2.png) [@OZ\_](https://internals.rust-lang.org/u/OZ_)\
**Post date:** [October 27, 2018, 3:43pm UTC](https://internals.rust-lang.org/t/pre-rfc-domains-as-namespaces/8688/19 "2018-10-27T15:43:26Z")

</div>

> [@IsaacWoods](#):
>
> You’re being somewhat counterproductive here, imo.

No surprises here, I said already I'm against this idea.

> [@IsaacWoods](#):
>
> This addresses a lot of the concerns I’ve seen raised about squatting

Really? How it will prevent spam in "default" namespace?

> [@IsaacWoods](#):
>
> including the legitimate case of squatting crates with a prefix such as the `win32-` crates

prefix is not a domain.

Companies change domains - will it affect projects who use crates from changed domain?

This idea if implemented, will just make system of crates more complicated, with more fragile points, that's all. It doesn't prevent spam, squatting or phishing (it even makes phishing easier).

---

<div class="post-metadata">

**Author:** ![Soni](https://avatars.discourse-cdn.com/v4/letter/s/a3d4f5/32.png) [@Soni](https://internals.rust-lang.org/u/Soni)\
**Post date:** [October 27, 2018, 3:56pm UTC](https://internals.rust-lang.org/t/pre-rfc-domains-as-namespaces/8688/20 "2018-10-27T15:56:22Z")

</div>

it’s supposed to help offload moderation from the [crates.io](http://crates.io) mod team

---

<div class="post-metadata">

**Author:** ![anon2808951](https://avatars.discourse-cdn.com/v4/letter/a/67e7ee/32.png) [@anon2808951](https://internals.rust-lang.org/u/anon2808951)\
**Post date:** [October 27, 2018, 3:59pm UTC](https://internals.rust-lang.org/t/pre-rfc-domains-as-namespaces/8688/21 "2018-10-27T15:59:52Z")

</div>

(post deleted by author)

---

<div class="post-metadata">

**Author:** ![anon2808951](https://avatars.discourse-cdn.com/v4/letter/a/67e7ee/32.png) [@anon2808951](https://internals.rust-lang.org/u/anon2808951)\
**Post date:** [October 27, 2018, 4:12pm UTC](https://internals.rust-lang.org/t/pre-rfc-domains-as-namespaces/8688/22 "2018-10-27T16:12:32Z")

</div>

(post deleted by author)

[Next page](https://internals.rust-lang.org/t/pre-rfc-domains-as-namespaces/8688.md?page=2)
