Getting a Canister's Controller On-Chain

TL;DR
We want to allow a canister to query the status of another canister on mainnet, without being the controller. This will allow for an on-chain way of verifying that someone owns the canister they say they own.

The Current Way to Get a Canister’s Status / Controller

On Chain

You cannot make a call to whatever canister you’d like to, to get that canister’s list of controllers. The only way you can do this is in DFX, by running:

dfx canister --network=ic --no-wallet status <canister-id>

If you are the controller of the canister you will be returned with something that looks like this:

Canister status call result for <canister-id>.
Status: Running
Controller: <ID-of-controller>
Memory allocation: 0
Compute allocation: 0
Freezing threshold: 2_592_000
Memory Size: Nat(358829)
Balance: 4_899_635_664_822 Cycles
Module hash: <hash>

However, if you are not the controller you are returned a 403 Forbidden. This seems a bit redundant as the only way to get info on the controller is…. by being the controller :woman_facepalming:

Off-Chain

You can get the status / controller of any canister off-chain by using the state-tree of the IC. You make an HTTP call to the subnet and pass the desired canister ID along, and are returned the list of controllers for that canister.

Why This is an Issue

In a lot of projects, it is crucial to be able to verify that someone owns the canister that they say they own. It acts as a way of programmatically verifying that someone is who they say they are so that they can take some sort of action against that canister on an external service.

Without being able to verify that someone actually owns the canister they say they own, at least one party must rely on trust.

Isn’t there a workaround?

Yes, there are a couple of work-arounds but they all involve trust and leave the possibility of malicious actors.

  1. You can ask the canister to implement a method that could be called and would return the controller to the caller.

    Implementing a method that you have not written yourself involves trust because this method may not work how it is advertised to you.

  2. Verify that someone owns a canister by getting them to change the controller to your canister, with the promise of returning control back after verification.

    Again, the person who is getting validated is trusting the validator to return the canister exactly how they got it, or worse, return it at all!

Proposal

We propose that the management canister implements a way of making on-chain canister to canister query calls that returns the canister’s list of controllers. This could be exactly like the ‘canister_status’ method, but returning only the controllers and without restrictions.

This data is already available by using the method described in the “off-chain” subsection above.

Allowing for this would enable trustless verification that an actor owns the canister they claim to own.


We would also love to hear from the rest of the community on this topic as well. Maybe you’ve had the same issue, or maybe you’ve found a trustless way around this? We’d love to chat.

Thank you!

7 Likes

Same for the module_hash of the canister.

1 Like

An alternative we discussed was simply making the canister status available to all. It’s restricted now simply to be on the safe side (is reading the cycle balance too much information?), but given the headache it causes, I’m swaying to simply allow anyone to use canister_status.

A separate public method is fine, too.

2 Likes

I say it is too much. A separate method we need.

Personally, I don’t think that reading the cycle’s balance of a canister is too much information. However, maybe it would be best to leave that up to the community as a whole?

Additionally, how can we move this forward? It would be great to get this in-front of a wider portion of the community to get an answer to if we can just make ‘canister_status’ a public method, or if adding a separate method that only returns the list of controllers is the better route.

2 Likes

I would like to see this opened up as well. Currently developing an application where I need this info.

I think in general blockchains are not made for running private applications, but for running open composable services or at least those should be prioritised. This does not fit into that.