/secure-scuttlebutt

:nut_and_bolt: a secure database with replication that is guaranteed to work

Primary LanguageJavaScriptMIT LicenseMIT

secure-scuttlebutt

A secure database with replication that is guaranteed to work.

stability: level 1, experimental - expect breaking changes.

Following the node.js stability index, and the good parts of semver v1 does not mean stability, it just means there has been a breaking change since v0.

example

// create a scuttlebutt instance and add a message to it.

var pull = require('pull-stream')
var keys = require('ssb-keys').loadOrCreateSync(pathToSecret)

var ssb = require('secure-scuttlebutt/create')('/tmp/ssb1')

//create a feed.
//this represents a write access / user.
//you must pass in keys.
//(see options section)

var feed = ssb.createFeed(keys)

// the first message in the feed is always the public key.
//add a message to your feed.

//feed.add appends a message to your key's chain.
feed.add({type: 'msg', text:'FIRST POST'}, function (err, msg, hash) {
  //the message as it appears in the database.
  console.log(msg)

  //and it's hash
  console.log(hash)
})

// stream all messages by all keys.
pull(
  ssb.createFeedStream(),
  pull.collect(function (err, ary) {
    console.log(ary)
  })
)

// get all messages for a particular key.
pull(
  ssb.createHistoryStream(feed.id),
  pull.collect(function (err, ary) {
    console.log(ary)
  })
)

Concepts

Building upon secure-scuttlebutt requires understanding a few concepts that it uses to ensure security.

Identity

Each node's identity is represented by the hash of their public key. Although they are not "human readable", this does guarantee that you get unique identifiers (without a central registry) and it's infeasible for anyone to forge your identity.

Secure Data Structures

SecureScuttlebutt uses a signed block-chain per identity. Each block points to the previous block, the signing key, and contains a short message and a signature. Every identity has their own block-chain.

Each block-chain is an append-only data structure that can be written to exclusively by the keys' owner. Since the chains are append only, replication is simple, request the chain for that id, since the latest item you know about.

Replication

replication has been moved into the networking layer: scuttlebot

References

There are 3 types of objects - messages, feeds, and attachments. messages and attachments are refered to by their hashes, but feeds (block-chains) are refered to by the hash of their signing public key. Thus, chains can both refer to other chains, and also to particular points within other chains.

API

ssb = require('secure-scuttlebutt/create')(path)

Create a secure-scuttlebutt database at the given path, returns an instance.

require('secure-scuttlebutt')(db, opts)

Pass in a levelup instance (it must have sublevel installed), and an options object. The options object provides the crypto and encoding functions, that are not directly tied into how secure-scuttlebutt works.

The following methods all apply to a SecureScuttlebutt instance

SecureScuttlebutt#createFeed (keys?)

Create a Feed object. A feed is a chain of messages signed by a single key (the identity of the feed). This handles the state needed to append valid messages to a feed. If keys are not provided, then a new key pair will be generated.

Feed#add (message, cb)

Adds a message of a given type to a feed. This is the recommended way to append messages. message is a javascript object. it must be a {} object with a type property that is a string between 3 and 32 chars long.

Feed#id

the id of the feed (which is the hash of the feeds public key)

Feed#keys

the key pair for this feed.

SecureScuttlebutt#getPublicKey(id, cb)

Retrive the public key for id, if it is in the database. If you have replicated id's data then you will have the public key, as public keys are contained in the first message.

SecureScuttlebutt#createFeedStream (opts)

Create a pull-stream of the data in the database, ordered by timestamps. All pull-level options are allowed (start, end, reverse, tail)

SecureScuttlebutt#createLogStream({gt: ts, tail: boolean})

create a stream of the messages that have been written to this instance in the order they arrived. This is mainly indended for building views. The objects in this stream will be of the form:

{
  key: Hash, value: Message, timestamp: timestamp
}

timestamp is generated by monotonic-timestamp

SecureScuttlebutt#createHistoryStream ({id: hash, seq: int?, live: bool?})

Create a stream of the history of id. If seq > 0, then only stream messages with sequence numbers greater than seq. if live is true, the stream will be a live mode

License

MIT