Canister History Proposal

About this proposal

  • We started this project a few months ago and already shared information during Global R&D on Aug 03 and Sept 14, 2022.
  • This proposal is a draft. We are looking for feedback from the community on the project goals and the selected solution.
  • We will publish more detailed technical specs once they are ready.

Problem

As the user, I’d like to check if I should trust this canister I’m interacting with

  • When I plan to invest in a token implemented by a canister or a canister that manages my financial assets
  • When a canister deals with sensitive information
  • When a canister implements a service I integrate my app with, and I’d like to assess the quality of the code.

The trust problem could be divided into four categories:

# Problem question Why is it important? How do we solve it?
1 Do I trust the underlying platform (IC/NNS)? If the platform is malicious, it can change any code and data and remove all the traces. Outside this document’s scope.
2 Do I trust the code of the canister (current and past)? THIS PROPOSAL If the code has backdoors or undocumented features. It can tamper with the data and move funds. The focus of this document. Developers will have an option to provide the source code for each code update of the canister. The code will be cryptographically matched with the WASM binary executed in the canister.
3 Do I trust the app governance (=future code)? Governance = ability to make code deployments. If it’s unclear who can modify the canister’s code - the data may not be safe. There are existing solutions for this problem including SNS and others.
4 Can I check my data? It may be hard for regular users to review the canisters’ code. However, it’s easy to check the data. For example, any user can spot unauthorized transactions. Canisters can expose data through UI or API. Canisters can log data into trusted external services like CAP.

Approach

We propose to split the solution into three separate layers.

Layer 1: Canister history - Protocol Change

IC will log all canister code and controller changes and save the hash of the executable WASM code in the canister memory. The WASM history could be used by users or community tools later to check against the developer-provided source code.

This feature will be implemented by the IC replica to ensure that the canister history is authentic.

Layer 2: Build verification - Community Project

The user will need to know with certainty which source code produced each WASM. A build verification tool will rebuild each source code version and check with WASM history for consistency.

This feature may be implemented by the community because when all input data is available anyone can execute the build script and check the consistency.

Layer 3: Source code analysis - Community Project

Since most users don’t have the skills to read and understand the code, the community will need to come up with a trusted 3rd party to vet code updates.

This feature may be implemented by the community.

Components

The proposed solution will consist of the following components:

  • Replica: store all past code and controller updates in the replica
  • DFX: create a new command to display the canister history
  • Canister Explorer: a sample web tool that uses publicly available APIs to display canister history. Similar functionality can be integrated into community tools as well.
  • Community tools: The community can create additional tools to store source maps, validate the builds, and review the source code.

Use cases

Use case 1: Enable the canister history to store code and controllers updates

Requirements:

  • Each canister will store the history of WASM updates (as a hash) and controller updates
  • There’s no additional charge for storing the canister history
  • We will store up to 1000 history records. When the limit is reached the oldest records will be deleted
  • The canisters can be deployed with the existing tools - the replica will save the history automatically. There’s no external API change for deployment and controller updates.

Note: We will NOT store the history of custom metadata updates because of space constraints.

Use case 2: Review the canister history

Scenario 1 (DFX + command line):

% dfx canister history hello_world
ID: 8b23a529-898a-4c41-b9df-5d715654f595 
Name: hello_world


History:
======================================================================================================
| Timestamp           | Change            |  Details                       | Origin                  |
======================================================================================================
| 2022-01-30 06:42:53 | Create            |                                | 400706e731be            |
| 2022-01-30 06:42:53 | Install           | Code: 40d6-a454-400706e731be   | 400706e731be            |
| 2022-01-30 06:42:53 | Reinstall         | Code: fac43bd4-f315-482c9fae   | 400706e731be            |
| 2022-01-30 06:42:53 | Upgrade           | Code: 1a1186bd-75b7-48da9d4d   | 400706e731be            |
| 2022-01-30 06:42:53 | Controller Change | Added: 858b31a5-2fcd           |                         |
|                     |                   | Removed: 45678765-abcd,        |                         |
|                     |                   | 400706e731be                   |                         |
| 2022-01-30 06:42:53 | Uninstall         |                                |400706e731be             |
======================================================================================================
  

Scenario 2 (Canister Explorer):

  1. User opens canister explorer web app http://explorer.ic0.app
  2. User enters the canister address
  3. User sees a web page with canister history

Use case 3: Access canister history over API

Assumptions:

  • Canister history will be available over Agent API and HTTP API (both)

Sequence diagram:
image

Next steps

We are looking forward to hear your comments and suggestions here. Please reply in this forum thread.

11 Likes

Another step in the right direction.

  • We will store up to 1000 history records. When the limit is reached the oldest records will be deleted

Perhaps a future extension could allow canisters to choose a larger limit, provided they are willing to pay the cycles.

  • Canister history will be available over Agent API and HTTP API (both)

By Agent API do you mean the canister API? I thought Rust and JavaScript agents (like any external agents) used the HTTP API to communicate with the IC.

As a pathological case (which I know is sort of rediculous), someone could upgrade their canister once to add an unwanted controller or update the code to do something they don’t want others to see and then run 1000 upgrades to hide the change.

Of course this would look pretty fishy to upgrade so much in a small amount of time. So I think most people will be happy with 1000.

1 Like

Yes I meant the canister API that needs to be accessed through the Agent API rather than HTTP.

Granted.

Yes it will look very fishy - probably this issue will sort itself out. We need some limit to the number of records to allow all canister to have history without building a complex accounting and dev tooling around it. The earlier proposals of this feature had three dfx commands and a bunch of special cases.

1 Like

@mikhail-turilin What might the timeline look like for the rollout of this feature?

We have identified a technical issue that makes it difficult for us to provide a good time estimate for the roll out of this feature. We’re working on resolving the issue and will share a timeline as soon as we are confident about it.

1 Like