The difference between raw.ic0.app and ic0.app

Can you please tell me the difference between raw.ic0.app and ic0.app?
I am aware that service worker and boundary node are involved.

For example, webI Maps (the map service on Dfinity) is provided by raw.ic0.app, but when I access it with ic0.app, I get “Body does not pass verification”.

webI Maps(raw.ic0.app): https://pp5h5-jaaaa-aaaad-qalvq-cai.raw.ic0.app/
webI Maps(ic0.app): https://pp5h5-jaaaa-aaaad-qalvq-cai.ic0.app/

The difference between two suffix is the Certification

1 Like

^ That document is pretty complicated lol…

In simple terms, when you make a request to a resource (like an HTML page or image) on raw.ic0.app, the boundary node returns the resource as is. Just like with any normal website.

When you make a request to a resource on ic0.app, the boundary node returns the resource, which itself is “certified” by the canister (e.g. a dfx assets canister). In other words, the resource is signed by the subnet hosting the canister. At the same time (or perhaps before?), the boundary node also returns a service worker, which is a piece of JavaScript code that runs in the client browser and that intercepts the certified resource and verifies its certificate using the Internet Computer public key to make sure it’s valid. The service worker is needed because it’s the only way to run JavaScript code to intercept that web resource.

ic0.app is more secure but as a result more complex.

(If any of this is incorrect, please let me know! I really wish this was documented better.)

2 Likes

Thank you very much.
Another thing I am wondering is why resources that cannot be certificated at the boundary node (e.g. webI Maps) cannot be so?
I would appreciate it if you could tell me.

It’s not the boundary node that does the certification. Certification happens on the canister level, i.e. is done by a subnet. Any certified response has to be pre-certified during an update call, so that the certificate can simply be fetched in a query call at a later point in time. This means that every possible response would have to be pre-computed, which can be an impossible task.

Trivial example: you have a function that simply returns input + 1. To serve certified responses for this function, you’d have to compute the function value of every possible number input, which is an impossible amount of work.

More complex example: See the NFT sample canister docs, and the code. Attaching the certificate to a response happens here, and pre-computing the cert happens in this function.

1 Like