The counting-house keeps the books; the workshop does the listening.
Architecture · from the control plane desk
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.
Cryptography · standing notice
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.
Illustrated · a moving photograph
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
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.
Silence is not a refusal. A timeout means no opinion was
given, so the node decides for itself and settles up later.
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
Balance0secondsSUM(delta_seconds)
Directory of Addresses
Everything your servers will call, and what to present
Notices & Small Print
Limits to design around
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
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.
Sign grants. Your server authenticates your users however it already does, then signs a short token saying who may speak and for how long.
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.
Live sessions · protocol
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
Degradation · policy
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.