Skip to content

Optic - Secure Npm Release Automation

Set up Secure, Automated Npm Release Processes with Optic

The goal of software delivery is to release software to users and consumers. Automating the release pipeline with CI (Continuous Integration) and CD (Continuous Delivery) makes it easier to release high-quality code more often and faster.

In the JavaScript ecosystem, the Npm registry hosts 1.8 million packages, of which tens of thousands are released every day. Npm packages are easy to use, making them a popular choice. The downside of this popularity is that it increases the chances of these packages being a target for malicious code insertion.

Examples include the recent takeovers of the ua-parser-js , coa , and rc packages. In most cases, the accounts that are hijacked are Npm accounts that aren't using 2FA (two-factor authentication).

Why Optic?

Updates to packages have been made easier by tools like GitHub’s dependabot and actions , but releasing them manually with 2FA enabled can still be a pain.

Did you know that Npm plans to enforce 2FA for the top 500 packages by early 2022?

With tens of thousands of packages released every month, wouldn't it be great if there was a way to completely automate the release process?

Optic does exactly that!

Optic enables you to automate the release process of your Npm packages, apps and actions without compromising security. The Optic mobile app helps you to securely generate OTP tokens on the fly for 2FA protected Npm accounts. It allows you to do all that directly from the deployment pipeline at the click of a button!

Optic without Npm?

Optic is a very versatile tool that can work with different release pipelines. It can also be used for doing releases with python/pip or rust/cargo or any other combination!

All you need to do is configure the Optic GitHub action with the correct parameters for your release pipeline. We will be using Npm for the purposes of this blog post.

What is Optic?

Optic is an ecosystem of a mobile application, GitHub action, and backend application.

The mobile app stores Npm secrets, generates OTPs, and sends push notifications. The GitHub action triggers the deployment workflow. Backend server stores app subscriptions and generates Optic tokens.

How Optic works

In a nutshell, Optic works by automating the build and versioning process, as well as publishing Npm packages. It does all that without compromising the security. Publishing an Npm package requires you to authenticate using a publish token issued by Npm. These tokens are used when publishing packages using the Npm CLI. An OTP is required for the publishing process if you also have (2FA) enabled.

Features in Optic

  • Auto publish Npm packages using CI
  • Supports 2FA protected Npm accounts
  • Multiple repo owners/collaborators supported
  • Push notifications for approvals
  • Privacy first! Your Npm secret token never leaves your device
  • Mobile app with slick UI and biometric authentication
  • Completely open source with self hosting support

Architecture

Optic uses a Fastify server as the backend. The Firebase Firestore database stores app subscriptions and necessary user information. The mobile app is built using React Native and uses secure storage for storing Npm tokens.

Optic GitHub action is used to trigger the release process. You can set up Optic on your own servers. All instructions are mentioned in the repository ReadMe .

Optic repositories:

Setting up an Optic mobile app

In order to set up Optic, the first thing you need to do is generate a 2FA token for your Npm account, and then save it to your mobile device using the Optic app. This secret token is never transmitted to any 3rd party servers.

Instead, Optic mobile app requests the backend to generate a token that corresponds to your 2FA token and your mobile device. This Optic token is then stored on the device and used during the release process. The Optic token must also be saved in the repository secrets in order to be used by the release workflow action.

Screenshots of Optic mobile application

Now Optic is all set up for action, in the next section we will see how a release is published.

Setting up the Optic release action

Setting up a repository to use Optic is as simple as creating a GitHub workflow which uses the Optic action. The Optic action connects to a backend. The backend is nothing but a Fastify server that uses a Firestore database. The following snippet shows sample code for the Optic action.

YAML
jobs:

  release:

    runs-on: ubuntu-latest

    steps:

      - uses: nearform/optic-release-automation-action@v2

        with:

          github-token: ${{ secrets.github_token }}

          npm-token: ${{ secrets.Npm_TOKEN }}

          optic-token: ${{ secrets.OPTIC_TOKEN }}

          semver: ${{ github.event.inputs.semver }}

This GitHub action job configures the optic release automation action with the NPM_TOKEN and OPTIC_TOKEN . For the user that will receive the OTP, you can define Npm and Optic tokens in GitHub secrets. However, this is only necessary if you intend to publish to Npm.

By using the inputs, it is also possible to customize the commit message, tags and other release details. Please refer to the Optic repository ReadMe for more information about the parameters and how to use them.

Optionally, You can also include a build step. You simply need to add another parameter called build_command to the step to ensure that the build step runs before release. The build step can be defined as follows:

YAML
build-command: |

            npm install

            npm run build

Running the action

To publish a release successfully, we need to invoke the Npm CLI and provide the OTP. The optic action does that for you. When you run this action the following processes happen:

  • Repository source code is checked out
  • Package version is bumped as per the semver input configuration
  • If a build-command is configured then it is executed
  • Changes are committed and pushed to the release/${new semver version} branch
  • A PR is created with all the release details

Screenshot of the PR created by Optic:

Publishing a release

Once a maintainer reviews the PR and decides to merge it, the action sends the Optic token to the Optic backend server. The server attempts to retrieve the device and user information associated with the Optic token.

If a match is found, then a push notification is sent to the mobile device with options to accept or deny the release process.

If the request is approved, an OTP is generated and sent back to the server, this provides it to the Optic github action. The action then uses the Npm cli along with the OTP to publish a release.

Demo

A demo repository which uses the Optic action is set up and can be accessed here .

Wrapping up

Web application attacks are increasingly becoming stepping stones to more complex attacks. There is no time like the present to improve the security of your Npm account.

As the industry moves towards Zero-Trust Authentication, 2FA is a very important part of that strategy. Optic provides an easy and secure way to automate Npm releases. It eliminates all the hassles involved in manually publishing packages. It requires minimal resources to run on the server and database and has a lot of other features.

The NearForm team is constantly working on improving the application and adding new features.

Insight, imagination and expertly engineered solutions to accelerate and sustain progress.

Contact