Hello Radicle Community!
Radicle agreed to fund a grant researching package releases. This research focuses on packaging Radicle git repos into a software library, and then using a git tag to signal a āreleaseā. Some of those ideas come from this previous thread. The terminology and workflow is a little different for each programming language, so Iām starting with existing, well-established workflows from the JavaScript, GitHub, and npm ecosystem.
Introduction
Iām at a point of the research where Iām investigating the concepts of packaging signing, security, and supply chain attacks. Iāve been trying to understand the security model at the center of Heartwood protocol and Radicle Identity. Iāve also been comparing that with the npm package signing workflow.
The deeper I go down this rabbit hole of security and package signing, the more confused I get and more hopeless it seems. There are many attack vectors, and solving one of them does little to secure the entire supply chain. So I thought it would be a good idea to turn to the Radicle community, to see if we can collectively find some answers.
Background
For reference, I should point out the first two parts of the research Iāve already completed:
- Part 1 focused on how to generate a npm package from a Radicle git repository, and then how to include that package as a npm dependency in another JavaScript program.
- Part 2 focused on taking the output of Part 1 and integrating it with Verdaccio, which is an npm package cache. It will cache npm packages locally and serve them. This allows the opt-in use of Radicle as a package delivery system without changing any existing workflows (which is good UX).
So Part 1 showed that itās possible to generate a package, and part 2 shows that itās possible to deliver and cache the package. Parts 1 and 2 proved what is possible, now itās time to review those results through the lens of what is prudent. Itās time to look at the workflows adversarially and consider how a malicious actor could inject viruses and other things into a package.
Workflows
From my perspective, there are two workflows to take from here:
- Adopt an existing package signing workflow.
- Leverage the existing identity workflow built into Radicle
Existing Package Signing Workflows
Iāve studied the npm package signing workflow more than any other, but at a glance, it seems like there are few standards that are shared across package managers.
The npm package signing workflow gives a brief description of how the signing workflow would be supported by a third-party registry (like Radicle). Dev work would be required to integrate the same method into radicle-cli. In theory, the end result would be that packages generated from Radicle repositories could be passed around, and delivered over separate mediums (like Filecoin or Arweave). The signing process alerts the user if the package has been tampered with, but there is a lot of nuance to that statement. Itās unclear to me if the end result is worth the cost of the effort.
So my first question to the community: Is working hard on a package signing scheme even worth it? It seems like a very hard problem to get right, and it does not appear that there are many industry examples to point to of what getting it right looks like.
If anyone would like to propose a package signing workflow, please point out the following parts of the workflow (at a non-technical, high-level):
- How does the package creator sign the package?
- How does the package consumer verify the signature?
- How would we integrate the workflow into Radicle?
Leveraging the Existing Identity Workflow
Radicleās identity model works pretty good as a security model. For example, if a package consumer is getting the package directly from a Radicle repository, they are implicitly trusting the repository owner. Thatās a pretty simple, clear chain of custody.
That model is broken however, if the package does not come directly from a Radicle repository. For example, if the package is uploaded to Filecoin or Arweave, and then consumed from there. Without package signing, there is no secure connection that the package consumer can verify.
There is a trade-off there: Getting a package directly from a Radicle Seed node is more secure, but how reliable is it? Being able to put packages in different locations (Filecoin, Areweave, Seed nodes, npm) improves reliability and availability, but it reduces security.
Research Implications
In Part 1 and Part 2 of my research, I was careful to point out when a package was coming directly from a Radicle Seed node or not, because of the trade-offs described above.
To summarize that research to the parts the are salient for this conversation:
-
In part one I showed the āgit+httpsā format allows a JavaScript application to specify a package dependency that can be downloaded directly from a Radicle Seed node, which is a secure way of retrieving a package. But in part two, I showed that Verdaccio will not cache that format, so if the Seed node is unreachable, then the dependency can not be installed (bad for availability).
-
In part two I showed that the āfile-proxyā app can download a specific package from a Radicle Seed node, in a way that Verdaccio can cache it. This is the best solution Iāve found in terms of security and availability.
Questions for the Radicle Community
So with this background, letās open it up to discussions. I feel the use of āfile-proxyā (from Part 2) strikes the best trade-off between security and availability. But perhaps there is a better way? Or perhaps there are security considerations I havenāt even considered yet?
Iām sure there are people in the Radicle community that are more knowledgeable about package signing methods and their trade-offs than I am. Please use this opportunity to educate us!