Ultimately I implemented it with a custom solution - i.e. I’ve got an environment modules that contains a list of canister ids and a function that checks if a caller match this list.
// env.mo
module {
public let manager: [Text] = ["aaaaa-ziaaa-aaaai-aaafq-cai"];
}
// utils.mo
import Principal "mo:base/Principal";
import Array "mo:base/Array";
import Env "../env";
module {
public func isManager(caller: Principal): Bool {
hasPrivilege(caller, Env.manager);
};
private func hasPrivilege(caller: Principal, privileges: [Text]): Bool {
func toPrincipal(entry: Text) : Principal {
Principal.fromText(entry);
};
let principals: [Principal] = Array.map(privileges, toPrincipal);
func filterAdmin(admin: Principal): Bool {
admin == caller
};
let admin: ?Principal = Array.find(principals, filterAdmin);
switch (admin) {
case (null) {
return false;
};
case (?admin) {
return true;
}
}
};
}
// used in one of my actor
public shared({ caller }) func doSomething(): async() {
if (not Utils.isManager(caller)) {
throw Error.reject("Unauthorized access. Caller is not a manager.");
};
...
};