npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

imicros-keys

v0.1.5

Published

Moleculer service for the imicros key store based on Cassandra database

Downloads

7

Readme

imicros-keys

Build Status Coverage Status

Moleculer service for the imicros key store

Installation

$ npm install imicros-keys --save

Dependencies

Requires a running Cassandra Instance.

Usage Keys Service

Set the master token as environment variable

process.env.MASTER_TOKEN = "MCN`1T-:,P41!QQ"
const { ServiceBroker } = require("moleculer");
const { Master } = require("imicros-keys");

broker = new ServiceBroker({
    logger: console
});
broker.createService(Master, Object.assign({ 
    settings: {
        cassandra: {
            contactPoints: process.env.CASSANDRA_CONTACTPOINTS || "127.0.0.1", 
            datacenter: process.env.CASSANDRA_DATACENTER || "datacenter1", 
            keyspace: process.env.CASSANDRA_KEYSPACE || "imicros_keys" 
        },
        expirationDays: 30  // rotate key after 30 days
    }
}));
broker.start();

The keys service is not started directly - the master service will create it after unsealing. After the first start call master.init to generate a new master key and retrieve the secret shares.

Keep the shares very save as the master key cannot be changed!

The following steps must be done after each restart with each single share:

  • call master.getToken with your share to receive a token
  • call master.getSealed with the received token to get the sealed nodes
  • call master.unseal for each sealed node with your share When the required number of shares is reached the node is unsealed and the keys service is started automatically.

The class unseal can be used to automate this process with a remote running daemon per share. The daemon requires three environment variables:

process.env.HOST = "https://my-host"  // can include a port number e.g. https://my-host:3000
process.env.SHARE = "e1b4cb2904ba87e2bc49cf1c09c886d3d14cf6ec93652162393bd0254d066843fa966c04a1d754196bb8992bd268700215ec3b6fcf4b1881c6ff79b1288533f5843bc8388bb5645de96e4937d156fd57d8169f58278b7fb1d3405b322f8ce8fa09b243ac70e1f5a38ca314b2aa5d7a1565bd5aeb756ca97197a7a9656121328b2506c0a479340ab1fbbce67364e4a8353107f792e428e776bdf0c0e2e7666e9efa62fd4d59afcd418fbd37f53cb49bc3011f64c6c070fe9a97762b0c27172ad7c1a070189ee2924bc78fda6b716ceadc1a54ff83954304a24e34bcd02fa3db2356236167c17333fa0eb0562f9e52f4d83942fdec928b4f0bed66d23ee24366c1"  // one of the shares created with the init action
process.env.SERVICE = "master"

To run the daemon call (or use nodemon or pm2)

node /lib/unseal

Services can now retrieve their secret keys with calling keys.getOek.

Actions master service

init { token } => { shares } 
unseal { nodeID, token, share } => { received }
isSealed => true|false
getSealed { token } => { unsealed:Array<String>, sealed:Array<String> }
getMasterKey { token } => masterKey  - only local calls!

Actions key service

getOek { service, id } => { id, key }
getSek { token, service, id } => { id, key }
deleteKeys { owner } => backup: { owner, services: { [service]:[keychain] }}

init

Called only once for all key services to retrieve shares. It generates a new master key and split it into the secret shares. These shares must be used for unsealing all running key services. Never change them in a running system with existing keys in the database!

let param = {
    token: "my secret master token"
}
broker.call("master.init", param).then(res => {
    // res.shares -> array of secret shares
})

getToken

Get a token for a share to call getSealed. The token is just used to avoid transfering the share in each call. Therefore should be called only once at the start of the unsealing program. Important note: For security reasons you will get always a token back - also, if the share is unvalid.

let param = {
    share: "..."            // as retrived by master.init
}
broker.call("master.getToken", param).then(res => {
    // res.token -> token to be used for calling getSealed
})

getSealed

Returns an array of node ID's of sealed nodes. If all nodes are unsealed, the array is empty. Important note: If the token is unvalid due to a wrong share in action getToken you will get an empty array back.

let param = {
    token: "my secret token retrieved by calling getToken"
}
broker.call("master.getSealed", param).then(res => {
    // res.sealed -> array of node ID's
})

unseal

Set a share for reconstruction of the master key and unsealing the node. Must be called for each sealed node ID with different shares until the required number of shares is reached. When the required number is reached the node is automatically unsealed and the key service is started.

let param = {
    nodeID: "...",          // as retrieved by master.getSealed
    share: "..."            // as retrived by master.init
}
broker.call("master.unseal", param).then(res => {
    // res.retrieved -> number of retrieved (different) shares
})

getOek

This method is called by other services to obtain their private key for encryption. It is called without ID to get the default key for encryption. After reaching the expiration date (according to the expiration days in the settings) a new default private key is generated. The retrieved ID has to be stored with the encrypted object and has to be given with the new retrieval to get the correct key for decryption.

let params = {
    service: "my service",                      // name of my service
    id: "35e53e27-3d91-4524-8c40-80566546f536"  // optional: getting the right key for decryption
},
broker.call("keys.getOek", param).then(res => {
    // res.id -> uuid of the key
    // res.key -> key
})