learn-data-access-control-with-phoebe / Leader session 3 of 6
Learn Data Access Control with Phoebe · Leader session 3 of 6

Least privilege people can actually work with

Least privilege is the easiest principle in this field to state and the hardest to keep. The reason is not technical. Every control spends somebody's working time, that time comes out of a budget whether or not anybody is measuring it, and once the spend exceeds what a shortcut is worth, the shortcut is taken. Tonight is that budget, the request queue that tells you where the design is wrong, and the two mechanisms that let you grant real access without adding to the number that never goes down.

🟡 Core Data and analytics leaders Whoever approves access requests 45 min
0-3 · Welcome 3-22 · The friction budget 22-40 · Build-along: fix your request path 40-45 · Q&A
Part 0

Where tonight sits

Session 1 gave you three counters. Session 2 named the biggest single move, which is a role list that matches the jobs people do. Tonight is the part that decides whether any of it survives the following month: what the controls cost the people living under them, and how to grant genuine, temporary access without it turning into another permanent line on the list. Session 4 is classification and masking. Session 5 is evidence an auditor accepts. Session 6 is the operating model. The example stays saltbox.customers at Saltbox, a consumer lending startup: ten columns, three regions, five jobs.

Live = presented in the 45 minutes Self-study = the full depth, after class 🔍 Every diagram zooms

★ What you walk out with tonight. A way of reading your own access request queue as a design document rather than an inbox, so that a repeated request stops looking like a nuisance and starts looking like a specification. An expiry policy you would actually enforce, written in your own words rather than borrowed. And two names on a piece of paper for the top role, along with the list of people who should come off it.

LiveWhy "least" is the wrong half of the phrase to argue about3 min▶

Least privilege gets debated as though the difficulty were deciding how little to grant. It is not. Almost everybody agrees, in the abstract, on roughly the right answer: people should hold what the job needs. The difficulty is privilege, specifically the part where the person needs something the design did not anticipate, at 4pm, with a customer waiting.

  • A control that is right and slow will be circumvented by people who are neither careless nor malicious, and who will describe what they did openly if you ask.
  • A control that is loose and fast will be praised for a year and then found by an auditor, at which point the correction is usually an over-tightening that starts the cycle again.
  • The stable version is neither. It is a design that anticipates most needs, plus a fast, logged, expiring path for the rest.

That last line is the whole session. Everything else is how to build the fast path so that it closes behind itself.

Self-studyThe five terms this session turns on4 min▶
  • Friction budget - the working time a set of controls costs the people subject to them, per week. It is spent whether or not anybody has ever counted it, and it is finite.
  • Shadow path - what somebody does instead when the sanctioned route costs more than the shortcut is worth. Not a policy violation in anybody's mind at the time.
  • Break-glass - a deliberately powerful grant, available immediately, for a situation nobody could predict. It is a legitimate mechanism and its whole value is in the closing.
  • Just-in-time elevation - access granted for a stated reason and a stated window, then removed automatically. The generalisation of break-glass to ordinary work.
  • Standing privilege - a column a role can read in clear that the design does not mark clear for that role. It does not matter whether anybody has read it; capability is the exposure.
Part 1 · covers the friction budget and the request queue

Least privilege has a running cost and somebody is paying it

9 min live

Security spend is usually discussed as a line in a budget: tools, headcount, an audit. The larger spend never appears there. It is the aggregate working time of everybody who waits for an approval, re-requests a thing they had last quarter, or asks a colleague to look something up. That number is real, it is being paid today, and the only question is whether anybody has looked at it.

Every control spends somebody's working time the budget is real whether or not you measure it Left pan: what the control costs the person. Right pan: what they save by going around. Left heavier means the shortcut gets taken, and nobody announces that it happened. Control friction two approvers, 3 days Value of shortcut close the ticket now The routes that open when it does each one has less logging than the control shadow route logging Shared login one account, whole team logging one shared name Export to a spreadsheet refreshed by hand weekly logging none at all Screenshot in a ticket pasted into the thread logging ticket retention A repeated request for the same thing is a design fault, not carelessness. Every shadow route is worse than the control it replaced.
🔍 Click to zoom - when friction outweighs the shortcut, the shortcut wins.
LiveThe friction budget, and who is paying it3 min▶

Take one control and price it honestly. An access request that needs two approvers and takes three days does not cost three days of anybody's salary, but it does cost the requester a context switch, a chase, and usually a day of doing something less useful while they wait. Multiply by the number of requests a quarter and you have a real figure.

The budget is finite in a way that matters. People will absorb a certain amount of this and keep using the sanctioned path, because the path is the path. Past some point they stop, and the point is not where you think it is: it moves with how urgent the work feels, not with how sensitive the data is.

Price the control before you deploy it. One question, asked out loud in the meeting where the control is agreed: how many times a month will this fire, and how long will each one take the person on the other end. If nobody can answer, the budget is being spent blind, which is how a two-approver rule ends up guarding a plan name.

LiveThe request queue is a design document3 min▶

An access request queue is usually treated as an operational annoyance to be cleared faster. Read the other way round it is the most honest specification you will ever get: it is people telling you, at their own expense, what the design failed to anticipate.

  • The same request three times is not three requests. It is one missing line in the access design, being paid for repeatedly by three different people. Approving it a fourth time is choosing not to fix it.
  • Requests cluster by job, not by person. When every new support agent asks for the same two columns in their first week, that pairing belongs in the support role and the queue should never see it again.
  • Volume is a design metric, not a service metric. A team proud of clearing requests in four hours has optimised the symptom. The number worth watching is how many requests arrive at all, and whether it is falling.
  • The requests that never arrive are the expensive ones. People stop asking after two refusals. Silence from a team is not the absence of a need, it is the presence of a workaround.

A useful habit is to review the queue quarterly as a group, not to audit the decisions but to look for repeats. Every repeat is either a role that should exist or an attribute that should be driving a policy, and both are cheaper than the tenth approval.

LiveThe shadow-path rule3 min▶

Stated plainly: any control whose friction exceeds the value of a shortcut gets routed around, and the routes are always worse. Worse is not a moral judgement. It is a factual comparison on three dimensions that anybody can check.

RouteWho can see itWhat the log says
A shared login the team all knowsEverybody on the team, plus whoever they tellOne name, doing everything, forever
A spreadsheet exported weeklyAnybody with the folder or the linkNothing at all after the export
A screenshot pasted into a ticketEverybody on that ticket and its audienceTicket retention, which outlives the customer
Real world

Saltbox's support team lost the phone column after an audit. Within a fortnight the pattern was a screenshot: an analyst with broader access would pull the record and paste an image into the ticket thread. The warehouse recorded a clean quarter. The ticket system now held customer contact details in image form, unmasked, unsearchable by any scanner, retained for seven years under a policy written for something else entirely.

The screenshot is the worst of the three and it is also the one nobody thinks of as a data movement. It defeats every column policy, every classification scan and every deletion request, and it takes four seconds.

Self-studyMeasuring the budget without a project4 min▶

You do not need instrumentation to get a defensible number. Three measurements, each of which takes under an hour.

  • Time one request end to end, yourself. Not from approval to grant, which is the number the platform team reports. From the moment somebody realises they are blocked to the moment they are working. The gap between those two figures is usually a factor of five and it is where the whole argument lives.
  • Count repeats in one quarter. Group the queue by what was actually asked for rather than who asked. Any group with three or more entries is a line missing from the design.
  • Ask three people what they do instead. Phrase it without judgement and you will get an honest answer, because nobody involved thinks they are doing anything wrong. They are right, mostly. The control made the shortcut rational.

Write the three figures next to the three counters from session 1. A monthly report that shows leaks falling while request time triples is describing an estate that is about to develop shadow paths, and it is worth being the person who says so before it does.

Part 2 · covers break-glass, elevation and the top role

Time-bound access and break-glass that actually closes

9 min live

The fast path has to exist, because the alternative is the shadow path. What makes it safe is not restraint at the moment of granting, which nobody has at 2am, but the fact that the grant is already scheduled to disappear before anybody makes it. Design the closing first and the opening becomes easy.

Grant with an expiry closes itself, on a date chosen up front Day 0 requested, with the reason recorded Day 0 granted, expires in 14 days Day 14 reverts on its own, no ticket Day 15 re-requested if the work continues Standing privileges added: 0 and the reason is still on the record Grant made during an incident closes when somebody remembers, which is never 02:40 granted to stop the bleeding Day 1 incident closed, the grant stays Month 4 the requester changes team Month 18 nobody can say what it is for Standing privileges added: 1 and removing it might break something The grant that reverts by itself is the only kind that reverts.
🔍 Click to zoom - the same grant, with and without a date on it.
LiveBreak-glass with an expiry3 min▶

Break-glass is a good mechanism. Something will go wrong that nobody anticipated, somebody will need power they do not normally hold, and a design with no answer for that moment will be overridden in a way nobody records. The failure is never the opening. It is that the glass is never replaced.

The grant that reverts automatically is the only kind that reverts. A grant that depends on somebody remembering to revoke it, during the week after an incident, while writing the postmortem and catching up on everything they missed, is a permanent grant with an optimistic label. This is not a discipline problem and it will not be fixed by reminding people harder.

  • Put the expiry in the grant, not in a calendar. The mechanism has to be the same mechanism, or the two will diverge and the calendar will lose.
  • Make the window short and the renewal cheap. Fourteen days with a one-click renewal is enforceable. Ninety days is a way of pretending there is an expiry.
  • Expect renewals and do not treat them as failures. A grant renewed three times is telling you it belongs in the design. That is the queue signal again, arriving through a different door.
  • Alert on the use, not the grant. A break-glass role that is held quietly is one thing. A break-glass role that is used at 3pm on a Tuesday is worth a message the same afternoon.
LiveJust-in-time elevation, with the reason recorded at request time3 min▶

Elevation generalises break-glass to ordinary work: the person holds their normal access, and steps up for a stated purpose and a stated window. The mechanics are the easy half. The half that decides whether this is useful in a year is capturing the reason at the moment of the request.

A reason written at request time costs the requester fifteen seconds and is specific, because they are in the middle of the thing. The same reason reconstructed a month later is unrecoverable. Nobody is being evasive; they genuinely cannot remember which of four investigations that Tuesday belonged to, and what gets written into the review is a plausible guess.

✗ A reason that tells a reviewer nothing Reason: needed for analysis Duration: until further notice Approved by: platform
★ A reason that still means something in eleven months Reason: incident 4471, duplicate charges on EU accounts. Need: read phone and email in clear, EU rows only, to contact the 38 affected customers directly. Window: 72 hours from 02:40 on 14 March. Requested by: support lead. Approved by: head of data. On expiry: reverts automatically. Renewal requires a new reason.

The second one is not bureaucracy, it is the artifact that lets somebody defend the decision later without relying on memory. It is also, quietly, the thing that makes the grant removable: a reason tied to a closed incident is a reason that has visibly expired.

LiveThe standing-privilege arithmetic4 min▶

Saltbox's opening state is one shared analyst role carrying 30 standing privileges. The finished design carries 0. Nothing in between is exotic: the ladder goes 30, then 25, then 17, then 1 after the role split, then 0 once the modelling view is pseudonymised.

Policies onStanding privileges
One shared analyst role30
Plus mask national_id for everybody25
Plus mask email and phone, except support17
Plus split the shared role five ways1
Plus row access policy on region1
Plus pseudonymise the modelling view0

The point worth sitting with is not the shape of the ladder. It is where those 30 came from. Every one of them started as somebody being unblocked. Not one was granted by a person who thought they were creating a permanent exposure. Each was a reasonable answer to a real request, on a day when the requester needed to get on with something, and the only thing missing was an end date.

Which means the counter is not a measure of how disciplined your team is. It is a measure of whether your grants have expiry dates, and that is a design decision somebody can make this month.

LiveThe two-person rule for the top role3 min▶

Every platform has one role that sits above the model. In Snowflake it is ACCOUNTADMIN, which combines the system and security administration roles; other warehouses have an equivalent under a different name. It should be held by two named humans, for break-glass only. Two, because one is a single point of failure and three is a habit.

The reason for the severity is measurable. Take Saltbox's finished design, with every masking policy, every row policy and the five-way role split still defined and deployed, and grant one person the top role. The score returns to 109 leaks and 30 standing privileges, which is identical to the opening state before any policy existed at all.

The policies do not fail, they stop applying. Nothing breaks, nothing errors, no alert fires. The controls remain deployed and correct and simply cease to constrain anybody. That is why the top role is not a seniority question, and why "she needs it to get things done" is a description of a missing role rather than a case for granting this one.

The practical move is short. Write the two names. Write the list of everybody else who currently holds it. For each of those, write what they were unblocked for, because that is the role you actually need to create.

Self-studyWriting an expiry policy you would actually enforce4 min▶

An expiry policy fails when it is written to be defensible rather than to be followed. Four questions decide whether yours will hold.

  • What is the default window, and does it apply to everybody. One default, with named exceptions that have reasons. A policy with per-team windows is four policies and they will drift.
  • What happens on the expiry date. Automatic revocation, or a notification to a human. Only one of those is an expiry policy. The other is a reminder, and reminders are ignored during exactly the weeks that matter.
  • Who can extend, and how many times. Unlimited renewals are fine if each one is logged and the third one triggers a design conversation rather than an approval.
  • What is exempt, and is that written down. Service accounts and standing job roles usually are, legitimately. An exemption list nobody has enumerated is not an exemption, it is a gap.

One test before you commit to a window: would you enforce it during your busiest week of the year, on the person you can least afford to block. If the honest answer is no, the window is too short and you have just discovered the number you can actually hold.

Build-along

Fix your request path

★ 18 min · everyone builds

Five of these produce a number and one produces a list of names. The names are the deliverable. Work down the steps and keep the answers rough, because a rough figure written down beats a precise one that arrives after the decision.

Time your own access request path end to end. Request something small yourself and measure from the moment you realise you are blocked to the moment you are working. Not the platform team's figure, which starts at ticket creation and ends at grant, and misses both halves where the time actually goes.

Count the requests in the last quarter that were for the same thing. Group by what was asked for, not by who asked. Any group of three or more is a line missing from the access design, and you are currently paying for it once per request forever.

Find every grant with no expiry that was made during an incident. Ask for grants created outside working hours, or during the weeks of your last three incidents. Each one had a good reason at 2am and almost certainly still exists.

Write the expiry policy you would actually enforce. One default window, what happens automatically on the date, who can extend and how often, and the exemption list written out in full. Test it against your busiest week and the person you can least afford to block.

Write down the two names who should hold the top role. Two, by name, for break-glass only. Then write everybody else who holds it today, and next to each one the thing they were unblocked for. That second list is a specification for the roles you are missing.

Ask one blocked colleague what they do instead. Without judgement, because they are behaving rationally and will tell you plainly. Whatever they name is a shadow path with worse logging than the control you deployed, and it is the honest measure of your friction budget.

Do the two names before you leave the room. It is the only step here that costs nothing, needs no data from anybody, and changes the worst possible day. Everything else on this list can slip a week without much consequence.

Homework

Before session 4

30 min
  1. Finish the repeat-request grouping for one full quarter and turn the top three groups into proposed lines in the access design.
  2. Get the list of grants with no expiry date, with the date each was made. Sort by age and read the oldest ten out loud to yourself.
  3. Circulate the expiry policy to the two people who will have to operate it and change it until they say they can. A policy the operators cannot hold is a policy that ends as an exemption.
  4. Send the two names for the top role to whoever administers it, along with the removal list and a date. A decision that stays in your notebook is not a decision.
  5. Ask a second blocked colleague, in a different team, what they do instead. Two answers from two teams is enough to know whether you have a pattern or an anecdote.
Check yourself

Three questions

The same access request arrives for the fourth time this quarter, from a fourth person in the same job. What is it telling you?

Repeated requests for the same thing are a design signal rather than a discipline problem. Requests cluster by job, and a pairing that every new person in a job asks for belongs in that job's role.

A grant is issued at 02:40 during an incident, with no expiry date. Eighteen months later, what is it?

The grant that reverts automatically is the only kind that reverts. Revocation depending on somebody remembering, during the week after an incident, is a permanent grant with an optimistic label.

Saltbox's finished design scores 0 leaks and 0 standing privileges. One person is then granted ACCOUNTADMIN. What happens to the score?

The policies do not fail, they stop applying. Nothing errors and no alert fires, which is why the top role belongs to two named humans for break-glass only rather than to whoever is senior.

Sources covered

What tonight maps to

✓ The friction budget Every control spends somebody's working time, the budget is finite and already being spent, and the three measurements that price it without a project.
✓ The access request queue as a signal Repeats as missing design lines, clustering by job rather than person, volume as a design metric, and the requests that stop arriving.
✓ The shadow-path rule Friction beyond the value of a shortcut gets routed around. Shared logins, exports and screenshots, each compared on audience and logging.
✓ Break-glass with an expiry Expiry in the grant rather than a calendar, short windows with cheap renewal, renewals read as design signals, and alerting on use rather than holding.
✓ Time-bound elevation with the reason recorded Why the reason is unrecoverable a month later, what a defensible request record contains, and how a closed incident makes a grant visibly removable.
✓ The standing-privilege arithmetic and the top role 30 down to 0 across the ladder, every one of the 30 starting as somebody being unblocked, and the top role returning the finished design to 109 leaks and 30 standing privileges.
◐ Classification, masking and exception roles Session 4. Tonight names masked access only as what lets a job proceed rather than be blocked into a shadow path.
◐ Evidence, recertification and the review routine Sessions 5 and 6. The expiry policy written tonight is one of the things that review will check, and the reason field is the evidence it reads.
· Identity providers, SSO and MFA Not covered by design. Authentication is upstream of every control here, including the two named humans on the top role.
· Data protection law and consent Not covered by design. What the law requires is a separate discipline; this is the machinery that carries out a decision once it has been made.

Session 3 cheat sheet

Friction has a budgetEvery control spends somebody's working time, and it is spent whether or not you count it.
The queue is a specThe same request three times is one missing line in the design, paid for three times.
Shadow-path ruleFriction beyond the value of the shortcut gets routed around, and the routes are worse.
Three routesShared login, weekly export, screenshot in a ticket. Wider audience, thinner logging.
Expiry or nothingThe grant that reverts automatically is the only kind that reverts.
Reason at request timeFifteen seconds now, unrecoverable in a month. It is what makes the grant removable later.
30 to 0Every one of those 30 standing privileges started as somebody being unblocked.
Two named humansGranting the top role returns the finished design to 109 leaks, every policy still deployed.