Saphan StudioDocs
Identity

What a token carries, and how long it lives

What a program is given, the four lifetimes, the approval a person presses, and how a person takes it back.

A token is issued to a program, on behalf of a person who signed in, for one named service. All three parts of that sentence are load-bearing: without a person there is no token, without a named service there is no token, and the program is the holder rather than the subject.

What it carries

It carriesIt does not carry
who signed inany grant of authority over this product's data
which server vouched for thatany permission belonging to another service
the one service it may be spent ata name for the program that the program chose for itself
what kind of access was asked foranything that outlives the lifetimes below

No administrator of the authorization server can put authority into a token. That server authenticates; it does not decide what anyone may do. Permissions live with the thing that owns them, and the reach of a token is resolved from the person it belongs to rather than from anything the program asked for.

A token works at one service and nowhere else. A program that needs to talk to two services needs two grants, and sends the person through sign-in twice, once for each. There is no shortcut and the release does not intend to offer one. What it costs is one extra trip through a sign-in page for the human, at first connection. What it buys is that compromising the credential for the weaker service yields nothing at all at the stronger one, and withdrawing one does not touch the other.

The four lifetimes

WhatHow long
the code a program exchanges for a tokenone minute, and it is spent on first use
the token it then acts withten minutes
a standing credential that has gone unuseda fortnight
the whole delegation from one sign-ina month

These are not settings in this release. Changing one is a change to the product, made in one place, and every refusal and every check follows it.

The consequence that decides everything else on this page: a token a program is already holding cannot be withdrawn. The service it is presented to checks the token itself and never asks the authorization server anything, so there is nothing to ask and nothing to recall. Every act of revocation in this section stops the next token; none of them reaches the last one.

Ten minutes is therefore the exposure window of a stolen token, and that is why the number is what it is. It keeps the window small while costing a busy program one quiet refresh per ten minutes of work. If ten minutes is ten minutes too many for you, that number is the thing to change, and it is the only thing that changes it.

The other two are the reasoning worth knowing:

  • A fortnight unused is not "how long may a program stay connected" — each use replaces the credential and resets the clock. It is "how long may it go quiet", and a fortnight covers a holiday and a machine left switched off. It does not cover a laptop that was decommissioned, which is the case it exists to stop.
  • A month absolute, so that every standing delegation is re-authorized by a person within the month. Without a ceiling, a program that refreshes fortnightly holds a credential derived from one sign-in forever, and "when did a human last agree to this?" has no answer at all.

A standing credential, and the one thing to get right

A program keeps working while nobody is at the keyboard only if that was asked for by name. It is never granted by default, however the program was registered.

Each use of a standing credential replaces it. The old value is dead the moment the new one is handed over.

Keep exactly one, and replace it the moment a refresh succeeds. If a value that has already been replaced comes back, the whole delegation is withdrawn — including the live credential — and the person has to authorize the program again. That is deliberate: a replaced value coming back means two parties hold copies, and the server cannot tell which one is you. Taking the delegation from both makes the outcome the same either way, so the person can come back and a thief cannot.

Two ways integrations trip over this, and both are ordinary bugs rather than exotic ones:

  • two copies of the same program sharing one stored value. Both refresh, one wins, the other replays. Store it per instance, or serialise the refresh.
  • a retry after a timeout. If a refresh times out, the replacement may already have happened. Re-read what you have stored before retrying, rather than re-sending the value you had in hand.

A withdrawal for reuse reaches one delegation — one person, one program, one service. It is not an organization-wide sign-out, and a program holding a second delegation for a second service keeps that one.

Narrowing a request until it no longer asks to keep working ends the delegation. You may narrow what a token reaches on a refresh and you may never widen it, not even back to something the original authorization did include. Narrowing away the ability to act while nobody is watching is read as "I no longer want a standing credential", and that is what you get: one last token and nothing to refresh with.

The approval a person presses

If nobody who runs the authorization server vouched for a program, then the first time a given person authorizes it they are shown a page, and nothing is issued until they press the button. If a human registered the program by hand at a shell on that machine, there is no page: a human already vouched for it.

The three facts to read on that page are the first three: the program's identifier, the address the authorization will be delivered to, and the service the program may act at. If any of them is not what you started, close the page. Pressing nothing is the refusal, which is why there is no cancel button to press.

The page does not show the name the program chose for itself, deliberately. That name is a string the program wrote about itself, and rendering it above a stranger's delivery address would be the server vouching for something it never checked. Only the identifier and the address are facts the server established.

The approval covers that program, that one delivery address and that one service — and nothing else. If the program later asks for a different address or a different service, the page comes back and the person decides again. So does a wider request. A mismatch always re-asks and never refuses: there is no error for "this differs from what was approved", because the party with something to decide is the person, not the program's error handler.

What this costs a program is one page, once. A program that talks to one service through one address meets it a single time. A program that talks to two services meets it twice, which is the same decision the two-grant rule above already forces.

Why it exists, in one sentence: signing in and agreeing to a program are two different facts, and until this page existed the first was being read as the second — which is enough for a program a stranger registered to be handed a standing delegation on the seat of any person who clicked one link.

How a person takes it back

This is an act performed by a human hand, on the person's own account page, and it needs no token in their hand at all.

  1. Sign in, and follow the list of applications you have approved.
  2. Each one carries whether it can act for you while you are asleep, and one block per decision you made — two blocks means you approved it twice, for two addresses or two services.
  3. Press withdraw. The page comes back and tells you what ended, in counts.
What withdrawal endsWhat it does not
the approval itself — the next authorization shows the page againa token the program already holds, for up to ten minutes
every standing credential, including one being replaced at that instantyour own signed-in session
an unexchanged authorization the program is holdingthe program's registration, if a human registered it

Withdrawing does not sign you out, and that is a door. Anyone who has your live session can walk the same program through authorization again, press approve, and hold a brand-new standing credential a minute later. If you are withdrawing because you think somebody else got in, change your password first and withdraw second.

Withdrawing is not a block and not a ban. There is no list of refused programs, because a person who cannot undo their own mistake stops using the control at all. Start the program again and approve it once more.

In this release an operator cannot withdraw on somebody else's behalf. The control acts on the account holding the session and only that one, so the case it most exists for — a person who was phished and may be asleep — is the case it cannot serve. There is a hand-written last resort against the database, and it is exactly that: a last resort. Wake the person and have them press the button if you possibly can.

A program can also hand a grant back itself, and that endpoint always answers as though it succeeded whether or not the value named anything — not out of politeness, but because an endpoint that answered differently for a real value would be a free way to test stolen ones. ⚠ It is the program's instrument, presented with the credential, which makes it exactly the wrong instrument for a person who was phished into approving something: that person does not hold the credential, the program does.

On this page