Most methods within those canisters are declared as public shared, because I need to use them from other canisters (frontend canister or even other canisters). But this means those methods are accessible by anyone outside the app, right?
Question
What are the recommendations for protecting access to methods of those canisters, considering that I will also need access to those methods from outside the app, from specific principals (for monitoring purposes) ?
I’ve browsed around the forum threads a bit, but haven’t found anything relevant. I’m probably not using the right keywords, because this seems like an obvious security concern.
Yes, anyone can access the functions. The best way to test if a function is completely public is to try it without authenticating to the Candid UI (the backend link provided) when you deploy (either locally or on the mainnet).
An initial thing is to require users to authenticate to access the function.
For example, in Rust:
let caller = ic_cdk::caller();
if caller == Principal::anonymous() {
panic!("Anonymous principal not allowed to make calls.")
}
caller
It sounds like you want to take a step even further by only allowing users who have authenticated on your frontend to access any backend functions. There isn’t a built-in way to do this.
Thanks ! Actually, I want to go even one step further: I want some methods to be usable only by a predetermined list of canisters (other canisters of my app + me). I guess I can manually check that the caller is among that list. But yes, my question was exactly this: is there any built-in way of doing this? (I use Motoko)
You could create a hashmap of the list of canisters (an array would work too but I prefer hashmaps) and loop through it to check the caller is one of the principals in the hashmap.
I implemented an access control mechanism based on access tokens in the ic-oss service.
This allows for fine-grained permission control over files, folders, buckets, cluster, including support for permission inheritance in the file tree. It is a highly flexible access control system designed to meet enterprise needs.
I plan to develop it into a standalone access control service that can be called by other canisters.
Yes, I see. I’m already using Result on all my methods so it should be straight forward to add.
As for your last sentence, I agree, but it just feels like every single project building on canisters will want a way to protect their methods, no? So I’m a bit surprised that there’s no “built-in” way to do this already.
In case someone else is interested, I dug up this topic which appears to be doing exactly this in Motoko.