Vol. I No. 1 Control Plane Edition Published this morning

The Daily Transcript

In which spoken words are captured, tallied by the second, and charged to the proper account — with every token inspected at the door.

Ed25519 signatures only Single-use tokens Append-only ledger SQLite · WAL

Two Houses, One Service

The counting-house keeps the books; the workshop does the listening.

Every voice that reaches this service arrives carrying a letter of introduction. The service itself is split in two, and the split is the whole design: the control plane knows who the customers are, what they have paid for and how much they have left, while the data plane knows only how to turn audio into text as fast as the hardware allows.

The counting-house holds customers, signing keys, plans, credit and usage history. Its traffic is low and transactional; it wants durability more than speed. The workshop holds none of that. It is latency-sensitive, it scales sideways, and when it needs to know whether a speaker may proceed, it asks.

The arrangement means a customer's own users never hold an account here. Their provider vouches for them — and the vouching is cryptographic, not a matter of trust.

Continued in “The Gauntlet”, right →

The Sealed Letter

Why we can read a customer's seal but never forge one.

Each customer holds an ed25519 private key. We hold only the public half. When one of their users wishes to dictate, the customer's own server signs a short-lived token stating who the user is and how many seconds they may spend.

Because the limits are inside the signature, they cannot be edited on the way through. A user who opens the console and changes max_audio_seconds from sixty to sixty thousand produces a token that no longer verifies.

The asymmetry is the point. A shared password would let us mint tokens in a customer's name; a public key lets us only ever check them.


        
A grant token's claims, as signed by the customer

Passage of a Single Word

Four parties, and only one of them holds a private key.

The user logs in with their own provider. That provider signs a grant. The user carries it to a transcription node, which checks it against the counting-house. Audio flows; seconds are tallied and charged as they are spoken, not merely at the end.

Should the counting-house fall silent, the workshop verifies signatures itself against keys it cached earlier, and keeps listening — recording what is owed for when the post resumes.

Take Note

  1. A refusal is honoured. If the counting-house says a customer is out of credit, the node refuses. It never guesses in the customer's favour.
  2. Silence is not a refusal. A timeout means no opinion was given, so the node decides for itself and settles up later.
The speaker no account with us Their provider holds the private key Transcription node audio in, text out Counting-house keys, plans, credit signed grant carried by the user verify limits + balance
The passage of one grant token — the seal never leaves the provider

The Gauntlet

Spoil the token and see which door refuses it

Every token runs the same seven checks in the same order, and stops at the first failure. The messages below are the ones the service actually returns. Introduce a flaw, then present the token.

    Read the Seal

    Paste any grant token — nothing leaves this page

    Decoding is not verification. A token's claims are plain text to whoever holds it, so reading them proves nothing — only checking the signature does. The key that check needs is the public one, which is why we publish it openly at /v1/customers/{slug}/jwks.json: it can confirm a seal, never counterfeit one. Only the private half must never leave the customer.

    Header

    
                

    Claims

    
                

    The Counting-House Ledger

    Nothing is ever edited — the balance is the sum

    Credit is not a number we overwrite. It is a column of entries, and the balance is whatever they add up to. When a customer disputes an invoice, every second can be accounted for by the rows that produced it.

    Credit ledger entries
    Entered Reason Reference Seconds
    Balance 0 seconds SUM(delta_seconds)

    Directory of Addresses

    Everything your servers will call, and what to present

    Notices & Small Print

    Token lifetime · 3600s ceiling
    Mint whatever lifetime you like; we decline to honour anything longer than an hour. Minutes are the sensible choice.
    Single use
    A token is spent on first use. Mint one per connection — a reconnect needs a fresh one, and so does each top-up.
    Extending a live session
    Send a fresh grant over the open connection and its seconds are added to the session. Same customer, same user, no reconnect.
    Clock skew · 60s
    Allowed either side of exp and nbf, so your signing server need not be perfectly in step with ours.
    Algorithm · EdDSA only
    ed25519 signatures. An alg of none, or an HMAC substitution, is refused before anything else is read.
    jti · required
    Without one a token cannot be single-use, and will be refused.
    Effective limit
    The least of what you granted, what your plan allows, and the credit remaining on your account.
    Key rotation
    Several signing keys may be active at once, so you can roll a new one out before retiring the old. We refuse to retire your last one.

    How to Begin

    1. Take an account. You receive a dashboard login, an API key and an ed25519 keypair — or register a public key you generated yourself, and we never hold the private half at all.
    2. Sign grants. Your server authenticates your users however it already does, then signs a short token saying who may speak and for how long.
    3. Send them to us. Your users connect with that token. We check the seal, apply the limits and tally the seconds.

    The worked example is about ninety lines of Node, with no dependencies.

    Topping Up Mid-Sentence

    A speaker who runs out of seconds need not be cut off.

    A grant carries a budget of seconds. When it runs out the session ends — which, for someone dictating a letter, arrives at the worst possible moment. So a live session can be extended without reconnecting.

    Send a fresh grant over the open connection. The seconds are added to what the session already had, so you can hand out a minute at a time without tracking how much has been used.

    
            
    Extending a session that is already running

    The grant must name the same customer and the same end user. One of your users cannot extend another's session, and no one else's grant can move a session onto your account.

    Nothing is dropped: no reconnection, no gap in the audio, no missing words in the transcript.

    When the Post Fails

    A refusal from the counting-house is a decision and is always obeyed. A timeout is not: it means no decision was reached. The node then verifies the signature itself against cached public keys and keeps transcribing.

    Two things still hold offline: signatures are checked, and a token can still only be spent once on that node. What cannot hold is credit — the ledger is elsewhere. Seconds accrued are queued and settle when the post resumes.

    The trade is deliberate and it favours you: your users keep dictating through an interruption on our side, and the account is squared up afterwards rather than sessions being dropped.