How to deploy and distribute a censorship-resistant upgradeable dApp
From the inception of the first versions of Aragon Core we took building a truly decentralized app very seriously. We decided that just using Ethereum as the settlement layer was not enough, because if a significant part of the infrastructure depended on centralized servers, we would quickly become a central point of failure that could be taken down.
However, relying on regular users to review, download and keep up to date versions of all the required software can become a barrier for adoption beyond developers or very tech-savvy users. In order to fully run Aragon Core, both IPFS and Ethereum nodes are required, both of which require setting up a complex environment and there are currently no good options for running them on mobile devices.
In this post we explore the process of how Aragon Core and the different apps the Aragon team has built so far (Voting, Token Manager, etc.) get deployed and how we make them available to users regardless of their skill level.
APM, the Aragon Package Manager
Upgradeability is an important focus for us, and one of the key features of aragonOS. We are dealing with experimental and bleeding edge technology, and it would be such a step back forcing users to commit forever to whatever version of the software was available when they created their organization.
We decided to build APM as the main way to distribute different versions of the packages that comprise Aragon Core. A package or repository (repo) in the APM keeps track of evolving versions of its contents (the webapp component typically) and smart contract code (if applicable).
APM architecture: Registries, repos and versions
Each APM Registry is a smart contract that owns an Ethereum Name Service(ENS) domain and therefore can create subdomains for its repos. This gives users the ability to find repos with human-readable names. We envision that many APM registries will be created for different purposes and types of packages. In the case of Aragon, we use the
aragonpm.eth registry to host our core components and all the 'first party' apps that we develop. For now only people within the organization can create new repos. We also have the open.aragonpm.eth registry for community developed packages, where anyone can create repos.
At the repo level, each repo can have its own rules that govern how new versions can be published using the aragonOS access control list. This allows for setting up different types of processes depending the importance of the repo or the nature of the upgrade (major, minor or patch).
A Repo is created in a Registry and can have many versions published over time
As explained above and in the figure, a repo keeps versioned history of content and smart contract code tuples. The content is an on-chain reference to a blob of data that lives off-chain (we support IPFS or HTTP addressing currently). By using IPFS whoever is fetching the content has the assurance of the integrity of the data and that it hasn't changed since it was published. Aragon always uses IPFS for publishing, but having HTTP is useful for testing purposes or for less critical code.
The smart contract code only applies to packages that have an on-chain contract component associated with a particular version. It can be the implementation code for upgradeable Proxies or a smart contract that can be directly used. By having these code addresses stored on-chain, smart contracts can use APM directly to get the latest version of the code for a repo. At Aragon we benefit from having these contract references on-chain for our dao-kits to know what the latest version of an app is (to set up the proxies), or for locating the smart contract for a dao-kit that can create and set up a DAO (which is interacted with directly).
APM gives users complete transparency over all deployments and traceability of what process publishing a new version entailed. At the moment, Aragon One's dev team can directly publish new versions, but in the future, publishing new versions to repos could require a more complex governance process. Because APM repos are Aragon apps that are part of the APM Registry DAO, repos can use any of the aragonOS-compatible governance apps to govern the process for creating new updates.
It is important to point out that APM just acts as a Schelling point to what the last version of a repo is, but all upgrades are opt-in and DAOs through their governance mechanisms need to decide to upgrade, or keep using an old version. Automatically upgrading all of Aragon's DAOs is extremely dangerous regardless of what the governance mechanism over upgrades is. That's why by default all upgrades must be started within the DAO, however someone could build an auto-update contract that makes the DAO and its apps up to date to the latest version in APM.
We have recently started to document all our deployments and the governance over different repos in our APM registry. This gives total transparency over who can deploy new code and also a full audit trail of the changes that were pushed, which can be reproduced locally in order to verify their integrity. The next step on this front is to have these reports be automatically generated and with better visualization of the information. You can check out the deployment history in the deployments repository below:
apm-serve, bridging the gap to the web2
Even though anyone running Ethereum and IPFS nodes can directly connect to APM to fetch repos and use the apps, it presents a significant barrier to entry for less sophisticated users or newcomers that are just trying Aragon out.
We decided to create apm-serve to balance decentralization and usability, knowing that a motivated user could always have a fully trustless set up without requiring much infrastructure work or resources. apm-serve acts as a bridge between APM and someone casually browsing the web. We were inspired by the IPFS gateway when building apm-serve, which brings access to IPFS hosted content to anyone surfing the web. apm-serve is to APM what the IPFS gateways are to IPFS.
This tool, hosted on a server located in Switzerland, is able to serve content from APM just by performing a simple HTTP request to the server. We host our instance of apm-serve on aragonpm.com, signaling the bridge to the on-chain
aragonpm.eth domain name.
When someone goes to http://aragon.aragonpm.com, apm-serve will find the APM repo for
aragon.aragonpm.eth and then get its latest version. Once the version is found, apm-serve will fetch from IPFS the content associated with that version and serve it back to the user. The bridge is built so that it can serve any APM repos that get published automatically, without needing any further configuration.
Aragon Core being served with apm-serve
Thanks to apm-serve, any static website can easily be published in the decentralized web, with the ability to have ECDSA signatures and arbitrary governance to any deployment, and still be served using regular HTTP requests.
Interacting with APM: apm.js and Aragon CLI
In order to interact with APM registries we have built apm.js, a standalone JS library to inspect APM repos, get their different versions and fetch the referenced content. In fact, apm-serve is just a very thin server layer on top of apm.js. The library also allows interaction with the APM contracts in order to create repos or new versions in repos.
The Aragon CLI also uses apm.js to provide a great developer experience to publishing new versions to APM repos. The CLI APM commands, accessible doing
aragon apm, are the easiest way to manage APM repos.
Using the Aragon CLI to publish a version to an APM repo and inspecting it
Further uses of APM
As explained before, APM can already be used to verifiably deploy new versions of static websites completely unrelated to Ethereum. Because APM is built on top of Ethereum and IPFS, the authorship and integrity of every change are maintained, while at the same time being censorship-resistant and easily mirrorable.
Another very interesting usecase of APM is DappNode, who are using APM as the backbone of their Docker registry for packages. Thanks to using APM, packages in DappNode with different levels of criticality can have custom governance processes for publishing updates.
APM powered DappNode package registry
For the next versions of APM we are also looking into compatibility with the Ethereum Package Manager spec for smart contract packaging and distribution. APM could be used to provide an extra layer of authorization and traceability to package upgrades.
We'd also love to see APM being used as a language agnostic package manager for open source libraries and frameworks. Heavily used centralized infrastructure for package management such as NPM is a security hole the Ethereum developer community relies on heavily right now. A decentralized NPM with a more sophisticated security model could be built on top of APM, which could have helped prevent some of the past issues with NPM.
To keep up with the progress of Aragon
Subscribe to Aragon Project blog
Get the latest posts delivered right to your inbox