NAV Navbar
javascript python ruby java php go swift

Introduction

TozStore makes application-level, end-to-end cryptography easy for developers. Most devs aren’t trained in cryptography, so TozStore provides devs with familiar, easy to master tools that run complex, powerful cryptographic operations under the hood. TozStore handles those areas of cryptography that are easy to get wrong (e.g. key generation, algorithms, modes). Whether you are new to cryptography or already highly experienced in implementing crypto, this guide will quickly have you comfortable using TozStore to drastically improve the security of your applications and establish a trustworthy way to write, read, and share data.

Strength of Application-Level Encryption

TozStore provides application-level encryption. Systems that take advantage of encryption to strengthen security typically use infrastructure-level encryption and not application-level encryption. Application-level encryption provides greater application security than infrastructure-level encryption.

With infrastructure-level encryption, networking or database infrastructure is encrypted, so data is encrypted when it is in this infrastructure and not encrypted when it is outside this infrastructure. Infrastructure-level encryption approaches like Virtual Private Networks (VPNs) protect data in transit and can control access to a network. Anyone with access to the network, has access to the services and all data within those services. With infrastructure-level encryption, data will no longer be secure if data leaks outside of the network infrastructure or an attacker bypasses standard access control mechanisms.

TozStore provides application-level security that secures data for its entire life-cycle. Data gets encrypted where it is generated (written) and decrypted where it is consumed (read), providing end-to-end encryption. TozStore encrypts data records individually, providing powerful and fine-grained access control for sharing and revoking access to records. As result, data carries its own security. No matter what infrastructure it crosses, data remains encrypted and secure. Even if data leaks outside of the network infrastructure, gets backed up to an insecure location, or is hacked by an online adversary, the encrypted data remains secure.

For Devs New To Crypto

You do not need to study cryptography in order to integrate strong cryptography in your applications. TozStore will allow you to properly implement strong cryptography with developer-friendly tools that provide a layer of higher-level abstraction over complex cryptographic operations. Devs who are not familiar with cryptography will likely want to know first and foremost how they can trust both TozStore and their own use of TozStore tools to properly implement cryptography in their applications.

Getting Started

Endpoints as TozStore Clients

As a developer using TozStore, you first need to determine what constitutes an end-point in your system. You can install the necessary TozStore SDKs (software development kits) to gain access to TozStore tools. TozStore currently provides SDKs for the following languages: JavaScript for the browser, back-end JavaScript (Node), Python, Ruby, Go, plain Java, Java for Android, Swift,and PHP.

TozStore understands endpoints as clients. Every TozStore client needs a unique set of client credentials that must be generated and provided securely as parameters to instantiate a client instance using an SDK. The client instance possesses read, write, share, revoke, and other methods.

A client's credentials are integrally involved when they perform cryptographic operations, prime examples being when client writes (encrypts), reads (decrypts), and shares access to data records. Because of this, compromised private keys pose a great security risk, and using TozStore properly requires strong key management.

Client Credentials And Key Management

Key management is a foundational security concern while using TozStore. Most significantly, client credentials include a private key that is critical for security. Making a private key public compromises the security provided by TozStore the same way leaving a key in a lock would undermine the security provided by the lock. Losing access to keys also poses the risk of losing access to data, as data encrypted with a client's credentials cannot be decrypted without the relevant client credentials.

The security of data stored using TozStore depends upon the key management practices used surrounding TozStore tools. The section on Key Management in this guide offers advice on making a key management plan. In this section, the team at Tozny who created the TozStore system will share some of our concerns, best practices, and decisions regarding key management. Hopefully, this will help you confidently and quickly decided on the key management plan that is right for your system.

Once you have decided on a way to manage your client credentials, TozStore provides a few ways to generate client credentials. Clients have the option of whether to store an encrypted back-up of their credentials on the server. In choosing a workflow for registering clients, consider the balance between concerns over the security of private keys and the ability to recover lost private keys.

Generating Client Credentials

Regardless of how you choose to generate client credentials and register clients, you will need to use the Tozny Dashboard, a collection of Tozny tools. Create a free account with Tozny. Save this link for easy, future use.

The first way to generate client credentials is go to the Dashboard then Clients tab and click the action button to create a new client, then gather the client's credentials presented as a JSON. In this one action, the Dashboard will generate the needed keys, register the client with TozStore and receive the resulting TozStore client ID and credentials needed to authenticate with the Tozny API. Additionally an encrypted back-up of the client's credentials in TozStore. To avoid having a backup created read on for how to create clients programatically below.

This same workflow can be implemented using a TozStore SDK to dynamically generate client credentials, register, and back-up clients. However, you may be less concerned with being able to retrieve lost private keys and more concerned with stronger security. In this case, you may want a client's private key to only ever be available locally, so you will not want to back-up client credentials in TozStore. In this case, you can dynamically generate client credentials and register clients without backing up client credentials in TozStore.

Dynamically generating client credentials using a TozStore SDK requires first generating a client registration token using the Dashboard. When you generate client credentials and register clients with the Dashboard, your Tozny account username and password enable access to the Tozny API. A client registration token stands in for this layer of authentication.

Overview of Client Credentials

A developer does not need to understand the role client credentials play in allowing a TozStore client to encrypt, decrypt, and share data securely to use TozStore. However, a basic understanding client credentials and the way they are generated may be useful for some developers who want to understand how TozStore works and what they are trying to achieve. Beyond generating a full set of client credentials and passing those client credentials in a secure way to an client instance using a TozStore SDK, you will not need to directly interact with client credentials except for TozStore client IDs.

A full set of client credentials will include: a human-readable name, a unique TozStore client ID, a public and private key-pair used to encrypt and decrypt data, a public and private key-pair used to sign data and validate a signature, an api url, and a pair of api credentials used to authenticate calls made to the TozStore API.

An example of a json containing a full set of TozStore client credentials looks like this:

{ "version": 1, --> version 1 or 2 (1 is only for early TozStore users) "api_url": "https://dev.e3db.com", --> api url the client will use for requests "api_key_id": , --> enables authentication to make TozStore API calls "api_secret": , --> enables authentication to make TozStore API calls "client_id": client's unique TozStore client ID "client_email": , --> not currently used "public_key": , --> client's public data encryption key "private_key": , --> client's private data encryption key KEEP SECURE "public_sign_key": , --> client's public signing key "private_sign_key": --> client's private signing key KEEP SECURE }

The underlying workflow for generating a full set of client credentials includes three stages:

1) A client name and api url are provided as strings, and TozStore SDK methods are used to generate a public key and private key-pair and a public signing key and private signing key-pair.

2) A TozStore SDK client.register method sends the above, partial client credentials to TozStore, and TozStore sends back a unique a client ID, an API key, and an API secret.

3) If desired, the now full set of client credentials are encrypted and backed up in TozStore.

Once a full set of client credentials is generated and a client is registered in TozStore, a client instance can be instantiated using a TozStore SDK to give access to TozStore tools, including methods to write, read, and share data.

Front-End TozStore Clients & Public TozStore Forms

Data Record Structures

Next, you need to determine what structure would be best for your data records. Data records consist of plain-text metadata, plain-text keys, and encrypted values. Plain-text metadata allows querying encrypted data sets.

Records also have a type. By default, data is only accessible by the client that wrote the record. The share method grants other clients access to data of a given type. Shared access to a data type can also be revoked. A record's type provides a way to batch records for granting access between clients.

TozStore

Install and Import Tozny SDK

  // Run the following command in your terminal. 

  $ npm install --save e3db

  // `npm` will update your `package.json`.


  // Alternatively: 

  // Add `e3db` as a dependency in your package.json.

  "dependencies": {
    "e3db": "^1.2"
  }

  // Then run the install command in your terminal. 

  $ npm install

TozStore currently provides SDKs for the following languages: JavaScript (Node), Python, Ruby, Go, Java, Swift,and PHP. Our libraries are open source and available here:

PHP JavaScript / Node Python Ruby GoLang Swift Java

Register Client using Tozny Dashboard

You can create clients directly in the Tozny Dashboard. You can simply grab the client credentials from the console. Clients registered from within the console will automatically back their credentials up to your account. You can also create clients dynamically using a Tozny SDK and optionally back-up client credentials.

Register Client With Back-Up (SDK)

  const e3db = require('e3db')

  let token = '...'
  let clientName = '...'

  async function main() {
    let cryptoKeys  = await e3db.Client.generateKeypair();
    let signingKeys = await e3db.Client.generateSigningKeypair();
    let clientInfo  = await e3db.Client.register(token, clientName, cryptoKeys, signingKeys, true)

    // ... Run operations with the client's details here
  }
  main()

Use the Tozny Dashboard to create a client registration token. With this token, you can dynamically create clients with with any of our SDK's. (To generate clients without backing up credentials, see the next section.)

The private key must be passed to the registration handler when backing up credentials as it is used to cryptographically sign the encrypted backup file stored on the server. The private key never leaves the system, and the stored credentials will only be accessible to the newly-registered client itself or the account with which it is registered.

Register Client Without Back-Up (SDK)

  const e3db = require('e3db')

  let token = '...'
  let clientName = '...'

  async function main() {
    let cryptoKeys  = await e3db.Client.generateKeypair();
    let signingKeys = await e3db.Client.generateSigningKeypair();
    let clientInfo  = await e3db.Client.register(token, clientName, cryptoKeys, signingKeys, false)

    // ... Run operations with the client's details here
  }
  main()

Use the Tozny Dashboard to create a client registration token. With this token, you can dynamically create clients with with any of our SDK's. (To generate clients backing up credentials, see the previous section.)

The object returned from the server contains the client's UUID, API key, and API secret (as well as echos back the public key passed during registration). It's your responsibility to store this information locally as it will not be recoverable without credential backup.

Load Client Credentials (Configuration) and Create Client Instance

/* Configuration is managed at runtime by instantiating an e3db.Config object with your client's credentials. */

const e3db = require('e3db')

/**
 * Assuming your credentials are stored as defined constants in the
 * application, pass them each into the configuration constructor as
 * follows:
 */

let config = new e3db.Config(
  process.env.CLIENT_ID,
  process.env.API_KEY_ID,
  process.env.API_SECRET,
  process.env.PUBLIC_KEY,
  process.env.PRIVATE_KEY,
  process.env.API_URL
)

/**
 * Pass the configuration when building a new client instance.
 */
let client = new e3db.Client(config)

Configuration is managed at runtime by instantiating an e3db.Config object with your client's credentials.

Write (Encrypt) New Data Record


const e3db = require('e3db')

let client = new e3db.Client(/* config */)

async function main() {
  let data = {
    'first_name': 'Jon',
    'last_name': 'Snow',
    'phone': '555-555-1212',
  }
  let metadata = {
    'house' : 'Stark'
  }
  let record = await client.write('contact', data, metadata)

  console.log('Wrote record ' + record.meta.recordId)
}
main()

The above command returns a Record ID:


2c1b256e-8449-423a-955f-e2c508almnop

When a client creates data, its encrypted and signed locally and transmitted to E 3 DB for storage. Developers don’t have to manage the cryptography, only the form and structure of their data. Data can be queried using unencrypted metadata.

Parameters

Parameter Required Description
recordType true A string representing the type of record you are storing
data true An object of key value pairs representing data you want to store encrypted
metadata false An object of plain text meta about the data. Used to query

Read (Decrypt) Data Record

  let recordId = 'abc';
  let record = await client.read(recordId)

The above command returns JSON structured like this:

{
  "data" : [
    "name" => "record_name",
  ],
  "meta" : [ 
    "your_meta" => "value"
  ]
}

Clients can read records by fetching records with their ID.

Clients can read data written by themselves or other clients (with permission). When reading data, it’s transmitted encrypted to the client and decrypted with the client’s private key, and its signature is verified.

Parameters

Parameter Required Description
recordId true The record you want to retrieve from TozStore

Update Data Record

  let recordId = 'abc'
  let record = await client.write(recordId)

  record.data.name = 'Mr. Jon Snow'
  let newRecord = await.client.update(record)

The above command returns a record object:

  {
    "data" : [
      "name" => "record_name",
    ],
    "meta" : [ 
      "your_meta" => "value"
    ]
  }

The update function lets clients easily download, decrypt, verify, modify, encrypt, sign, and re-upload data in one step. Changes to data are versioned to prevent potential conflicts between multiple clients updating data simultaneously.

To update a record you must first download the record and update its properties as needed.
You then pass the updated Record object to the update function.

Parameter Required Description
record true The updated record object

Delete Data Record

  const e3db = require('e3db')

  let token = '...'
  let clientName = '...'
  let recordId = '...' //your record id to delete
  async function main() {
    await e3db.Client.delete(recordId)

    // ... Run operations with the client's details here
  }
  main()

This function simply deletes a record or set of records. Only a user with permission may delete data.

Parameter Required Description
record_id true The id of the record you want to delete

Query Data Records

  const e3db = require('e3db')

  let client = new e3db.Client(/* config */)

  let data = true
  let writer = null
  let record = null
  let type = 'contact'

  async function main() {
    let records = await client.query(data, writer, record, type).next()
    let fullName = record.data.first_name + ' ' + record.data.last_name
    console.log(fullName + ' --- ' + record.data.phone)
  }
  main()

Query E3DB records according to a set of selection criteria.

The default behavior is to return all records written by the current authenticated client.

To restrict the results to a particular type, pass a type or list of types as the type argument.

To restrict the results to a set of clients, pass a single or list of client IDs as the writer argument. To list records written by any client that has shared with the current client, pass the special string 'all' as the writer argument.

Parameter Required Type Description
data false Bool Flag to include data in records returned
writer false String or Array Records written by a single writer or list of writers
record false String or Array Select single record or list of records
type false String or Array Select records of a type or types
metadata false Array Associative array of plaintext meta to use as filter
pageSize false Number Page size returned by response

Share Data Records

  /**
 * ---------------------------------------------------------
 * Initialization
 * ---------------------------------------------------------
 */

  // Configuration values must be set in an immutable configuration object.
  // You can use whatever "profiles" or client credentials you want.
  let config = new e3db.Config(
    process.env.CLIENT_ID,
    process.env.API_KEY_ID,
    process.env.API_SECRET,
    process.env.PUBLIC_KEY,
    process.env.PRIVATE_KEY,
    process.env.API_URL,
    process.env.PUBLIC_SIGN_KEY,
    process.env.PRIVATE_SIGN_KEY
  )

  // Now create a client using that configuration
  let client = new e3db.Client(config)
  /**
  * ---------------------------------------------------------
  * Simple sharing by record type
  * ---------------------------------------------------------
  */

  // Share all of the records of type 'test-contact' with another client ID:
  let anotherClientId = 'db1sdfb9-3fb6-4458-a291-0bc673437dba08b'
  await client.share('test-contact', anotherClientId)

These functions change access control and add or remove an encryption key so that a new party can read or write data. It can be run by any client with permission to this data. It does not require downloading or re-encrypting the data, since TozStore utilizes a key wrapping approach for efficiency. As a result, a very large amount of data can be shared with multiple parties using a fast, constant-time operation.

Parameter Required Type Description
record_type true String The 'type' of records that should be shared with a client
client_id true String The recipient who will get access to the records

Unshare Data Records

  /**
 * ---------------------------------------------------------
 * Initialization
 * ---------------------------------------------------------
 */

  // Configuration values must be set in an immutable configuration object.
  // You can use whatever "profiles" or client credentials you want.
  let config = new e3db.Config(
    process.env.CLIENT_ID,
    process.env.API_KEY_ID,
    process.env.API_SECRET,
    process.env.PUBLIC_KEY,
    process.env.PRIVATE_KEY,
    process.env.API_URL,
    process.env.PUBLIC_SIGN_KEY,
    process.env.PRIVATE_SIGN_KEY
  )

  // Now create a client using that configuration
  let client = new e3db.Client(config)
  /**
  * ---------------------------------------------------------
  * Simple sharing by record type
  * ---------------------------------------------------------
  */

  // Revoke all of the records of type 'test-contact' with another client ID:
  let anotherClientId = 'db1sdfb9-3fb6-4458-a291-0bc673437dba08b'
  await client.revoke('test-contact', anotherClientId)

These functions change access control and add or remove an encryption key so that a new party can read or write data. It can be run by any client with permission to this data. It does not require downloading or re-encrypting the data, since TozStore utilizes a key wrapping approach for efficiency. As a result, a very large amount of data can be unshared with multiple parties using a fast, constant-time operation.

Parameter Required Type Description
record_type true String The 'type' of records that should be shared with a client
client_id true String The recipient who will get access to the records

Upload File

TozStore supports the storage of large encrypted files, using a similar interface for reading and writing records. The SDK will handle encrypting and uploading the file. Similarly, it will download and decrypt files as well. Note that file upload and download is currently in development and not supported in all of our SDK's. If you are actively looking for support in a specific library please contact us at support@tozny.com.

Download File

TozStore supports the storage of large encrypted files, using a similar interface for reading and writing records. The SDK will handle encrypting and uploading the file. Similarly, it will download and decrypt files as well. Note that file upload and download is currently in development and not supported in all of our SDK's. If you are actively looking for support in a specific library please contact us at support@tozny.com.

Authorize User (Beta)

Share on behalf of (Beta)

Errors

The Kittn API uses the following error codes:

Error Code Meaning
400 Bad Request -- Your request is invalid.
401 Unauthorized -- Your API key is wrong.
403 Forbidden -- The kitten requested is hidden for administrators only.
404 Not Found -- The specified kitten could not be found.
405 Method Not Allowed -- You tried to access a kitten with an invalid method.
406 Not Acceptable -- You requested a format that isn't json.
410 Gone -- The kitten requested has been removed from our servers.
418 I'm a teapot.
429 Too Many Requests -- You're requesting too many kittens! Slow down!
500 Internal Server Error -- We had a problem with our server. Try again later.
503 Service Unavailable -- We're temporarily offline for maintenance. Please try again later.