Skip to content
🎩 The mighty NodeJS password vault
JavaScript
Branch: master
Clone or download
Latest commit 806e088 Aug 7, 2019
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
build Tests cleanup Oct 17, 2015
scripts Reduce iocane iterations for test archive generation May 29, 2018
source
test Generate new test archive Jul 16, 2019
.babelrc Add transform runtime and support for got package Nov 13, 2018
.editorconfig Fix .editorconfig Apr 2, 2018
.eslintignore Fix VError referrence Apr 23, 2017
.eslintrc Update lint rules Jul 7, 2017
.gitignore Add code coverage Jun 4, 2018
.npmignore Update npm ignore file Jul 3, 2018
.prettierignore Ignore test file for prettier Feb 12, 2018
.prettierrc Add prettier Oct 18, 2017
.travis.yml Use trusty dist for web tests on travis Jun 3, 2019
API.md Prepare 2.15.3 Aug 2, 2019
API_WEB.md Prepare 2.15.3 Aug 2, 2019
CHANGELOG.md Prepare 2.15.4 Aug 2, 2019
CONTRIBUTING.md Tests tidyup + doc Feb 26, 2016
ENTRY_FACADES.md Add docs for facades Jul 7, 2017
LICENSE Initial commit Sep 6, 2015
README.md Add considerations to readme Jul 25, 2018
karma.conf.js Update chai and chai-as-promised Feb 13, 2018
package-lock.json Update lock Aug 7, 2019
package.json 2.15.4 Aug 2, 2019
webpack.config.js Add transform runtime and support for got package Nov 13, 2018

README.md


Buttercup Core


Buttercup core library

A NodeJS secrets vault.

Buttercup npm npm version node min version security encryption Join the community on Spectrum

Build Status

NPM

About

Buttercup is a password manager written in JavaScript for NodeJS and the browser. It's based around Archives that contain Groups and Entrys. Together, in a nested structure, these items act as a secure store for a user's credentials (much like standard managers these days). Entries allow you to store a credential's username and password, along with other miscellaneous properties (meta) and invisible functional info (attributes).

Buttercup archives sit in memory as an Object instance that is built from deltas that modify the structure. As changes are made to the archive, new delta commands are added to the history and saved to the archive's Datasource. Archives are compressed and encrypted before being saved.

Features

The core of the system, this Buttercup Core, boasts a few awesome features:

  • Deltas for storing archive history
  • Conflict resolution and archive merging
  • AES CBC/GCM encryption w/ 256bit keys
  • SHA-256 keys using PBKDF2 derivation
  • SHA-256 HMAC authentication
  • GZip text compression

This library also supports a variety of datasources for loading from and saving to:

You may want to read the API documentation (or for the web) and changelog. Please read our guide to contributing before creating any issues or pull requests.

Installation

To use Buttercup in a NodeJS environment, you can simply install and require it:

npm install buttercup --save
const { Archive } = require("buttercup");

To use Buttercup in a browser, you probably want to include the buttercup-web.js or buttercup-web.min.js file in the dist directory.

Usage

Buttercup centers around Archives which are the structures that manage stored secrets. An archive is a single encrypted data store which can be read from and written to a variety of storages (mentioned earlier). Archives are made up of Groups and Entries. A Group can be seen as a folder that contains Entries in a tree structure, and Entries are like files in that they contain secret information about some thing (website login, bank account etc.).

To get started, we should create a new Archive:

import { Archive } from "buttercup";

// Create an empty archive
const archive1 = new Archive();

// Create an archive with "General" and "Trash" groups
const archive2 = Archive.createWithDefaults();

Entries can't be added directly to an archive, but can be to Groups. Creating Groups and Entries is trivial:

const archive = new Archive();
const myGroup = archive.createGroup("My Group");
const myEntry = myGroup.createEntry("My Entry");

Every command on Archives, Groups and Entries modifies the Archive instance, but does not save it to storage. There is no command or need to commit any data - each instance links back to the original Archive. Archives are saved and loaded using Datasources:

import { Archive, Datasources, Credentials } from "buttercup";

const { FileDatasource } = Datasources;

const fileDatasource = new FileDatasource("./user.bcup");
const archive = Archive.createWithDefaults();
archive
    .createGroup("Websites")
        .createEntry("My bank")
            .setProperty("username", "user-name")
            .setProperty("password", "s3cureP4$$");

const credentials = Credentials.fromPassword("masterPassword!");
fileDatasource.save(archive.getHistory(), credentials); // returns Promise

Later:

const fileDatasource = new FileDatasource("./user.bcup");
const credentials = Credentials.fromPassword("masterPassword!");

fileDatasource
    .load(credentials)
    .then(Archive.createFromHistory)
    .then(archive => {
        // ...
    });

To see all available Datasources, checkout the @buttercup/datasources project. Credentials can be found at @buttercup/credentials. Both are bundled with the core library.

Considerations

Buttercup is an encryption library that is designed to work with very sensitive data. Using its APIs in a public space is strongly not recommended - any bad actor could simply hijack and misuse sensitive data passed through Buttercup. Use Buttercup in settings where security and privacy can be ensured:

  • Do use it in NodeJS by directly requiring items from its API, but ensure that your application is final
    • Be cautious using it in applications that are intended to run in a shared environment - Buttercup has several methods that can be overridden, which may pose a security risk in shared environments such as Node applications.
  • Do not use it in public spaces such as via a global variable
  • Do use it in bundled applications and executables, such as within an Electron app
You can’t perform that action at this time.