Skip to content

Instantly share code, notes, and snippets.

@mapmeld
Last active August 29, 2015 14:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mapmeld/7eb3b213358b55b74bdf to your computer and use it in GitHub Desktop.
Save mapmeld/7eb3b213358b55b74bdf to your computer and use it in GitHub Desktop.
Ωpm project

Ωpm project

Ωpm ("omega package manager") is an encrypted package manager with verifiable builds.

Concept

npm and other package managers have been criticized for including post-install scripts. Some packages (for example, C++ code in a Node package) differ depending on which machine builds them. For cryptography to be trusted, the web needs to embrace verifiable builds. These are also called "deterministic" or "reproducible" builds.

How can I use it?

Your "app" is a node.js/io.js server or application.

The "CLI" is a command-line interface, analogous to running "gem" or "npm".

The "Ωpm server" is a package host, analogous to rubygems.org or npmjs.org. Your username is your public GPG key.

Here's how your app can depend on Ωpm packages:

  • set up GPG and a key on your computer
  • check the Ωpm server for packages (todo: encrypted search)
  • include the commit SHA in the dependencies in your package.json (though this is a pointer, not a secure hash)
  • run "Ωpm install" using the CLI, or "Ωpm install [PACKAGE] [SHA]" for specific packages.
  • follow instructions and research when "Ωpm install" returns critical verified messages from developers
  • later on, you can run "Ωpm status" to get verified messages on any installed packages
  • in your code, use Ω("package", "SHA", callback); instead of require("package");

Here's how Ωpm uses encryption:

  • your local Ωpm CLI knows your PUBLIC key, and the Ωpm server's PUBLIC key
  • your CLI parses your dependency request, encrypts it so only the Ωpm server can read it, and makes one request
  • the Ωpm server finds all of the packages, encrypts them so only you can read them, and sends them back in one block
  • your CLI verifies the dependencies are what it expected - they should be the same on all machines
  • your CLI scans for signed updates from package developers (for example: security notices)

Here's how a package can be added to Ωpm:

  • follow the directions for writing an app based on Ωpm
  • only use Ωpm dependencies
  • limit your code to JavaScript files
  • limit your package.json to metadata, dependencies, and shortcuts like npm run and npm test
  • your local Ωpm CLI knows your PUBLIC key, and the Ωpm server's PUBLIC key
  • your local CLI encrypts your package so only the Ωpm server can read it. It will ask you to use the GPG CLI, which additionally signs the package with your PRIVATE key. This allows the server and users to verify that the package came from you.
  • after your first upload, and whenever you make updates, the Ωpm server and CLI will ask if you want to send important messages to users when they run Ωpm install or Ωpm status. You will need to sign the messages with the same key.

Why JavaScript?

I don't think it's the most important language for crypto, but it's accessible to many programmers, and I know it and the npm system better than other package managers.

Why not end-to-end encryption?

I spent time thinking about if Ωpm could use end-to-end encryption, but:

  • package-developers don't know your key - maybe you don't have a key yet - so how can they encrypt their code for you?
  • developers could host packages and the Ωpm server could be a router, but I don't see this making things more secure, as a hacked Ωpm server could be compromised to reroute package locations
  • Ωpm should only distribute valid packages, and it needs to inspect the packages to know this

What are the security risks?

the Ωpm client download could be compromised before you download it, so it doesn't do proper checks

Run tests, compare hashes, stay informed.

the Ωpm server could be compromised before you looked up a package, so the initial developer key you'd see would be wrong, making you think Alice signed several packages, when it was someone else instead

Developers should register their public keys in multiple places. Once you have their key, your Ωpm CLI will expect only updates and messages signed by the same developer. This has a lot to do with "web of trust" - http://mikegerwitz.com/papers/git-horror-story

package developers could be coerced to change code or release messages

once you have a working package, take care updating, and research solutions to any messages you receive when running Ωpm status

ideally encrypting package uploads, and allowing package uploads over Tor, would make it easier to hide the identity of package developers

if a package on my server was maliciously edited between install and runtime, couldn't the SHA in the require function also be maliciously edited?

I'm thinking that it would be good to keep the file with require functions as small as possible, and add some feature where you can tell if it's tampered with in other ways (GPG verify?).

package developers could write low-quality code

file issues and send pull requests - there's not much which can be done about this in any package manager

Plz help

I don't know if Ωpm can itself be designed to follow the rules of an Ωpm package. The initial network of packages will be very small.

I don't know if there is an easy way to move npm modules with GPG-signed git repos over to Ωpm.

Latest release

Install

In the current version (0.0.3) the "Ωpm install" downloads a package from npmjs.org or a git repo, but does not run any other scripts or compiling steps. Its output package.json does not vary between installs. It also runs "keybase dir verify" on each package, which checks for a signed SIGNED.md file with SHAs of all files in the directory.

The install step should also support signed git repos.

The keybase command currently throws errors on even the omega-sqrt package, because when running install, .gitignore is renamed as .npmignore, and package.json is modified. This happens even when installing from a git repo.

Require

In the current version (0.0.3), Ω("package", "sha", callback) is an async replacement for require. It verifies the SHA of a node_module/package directory before require-ing it. Due to changes in Ωpm install, this SHA should be the same for all installs of a package.

App

Template app: https://github.com/mapmeld/omega-template-app

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment