Branca Token

Authenticated and encrypted API tokens using modern crypto.

Branca is a secure easy to use token format which makes it hard to shoot yourself in the foot. It uses IETF XChaCha20-Poly1305 AEAD symmetric encryption to create encrypted, tamperproof and URL safe tokens.

Secure by design

There is no algorithm agility. The only supported cipher suite is IETF XChaCha20-Poly1305 AEAD. By removing the choice it is hard to shoot yourself in the foot.

Easy to implement

For developers a fast implementation of the chosen cipher suite is offered by the Sodium crypto library. Sodium is a modern, easy-to-use software crypto library.

Tamperproof

By using authenticated encryption integrity of the token can be guaranteed. This means a possible attacker cannot alter the contents of a token.

You choose the payload

Payload is an arbitrary sequence of bytes. You could use a JSON object, plain text string or even binary data serialized by MessagePack or Protocol Buffers.
Known implementations
Clojure
.NET
Elixir
Erlang
Go
Java
JavaScript
Kotlin
PHP
Python
Ruby
Rust
Getting started

JavaScript

Install the library either with yarn or npm. You must provide the library with 32 byte secret key. As the name suggest this key should be kept secret. Never commit the key to GitHub or otherwise leak it. The code below uses a JSON string as an example payload.


$ yarn add branca
$ npm install branca
          

const key = crypto.randomBytes(32);
const branca = require("branca")(key);

const json = JSON.stringify({
    "user" : "someone@example.com",
    "scope" : ["read", "write", "delete"]
});

const token = branca.encode(json);
const payload = branca.decode(token);

console.log(token);
console.log(JSON.parse(payload));
          

PHP

Install the library with composer. Pass the 32 byte secret key to the constructor. As the name suggest this key should be kept secret. Never commit the key to GitHub or otherwise leak it. The code below uses a JSON string as an example payload.


$ composer require tuupola/branca
          

use Branca\Branca;

$key = random_bytes(32);
$branca = new Branca($key);

$json = json_encode([
    "user" => "someone@example.com",
    "scope" => ["read", "write", "delete"]
]);

$token = $branca->encode($json);
$payload = $branca->decode($token);

print_r($token);
print_r(json_decode($payload, true));
          

Python

Install the library pip. Note that you also must have libsodium installed. Pass the 32 byte secret key to the constructor. As the name suggest this key should be kept secret. Never commit the key to GitHub or otherwise leak it. The code below uses a JSON string as an example payload.


$ brew install libsodium
$ pip install pybranca
          

import json
import secrets
from branca import Branca

key = secrets.token_bytes(32)
branca = Branca(key)

string = json.dumps({
    "user" : "someone@example.com",
    "scope" : ["read", "write", "delete"]
})

token = branca.encode(string)
payload = branca.decode(token)

print(token)
print(payload)
          

Elixir

Add the dependencies to mix.exs and install dependencies. The secret key goes to config/config.exs. As the name suggest this key should be kept secret. Never commit the key to GitHub or otherwise leak it. The code below uses a JSON string as an example payload.


# mix.exs
...
defp deps do
  [
    {:poison, "~> 3.1"},
    {:branca, "~> 0.2.0"}
  ]
end
          

$ mix deps.get
          

# config.exs
...
config :branca, key: "supersecretkeyyoushouldnotcommit"
          

json = Poison.encode!(%{
  "user" => "someone@example.com",
  "scope" => ["read", "write", "delete"]
})

token = Branca.encode!(json)
payload = Branca.decode!(token)

inspect(token)
inspect(Poison.decode!(json))