ContentsThe library

Proving Who You Are

Who You Are, What You May Do, and Who Remembers

Three separate problems get solved by one library and called login. Separating them is the whole of this lesson, because every later decision depends on which one you are answering.

Three questions

A request arrives asking to delete a document. Three separate things have to

be established before it can be carried out, and they are usually described

with one word.

Who is making this request? That is identification. It binds the request to

an account, and when it fails the honest answer is that you do not know who

this is.

May that account delete that document? That is permission. It depends on the

account, on the specific document, and on the specific operation, and it is

a different answer for each combination.

How did we know the answer to the first question without asking the person

again? That is the session. Identity was proved once, minutes or weeks ago,

and something has been carrying that fact ever since.

FIG 1One delete request, by stage
stepstagethe questionwhat it useswhen it failswhat happened
1sessionhas identity been proved recentlya value the browser sentno identity, ask them to sign inThis stage knows nothing about documents. It produces an account identifier or nothing at all.
2identitywhich account is thisthe record the session points atthe account was deleted or disabledWorth separating from the stage above, because a valid session can point at an account that no longer exists.
3permissionmay this account delete this documentthe account, the document, the operationknown, but not allowedThis is the only stage that looks at what is being asked. It is also the only one that needs to load the document.
4the workdelete itthe documentit was already deletedThe actual operation, which assumes the first three succeeded and should never check them again.
4 steps
Four stages and three questions before any work happens. The two failures in the middle produce different answers to the caller: not signed in is a request to do something, while not allowed is a refusal, and conflating them tells a user to sign in again when signing in would change nothing.

Identifying somebody

Identification binds this request to an account. That is the whole job, and

it is worth being strict about how little it establishes.

It does not say the account is in good standing. It does not say the person

is who the account says they are, only that whoever is here presented

something the account controls. It does not say they may do anything at all;

an account with no permissions is perfectly well identified.

The usual way to be strict about this is to write it as a function that

returns an account identifier or nothing, and takes no argument describing

what is being attempted. If the function needs to know what is being asked,

two questions have been merged.

FIG 2Which question each mechanism answers
answers who you areanswers what you may doremembers the answerworth stealing
a password check1001
a one-time code by email1001
a session cookie0011
a role on an account0100
a rule about a document 0100
a signed token carrying 1011
an entry in a session st0010
Two marks on one row. A signed token carrying claims is the only mechanism here that answers both of the first two questions, which is exactly why it is convenient and exactly why it causes the revocation problem taken up in the fourth lesson. Notice also that everything in the third column is in the last column.

Deciding what they may do

Permission takes three inputs: the account, the thing, and the operation.

All three are necessary, and designs that drop one are the usual source of

trouble.

Dropping the thing gives you a role check and nothing more: this account is

an editor, so it may edit. That works until two editors must not edit each

other's documents, at which point every rule has to be rewritten.

Dropping the operation gives you access as a single bit: this account can

touch this document. That collapses reading and deleting into one answer,

which is almost never what anybody wants.

The second useful discipline is to check permission as late as possible,

against current data. A permission established at sign-in and carried

forward is a statement about the past. Somebody removed from a project at

ten o'clock should not be able to act on it at ten past, and whether that

holds depends entirely on whether the check reads the current membership or

a copy made at sign-in.

FIG 3Where each question is answered in one request
The two refusals sit at opposite ends and look similar in logs, which is why they are so often merged. Any design where the same code path produces both is a design that will eventually tell somebody to sign in again for a thing they are simply not allowed to do.

Remembering the answer

Proving identity properly is slow. It involves a person, a password manager,

sometimes a phone, sometimes a second device. Doing it once per request is

not a performance problem, it is an impossibility.

FIG 4Why it has to be remembered
identity checks per day if nothing is remembered
active users in a day
requests each user makes
Twenty thousand users making four hundred requests each is eight million sign-in prompts a day. The session exists because that number has to become twenty thousand. Everything difficult about the rest of this course follows from the fact that the answer is now cached somewhere you do not control.

So the answer is remembered: something is issued at sign-in, the browser

carries it, and every subsequent request presents it instead of a password.

That something is now equivalent to the password for as long as it lives,

which makes it the most valuable thing in the system and the subject of the

next several lessons.

Two consequences are worth stating now. The thing being carried has to be

unguessable, because anybody holding it is you. And it has to have a

lifetime, because an answer to the question of who you are gets staler every

hour, and at some point the honest thing to do is ask again.

Where the three get merged

Most confused designs are one question being answered with another one's

tool, and three merges account for nearly all of them.

FIG 5Authentication incidents by which questions were merged
The largest category is a session being treated as a yes. The second is a permission snapshot going stale, which is the same error displaced in time. Together they are over two thirds, and both are prevented by the same discipline of checking the thing being acted on, at the moment of acting.

The first merge treats a valid session as permission to act. Code reaches a

handler, observes that somebody is signed in, and proceeds. It is usually

correct, because most signed-in people are acting on their own data, and it

fails precisely when somebody passes an identifier belonging to somebody

else.

The second bakes permissions into a token at sign-in. It is appealing

because it removes a lookup. It means a permission change takes effect

whenever the token happens to expire, which is a sentence nobody wants to

say in an incident review.

The third gives the same answer to both refusals, so a user who is not

allowed to see a page is asked to sign in, signs in successfully, and is

asked again. They conclude that sign-in is broken, which is a reasonable

conclusion from what they can see.

The fourth trusts an external identity provider for a decision only you can

make. A provider can tell you which account this is. It cannot tell you

whether that account may delete this document, because it has never heard of

the document. The fifth lesson returns to this once the exchange itself is

clear.

The next lesson goes back to the beginning of the chain and asks how

identity gets proved in the first place, and what each method actually

resists.

Recap

  • Identifying somebody, deciding what they may do, and remembering the answer are three problems with three different failure modes.
  • A session proves the first question was answered once; it never answers the second, and treating it as though it does is the most common design error here.
  • Point at the exact line in your own request path where each question is answered, and you will usually find one of them is not answered anywhere.

This is the reading half

Starting the course gives you your own copy of it. Every idea on every page has problems standing under it, marked with a reason rather than a tick, and any sentence you do not believe can be opened and argued with. None of that can happen on a page nobody owns.

The contents

NextThe First Proof →

The rest of this course

  1. 01Who You Are, What You May Do, and Who Remembersyou are here
  2. 02What Each Kind of Proof Actually Resistsopening only
  3. 03The Thing the Browser Carriesopening only
  4. 04The Token That Answers for Itselfopening only
  5. 05Two Tokens Beat Oneopening only
  6. 06Borrowing Somebody Elses Proofopening only
  7. 07The Request Your Browser Sent for Somebody Elseopening only
  8. 08Making Somebody Stop Being Signed Inopening only

Read alongside