Skip to content
proxy designed to reduce the attack surface of npm publish
TypeScript JavaScript HTML CSS
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.github build: run CI on pull_request event (#35) Jan 11, 2020
config
docs docs: continue to flesh out README.md/other docs, add back documentat… Dec 30, 2019
public refactor: use handlebars for views (#43) Jan 14, 2020
src refactor: update headers, organize imports, etc (#48) Jan 15, 2020
test refactor: update headers, organize imports, etc (#48) Jan 15, 2020
views refactor: use handlebars for views (#43) Jan 14, 2020
.eslintignore feat!: initial commit of project Nov 23, 2019
.eslintrc.yml feat!: initial commit of project Nov 23, 2019
.gcloudignore feat!: initial commit of project Nov 23, 2019
.gitignore refactor: use handlebars for views (#43) Jan 14, 2020
.nycrc test: building framework for testing (#34) Jan 11, 2020
.prettierignore refactor: update headers, organize imports, etc (#48) Jan 15, 2020
.prettierrc feat!: initial commit of project Nov 23, 2019
CHANGELOG.md
CODE_OF_CONDUCT.md feat!: initial commit of project Nov 23, 2019
CONTRIBUTING.md feat!: initial commit of project Nov 23, 2019
LICENSE feat!: initial commit of project Nov 23, 2019
README.md docs: update README contributing link (#45) Jan 14, 2020
app-external.yaml chore: added usage instructions for GAE (#9) Dec 19, 2019
app-internal.yaml chore: added usage instructions for GAE (#9) Dec 19, 2019
codecov.yaml feat!: initial commit of project Nov 23, 2019
documentation.md refactor: use handlebars for views (#43) Jan 14, 2020
index.yaml feat!: initial commit of project Nov 23, 2019
package-lock.json chore(deps): update dependency cross-env to v7 (#49) Jan 27, 2020
package.json chore(deps): update dependency cross-env to v7 (#49) Jan 27, 2020
renovate.json feat!: initial commit of project Nov 23, 2019
tsconfig.json feat!: initial commit of project Nov 23, 2019
tslint.json feat!: initial commit of project Nov 23, 2019

README.md

Wombat Dressing Room

Google's npm registry proxy. Designed to reduce the attack surface of npm packages.

Build Status Known Vulnerabilities Code Style: Google

What it does

  • You publish to Wombat Dressing Room, and it enforces additional security rules, before redirecting to registry.npmjs.org.

  • Publishes are made from a single npm account with 2FA enabled (a bot account).

  • Publishes can be made using the npm CLI, by making Wombat Dressing Room the default registry (npm config set registry https://external-project.appspot.com).

Deployment

This service is deployed in 2 distinct services: an external service for registry access; and a protected service for authentication/authorization (you can use a proxy, such as IAP, to limit access to the authentication server).

Prerequisites

Wombat Dressing Room requires:

Create an npm account

You will need to create an npm account, which will be used or publication. This account should be configured such that 2FA is enabled for authentication and publication. When you are given a QR code to scan for your authenticator app, use a QR code reader to fetch and store the secret associated with the 2FA configuration. You will also need to scan the QR code with an authenticator app, so that you can provide an OTP token to npm.

Create a GitHub OAuth Application

As well as an npm account, you must create a GitHub OAuth application. These credentials are used when performing authenication: both when logging into Wombat Dressing Room, for creating tokens, and when verifying certain types of tokens.

Note: the Authorization callback configured with the OAuth application should be the URL of the internal service, with the suffix /oauth/github.

Setup your environment

Once you've addressed the prerequisites, you should create environment files in the config/ directory populating the appropriate variables.

In order to start this service in development you need to create a config/local.env, in order to deploy you'll need an config/external.env and config/internal.env.

Internal environment variables

NPM_OTP_SECRET={the text value of the otp secret}
NPM_TOKEN={the npm token}
GITHUB_CLIENT_ID={github app id}
GITHUB_CLIENT_SECRET={github app secret}
DATASTORE_PROJECT={project datastore is configured for}
LOGIN_ENABLED=yes-this-is-a-login-server
LOGIN_URL=https://project.appspot.com]
REGISTRY_URL=https://external-project.appspot.com

External environment variables

NPM_OTP_SECRET={the text value of the otp secret}
NPM_TOKEN={the npm token}
GITHUB_CLIENT_ID={github app id}
GITHUB_CLIENT_SECRET={github app secret}
DATASTORE_PROJECT={project datastore is configured for}
LOGIN_ENABLED=this-is-not-enabled
LOGIN_URL=https://project.appspot.com]
REGISTRY_URL=https://external-project.appspot.com

Development environment variables

NPM_OTP_SECRET={the text value of the otp secret}
NPM_TOKEN={the npm token}
GITHUB_CLIENT_ID={github app id}
GITHUB_CLIENT_SECRET={github app secret}
DATASTORE_PROJECT={project datastore is configured for}
LOGIN_ENABLED=yes-this-is-a-login-server
LOGIN_URL=http://127.0.0.1:8080
REGISTRY_URL=hhttp://127.0.0.1:8080

Deploy the application

To configure the Google App Engine services used by Wombat Dressing Room, perorm an initial deployment:

  1. install the gcloud command line tool, and run gcloud auth login.
  2. run GCLOUD_PROJECT=my-project npm run deploy, where my-project is the project configured in Prerequisites.

Create a datastore table

The tokens used by Wombat Dressing Room are stored in a datastore table, before accessing the application for the first time you should run:

GCLOUD_PROJECT=my-project npm run create-indexes

To populate this datastore schema.

Note: it takes datastore a while to initialize the first time you run the application. You can view the status of index creation in the Cloud Console.

Protect your application with IAP

Wombat Dressing Room consists of an internal application, used for authorization, and an external app, used for proxing to npm. You should limit access to the internal application, a great way to do so is with IAP: configuring the default application, such that only select accounts have access; and configuring the external application with the allUsers group, such that anyone can access the proxy.

Developing the service locally

Populate config/local.env, and run:

npm run develop

Deploying updates

Populate config/external.env, and config/internal.env, and run:

npm run deploy

Contributing

Contributions welcome! See the Contributing Guide.

License

Apache Version 2.0

You can’t perform that action at this time.