Boundary node feature request - subdomain.principal.ic0.app

Canister subdomains

We currently have https://jglts-daaaa-aaaai-qnpma-cai.ic0.app/
pointing to jglts-daaaa-aaaai-qnpma-cai canister

I propose we get https://*anythinghere*.jglts-daaaa-aaaai-qnpma-cai.ic0.app/ also point to that same canister.

This will allow one canister to serve multiple origins. Origins are the way browsers control access to local storage & credentials. Currently, one canister can only have one origin at its disposal.


https://en.wikipedia.org/wiki/Same-origin_policy#document.domain_property

If we get the ability for one canister to have multiple origins, this opens up a lot of interesting use cases. Some of which will be needed by Neutron, where we want to have multiple apps inside one canister.
Each app will be on its own subdomain and not have access to the credentials and memory of others.

Another use case : You want NFTs to have their own HTML. If you use credentialless iframe the support is only 70%, the other browsers will give users to the credentials of the main page.

It doesn’t seem like it will break anything. From (far away) it appears it will be an easy-to-do feature.

The workaround right now is to use iframe credentialless tag or Cross-Origin-Embedder-Policy credentialless, which is 70% supported and its memory is ephemeral.

5 Likes

I second this proposal, it sounds like an excellent idea. This subdomain pattern is useful in many ways with established http servers such as Apache HTTPD and Nginx to drive alternative configurations (not just "Virtual Hosts) for web services.
I have not been involved in any IC developer work (yet?) but I can easily imagine there are many uses for this pattern there as well.

1 Like

Hi @infu

Interesting idea!

From the point of the boundary nodes, this would be not that hard to achieve with one big exception: the TLS certificate. We use wildcard certificates. The wildcard unfortunately only applies to one “subdomain-level” and not all of them. For example, we use the wildcard certificate *.ic0.app, which covers all direct subdomains of ic0.app, such as jglts-daaaa-aaaai-qnpma-cai.ic0.app and nns.ic0.app, but it doesn’t cover sub-subdomains as you propose, such as *.jglts-daaaa-aaaai-qnpma-cai.ic0.app. In that case, we would have to request one wildcard certificate for each canister, which is just not feasible with more than 300k canisters.

However, couldn’t you use custom domains for that? The documentation is here.

I see what is the problem now. Well, I don’t really need them to be sub subdomains.
If the canister is jglts-daaaa-aaaai-qnpma-cai.ic0.app
something-jglts-daaaa-aaaai-qnpma-cai.ic0.app still works fine
also jglts-daaaa-aaaai-qnpma-cai-something.ic0.app works

Custom domains can’t really be used. Let’s say there are 100k user-owned canisters and each one has 10 apps. The system will somehow have to control DNS records and make API calls to the IC DNS system whenever someone tries to install a new app and it will result in 1mil records in IC’s registry. Even if possible, users will wait 5 mins for the subdomain registration to complete. but it will probably require a centralized server to make the necessary calls.
The only other solution I can think of is to have our own boundary node, but that will centralize the whole thing and defeat its purpose

You could add a header so the canister knows which subdomain it’s serving
image

The IC is providing amazing crypto technologies like Threshold ECDSA, VetKeys, and so on which allow interesting use cases. Allowing a canister to control multiple origins will be in the same direction

3 Likes

Just trying to clarify my thinking here. The reason to have different domains is to make sure that II gives different principals to the same user in the iframe? Then security can run through the principal? Or are you going to check the origin in the http_request(but that won’t work for regular calls…they’ll just go to the same canister but have different signatures). And then I guess this doesn’t work if you use plug or other non-II wallet?

II will give different principals to different origins and one canister will be able to have more - I don’t need that, but you can consider it another feature.
It’s not really about wallets or identities, buts it’s connected. It’s about one canister able to control how browsers store things in their memory (cookies, localStorage, indexDB, service workers, your private keys, etc).

Let’s say you have a canister with 10000 Nfts (or apps, no difference) and they are serving HTML+JS. Right now you can serve every NFT under a single origin and it will have access to private keys and frontend memory - which is not what you want. Or you can try iframe with credentialless=true, but that has 70% browser support and 30% will be vulnerable (if apps run untrusted code, they can access everything). Also, your NFTs won’t be able to have persistent browser memory, because it will get wiped out whenever you close the tab. You will need one canister per Nft. Then you will have to worry about how these will communicate with inter-canister calls.

This feature will let you solve that with only one canister.

@rbirkner Do you think that is something Dfinity will be able to add in the near future? I can also try to expose something like a database from the main origin thru postMessage, which won’t bring nearly the same features and will be hard to do, but will get things to work securely (excluding all iPhones & desktop Safari) Actually… now that I’ve written it, I don’t think its worth even trying that ‘patch’ if it won’t work on iPhones.

I understand now this is about secure front-end storage. Makes sense. Another alternative here is to use a custom icx proxy like we do for prptl.io(although you lose some decentralization). We’d been putting dapps in the directory structure, but I understand now that that should probably have been via a subdomain.

A while ago, we have also been thinking about how to enable dapps to create many domains easily. One example use-case could be a blogging platform (like blogger.com) where a user can easily create a new blog under their own subdomain.

Your proposal of adding some string to the canister-id in the subdomain would achieve that. My concern with that approach is that we have to define the structure of that subdomain because otherwise we might get into a lot of weird situations (for example to which canister should a subdomain that contains two canister IDs forward to? jalts-daaaa-aaaai-qnpma-cai-jglts-daaaa-aaaai-qnpma-cai.ic0.app).

We are currently looking into a more general naming system on the IC that would allow a dapp to maintain it’s own mapping of domains/subdomains to canisters. Think of it as a more general custom domain solution, where you don’t just register one domain with the boundary node, but a domain with all the subdomains and you control the mappings in a “naming canister”. This is still in the early stages though.

1 Like

That will be a great feature for custom domains and will work for something like a DAO governed blogger. For our case - we will end up controlling the domain name all users go thru, which is not good.

It could be just something--jglts-daaaa-aaaai-qnpma-cai.ic0.app and the second part after -- is always the canister.

1 Like

Hi infu!
There was this service worker change going on so it took a while but now something--jglts-daaaa-aaaai-qnpma-cai.ic0.app seems to work.
Is this what you had in mind? Let me know what you think.

2 Likes

Works great! That will be enough to allow a front end canister to control multiple origins

1 Like