Examples

Worked examples

What goes over the wire, with real bytes: nothing here is written by hand, it is read from the test vectors and examples that the repository checks.

The keys, tokens and names are fictional test values (the key is RFC 8032's published test key), never real ones.

A signed request, byte by byte

A device paired with a key signs every request that carries its token. The server rebuilds the signature base from the request, and checks the signature with the key it bound to the token.

The request as sent

GET /api/lantern/v1/apps?page_size=50 HTTP/1.1
Host: shelf.example.org
Authorization: Bearer et_c8V1nQ0xYbExampleVectorToken0000000000
Signature-Input: lantern=("@method" "@target-uri" "authorization");created=1793345400;nonce="tQ0Vb3Yt7sXx2c1mZ8kq4A";keyid="If4x36FUomFia_hUBG_SJxt77UtqvkWqWId-9H-XIbk";alg="ed25519"
Signature: lantern=:M8AuwRfGqDSUYUefbsIOlmFKxvi+6HnHv0pvbD22n/lrJqHvPcvYThUUCqK+6C63s9nTQPThdrTfM9yFwt6aBA==:

The signature base the device signs

"@method": GET
"@target-uri": https://shelf.example.org/api/lantern/v1/apps?page_size=50
"authorization": Bearer et_c8V1nQ0xYbExampleVectorToken0000000000
"@signature-params": ("@method" "@target-uri" "authorization");created=1793345400;nonce="tQ0Vb3Yt7sXx2c1mZ8kq4A";keyid="If4x36FUomFia_hUBG_SJxt77UtqvkWqWId-9H-XIbk";alg="ed25519"

The device's key

private key (seed): 9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60
public key:         11qYAYKxCrfVS/7TyWQHOg7hcvPapiMlrwIaaPcHURo=
keyid:              If4x36FUomFia_hUBG_SJxt77UtqvkWqWId-9H-XIbk
short fingerprint:  21FE 31DF A154 A261

The same request without its signature

Authorization: Bearer et_c8V1nQ0xYbExampleVectorToken0000000000

→ 401 · signature_required

§ 5.4 · vectors/signatures.json

A pairing, from its code to its token

The device asks for a code and shows it; its owner approves on another device, signed in to the server; the device polls until the token is given, once.

  1. 1. The device asks to pair

    POST /api/lantern/v1/pairing HTTP/1.1
    Host: shelf.example.org
    Content-Type: application/json
    
    {
      "schema": 1,
      "device": "Lea's Switch",
      "scopes": [
        "library",
        "saves"
      ],
      "key": {
        "alg": "ed25519",
        "public_key": "11qYAYKxCrfVS/7TyWQHOg7hcvPapiMlrwIaaPcHURo="
      }
    }
  2. 2. The server answers with a code

    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "schema": 1,
      "code": "KQ4M-7TXD",
      "verify": "https://shelf.example.org/pair",
      "verify_complete": "https://shelf.example.org/pair?code=KQ4M-7TXD",
      "poll": "/api/lantern/v1/pairing/p_4Fh2",
      "interval": 5,
      "expires": 600
    }
  3. 3. The owner approves; the device polls

    GET /api/lantern/v1/pairing/p_4Fh2 HTTP/1.1
    Host: shelf.example.org
    Signature-Input: lantern=("@method" "@target-uri");created=…;nonce="…";keyid="…";alg="ed25519"
    Signature: lantern=:…:
  4. 4. The token, once

    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "schema": 1,
      "token": "et_c8V1nQ0xYb",
      "scopes": [
        "library",
        "saves"
      ],
      "bound": true,
      "rating_cap": {
        "system": "PEGI",
        "rating": "12"
      }
    }

§ 5.2 · examples/v1/

A grant, for a peer

The server signs a short statement that a client may read one file; a peer that holds the file checks it with the server's public key, without asking anyone.

What the server signs (JSON, keys in this order, no space)

{"exp":1793346000,"purpose":"lantern-grant-1","sha256":"3a7bd3e2b4c1f0a9e8d7c6b5a4938271605f4e3d2c1b0a9f8e7d6c5b4a392817","size":734003200,"uid":"6f1c2a8e-4b7d-4e2a-9c31-8d5e2f0a7b14"}

The grant: the payload and its signature, each in base64url

eyJleHAiOjE3OTMzNDYwMDAsInB1cnBvc2UiOiJsYW50ZXJuLWdyYW50LTEiLCJzaGEyNTYiOiIzYTdiZDNlMmI0YzFmMGE5ZThkN2M2YjVhNDkzODI3MTYwNWY0ZTNkMmMxYjBhOWY4ZTdkNmM1YjRhMzkyODE3Iiwic2l6ZSI6NzM0MDAzMjAwLCJ1aWQiOiI2ZjFjMmE4ZS00YjdkLTRlMmEtOWMzMS04ZDVlMmYwYTdiMTQifQ.-4SQt-G8QN_sjMzKfaBGDl7b7Z-tW2qHaeC8bSwe70tHH4lVsyhxnMVMrb3r4y3RVBzbhOTeWdP4d6jFjex5Bg
public key (peers.key): FkDVKwFG57y5KAWiHAahZeQ1pO2FxI5AehF/nZjLXq8=

§ 19.3 · vectors/grants.json