{"id":13523973,"url":"https://github.com/spinner-cash/launchtrail","last_synced_at":"2025-04-01T01:34:00.268Z","repository":{"id":113164495,"uuid":"483351828","full_name":"spinner-cash/launchtrail","owner":"spinner-cash","description":"Simple and Secure Release Management for Internet Computer Projects","archived":false,"fork":false,"pushed_at":"2022-06-20T17:24:10.000Z","size":101,"stargazers_count":43,"open_issues_count":2,"forks_count":6,"subscribers_count":0,"default_branch":"main","last_synced_at":"2024-11-02T08:31:44.548Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/spinner-cash.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2022-04-19T17:50:50.000Z","updated_at":"2024-06-03T05:15:23.000Z","dependencies_parsed_at":null,"dependency_job_id":"f7aab9ab-5a55-4baf-a0de-80df41d4a066","html_url":"https://github.com/spinner-cash/launchtrail","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spinner-cash%2Flaunchtrail","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spinner-cash%2Flaunchtrail/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spinner-cash%2Flaunchtrail/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spinner-cash%2Flaunchtrail/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/spinner-cash","download_url":"https://codeload.github.com/spinner-cash/launchtrail/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246567638,"owners_count":20798208,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T06:01:05.618Z","updated_at":"2025-04-01T01:33:55.259Z","avatar_url":"https://github.com/spinner-cash.png","language":"Rust","funding_links":[],"categories":["Developer Tooling"],"sub_categories":["CI/CD"],"readme":"\u003cdiv id=\"header\" align=\"center\"\u003e\u003cimg src=\"../../raw/main/icon/blue-on-white-outline.png\" width=\"300\"/\u003e\u003c/div\u003e\n\n#\n\n**LaunchTrail: Simple and Secure Release Management for Internet Computer Projects**\n\n![release](../../actions/workflows/release.yml/badge.svg)\n\nThere are many ways to configure and update canisters and services on the [Internet Computer].\nBut the challenge is how to do them in a secure and auditable manner, bringing more transparency and confidence to the community of a project.\n\nLaunchTrail solves the problem by introducing the concept of \"scheduled action\": an action that is scheduled to take place at a future time.\nThe purpose is to give the public enough time to evaluate the impact and risk of an upcoming change:\n\n- They can see it as safe and do nothing (i.e. wait for it to happen).\n- They can see it as risky, and either\n  - try to mitigate the risk for themselves, or\n  - alert the community and developer, and hopefully have the \"scheduled action\" revoked.\n\nAll users are given a chance to evaluate the risk and benefit of something that is about to happen in order to make suitable plans and be self-responsible.\n\nTo achieve this, LaunchTrail has to (1) be immutable, and (2) keep a public record of everything it has done or is about to do, including creating new canisters, installing or upgrading their code, change their settings, so on and so forth.\nBecause LaunchTrail is trust-worthy, a project launched this way will have a verifiable history right from the start.\n\nIt is important to recognize that **LaunchTrail is not a form of governance** -- it is merely a tool, a means to an end, but not something you can replace governance with.\n\n## How it works\n\nA project can choose to deploy its own LaunchTrail canister to manage all other canisters.\nA LaunchTrail canister mainly does two things:\n\n1. Schedule, execute, or revoke an action.\n2. Keep a complete record of all actions and their execution results.\n\nAn action is essentially an update call that is going to be executed by LaunchTrail.\nThe lifetime of an action is depicted below:\n\n```\n       /------\u003e Revoked\n      /\n  Scheduled -----\u003e Active -----\u003e Executed\n                      \\\n                       \\-------\u003e Expired\n```\n\nOnce its scheduled time has passed, an action can no longer be revoked, and is given a time window to execute the call.\nAn action may also expire if its execution is never triggered.\nDepending on how an action is configured, there are 3 roles:\n\n- *Submitter*: who is allowed to schedule an action. Configured globally in the LaunchTrail canister settings.\n- *Executor*: who is allowed to trigger the execution of an action. Configured per action.\n- *Revoker*: who is allowed to revoke an action. Configured per action.\n\nIt is entirely up to the submitter to explain (via a URL link) what an action is going to do, and to convince people why it will be safe and secure to do so.\n\nAn action can specify a SHA-256 checksum of the actual call argument without having to expose it before execution time.\nThis allows developers to patch zero-day bugs, because the checksum can be retrospectively verified against the actual argument after an action is executed.\n\nThat being said, it is still recommended that a submitter provides both the checksum and the call argument ahead of time for people to verify.\n\n## Usage\n\nThe first step is to [download a public release of lanchtrail.wasm](../../releases).\n\nThe latest SHA-256 hash of the `launchtrail.wasm` file should match the output below:\n\n```\n$ shasum -a 256 launchtrail.wasm\nf14477489935a855e8cd417dec5374585da6c03432ad0142be3d2507cb9dd117  launchtrail.wasm\n```\n\nYou can also fork this repo to have Github Actions build from source if you want to independently verify a release.\n\n**Deploy LaunchTrail**\n\nThe fastest way to deploy is to download the `Makefile` from a release and run the following command (requires [GNU make] and [dfx]):\n\n```\nmake deploy NETWORK=ic\n```\n\nThis will download release binaries (see `RELEASE_TAG` in the Makefile), verify checksum, and deploy a canister using [dfx].\nIf all goes well, you will find the canister id of \"launchtrail\" in the `canister_ids.json` file created in the same directory.\n\nOmit the `NETWORK=ic` part if you only want to test the deployment locally.\n\n**Make LaunchTrail immutable**\n\nIt is only when LaunchTrail is immutable that people can trust its behavior is exactly as prescribed by its code and consequently trust the records it keeps.\nThis can be done by setting the controller of LaunchTrail to the [Black Hole] canister.\nWe can achieve the same purpose by removing all controllers, but only controllers of a canister can check its remaining cycle balance.\nSo using [Black Hole] is recommended.\n\n```\ndfx canister --network=ic update-settings launchtrail --controller e3mmv-5qaaa-aaaah-aadma-cai\n```\n\nIt is no longer upgradable after this.\n\nNext, we should keep an permanent record of the LaunchTrail canister info:\n\n```\n./dist/canister-info fetch $(dfx canister --network=ic id launchtrail) \u003e launchtrail_info.json\n./dist/canister-info verify \u003c launchtrail_info.json\n```\n\nThe `canister-info fetch` command fetches the (certificate of) canister info, and the `canister-info verify` command reads the info from stdin, and verifies its signature using IC's public key.\nIf successfully verified, it prints in human readable text the canister id, module hash, controllers, and creation time of this info (nano seconds since UNIX epoch).\nThis can serve as a proof that LaunchTrail was made immutable before the time stamp shown in the canister info.\n\nBecause this info is verifiable against the IC's public key, all records created by the LaunchTrail later will be trust-worthy because:\n\n1. The LaunchTrail canister is immutable, We can be sure no one is able to change its code.\n2. The LaunchTrail canister's module hash can be verified against a public release. We can check its source code and Github build process to confirm.\n3. The LaunchTrail canister will record all scheduled actions and their execution results in an append only log stored in the canister's stable memory.\n\nAll action records can be retrieved programmatically by calling the `records(..)` method on the canister.\nAnd a simple HTTP interface will be provided in a future release for even easier access.\n\n**Deploy project canisters**\n\nThe LaunchTrail canister has a simple interface given below, and more details can be found in its [Candid file](./launchtrail.did).\n\n```\nservice : (InitialConfig) -\u003e {\n  submit    : (Action) -\u003e (variant { Ok : nat64; Err : SubmitError });\n  execute   : (ExecuteArgs) -\u003e (variant { Ok : Result; Err : ExecuteError });\n  revoke    : (RevokeArgs) -\u003e (variant { Ok; Err : RevokeError });\n  configure : (Config) -\u003e ();\n  stats     : () -\u003e (Stats) query;\n  records   : (nat64, nat64) -\u003e (vec Record) query;\n}\n```\n\nWe are working on a tool to help manage LaunchTrail actions and records, and will update this space once it is ready.\n\nFor now, you can look at how it is being used in [tests](./tests/) (requires [ic-repl]).\n\n## FAQs\n\n**Can we set LaunchTrail to be its own controller so that it can self-upgrade?**\n\nNo. Any upgrade to the LaunchTrail canister will destroy the trust in the records it keeps.\nA possible attack is that a submitter can upgrade LaunchTrail to a malicious version that over-writes its existing records, and then upgrade again to a good version to hide the trail.\nThis kind of change will not be observable after the fact unless somebody can catch it in the moment.\n\nA project wants to make sure *every action leaves a verifiable trail*.\nMaking LaunchTrail self-upgradable defeats this purpose.\n\n**Is there a way to migrate canisters to newer versions of LaunchTrail?**\n\nYes. We can use LaunchTrail to change the controller of a canister to another LaunchTrail canister, possibly of a new version.\nSo projects can decide for themselves whether they want to upgrade as LaunchTrail develops new features.\n\n**What is the recommended best practice to manage permissions?**\n\nThe developer of a project is in control of initial setup, so they can make their own choices.\nBut it is generally recommended that the developer takes the default *Submitter* and *Revoker* role.\n\nThe *Revoker* role, also requires a bit more caution.\nAt the moment a revoker can block any scheduled action, including actions that can change role settings.\nWe are working to improve this situation and hopefully bring more flexibility in a future release.\n\nFor canisters created through LaunchTrail, it is recommended to set their controller to only LaunchTrail.\nThis is to ensure all operations on these canisters have a verifiable track records.\n\n**How to use LaunchTrail with SNS (Service Neuron Systems)?**\n\nThe current recommendation is to use LaunchTrail to deploy SNS, and have SNS be a *Revoker*.\nSince SNS is not yet released, we will learn more details later.\nBut it is important to recognize that SNS does not replace LaunchTrail, nor vice versa.\n\n## Build LaunchTrail from source\n\nYou will need [GNU make], [binaryen] and a Rust compiler toolchain such as [rustup] in PATH to build LaunchTrail from source.\nThen you can type `make` in this project directory to build everything.\n\nIf you want to run canister tests (which requires [ic-repl]), you need to first start a dfx environment, for example:\n\n```\nmake dfx.json\ndfx start --background\nmake test\n```\n\nPlease feel free to submit bug reports or feature requests on Github.\nPull requests are welcome too!\n\nAll source codes are original and released under [GPLv3](./LICENSE).\nPlease make sure you understand the requirement and risk before using them in your own projects.\n\n[rustup]: https://rustup.rs\n[dfx]: https://smartcontracts.org/docs/quickstart/1-quickstart.html\n[GNU make]: https://www.gnu.org/software/make\n[ic-repl]: https://github.com/chenyan2002/ic-repl\n[binaryen]: https://github.com/WebAssembly/binaryen\n[black hole]: https://github.com/ninegua/ic-blackhole\n[Internet Computer]: https://wiki.internetcomputer.org\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspinner-cash%2Flaunchtrail","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fspinner-cash%2Flaunchtrail","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspinner-cash%2Flaunchtrail/lists"}