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

Proof, not promises

The awkward part of an access programme is not designing it. It is the morning somebody asks you to demonstrate that the thing you designed is the thing currently running, and that you would find out if it stopped. Most teams answer that question with a screenshot and a sincere sentence, and both are worth exactly nothing to the person asking. Tonight is what evidence has to survive, the three artifacts that survive it, and the honest version of recertification, which is a much shorter document than the one being signed today.

🟠 Advanced Data and analytics leaders Whoever signs the access review 45 min
0-3 · Welcome 3-22 · What counts as evidence 22-40 · Build-along: make one review reproducible 40-45 · Q&A
Part 0

The gap between a good policy and a provable one

Sessions 1 to 4 produced a design: three counters, a role model, least privilege people can work with, and a classification with named exceptions. All of it is a claim. Tonight turns the claim into something a stranger can check without your help, over the same table as before, saltbox.customers at Saltbox, a consumer lending startup, whose ten columns run from a plan name to a national ID across three regions and five jobs. The output is not a better policy. It is the same policy, made falsifiable.

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

★ What you walk out with tonight. The three tests any piece of evidence is silently measured against, so you can tell in ten seconds whether what you are about to send will be accepted. The three artifacts that pass all three, none of which take longer to produce than the screenshot they replace. And a recertification packet a manager can actually evaluate, which is the difference between collecting a signature and collecting information.

LiveThe question is not "is this secure"3 min▶

An auditor is not evaluating whether your access design is a good one. That is your judgement to make and they have no basis to second-guess it. What they are testing is much narrower and much harder to fake: whether you can demonstrate that what you claim is what is deployed, and whether you would notice if it changed.

That reframing is worth sitting with, because it changes what you spend the week before an audit doing. Polishing the policy does not move the needle. Being able to regenerate the current state of the world from a command, next to a written statement of what it should be, does.

Real world

Saltbox passed one review on a bundle of screenshots and failed the next one with a stronger policy in place. The difference was a new auditor who asked the second question: show me the same evidence for the previous quarter so I can see what changed. Nobody had kept the earlier screenshots, and the ones from the current quarter had been taken by hand, so there was nothing to compare and no way to reproduce the comparison.

Self-studyThe vocabulary of an evidence conversation4 min▶
  • Access design - the written statement of which jobs need which columns in which regions. It is the ground truth every other artifact is compared against, and without it there are no findings, only opinions.
  • Grants dump - a generated text file listing the privileges that currently exist. Generated, not assembled, because the value is in being able to produce it again on any date.
  • Exception register - one row per exception: the class, the role, the reason, the approver and the expiry. The output of session 4, and the thing an auditor reads first.
  • Recertification - the recurring exercise where somebody confirms that current access is still correct. Also the most widely performed and least informative control in the discipline.
  • Standing privilege - a column a role can read in clear that the design does not mark clear for that role. The number this whole session exists to make reportable.
Part 1 · covers the three tests and the three artifacts that pass them

A screenshot is not evidence

10 min live

Every piece of evidence gets measured against the same three tests, whether or not the person asking says them out loud. Can it be reproduced. Is it dated against a history of changes. Can it be compared to the last time. A screenshot fails all three, which is why the request always comes back a second time.

Three candidates, three tests An auditor tests the artifact, never the intention behind it candidate evidence reproducible timestamped comparable A screenshot of the grants page taken the week of the audit no cannot be re-run no no change history no nothing to diff A spreadsheet exported by hand and emailed once, at audit time no assembled by hand yes sent on a date no a different shape The design in version control, a generated grants dump you can diff, an exception register yes regenerate any time yes commit history yes diff to last quarter The tests: can you re-run it, is it dated, can you compare it to last quarter. A screenshot fails all three, which is why the request comes back a second time.
🔍 Click to zoom - the trio costs less to produce than the screenshot it replaces.
LiveThe three tests, one at a time4 min▶

Each test exists because of a specific way evidence has been wrong in the past, and knowing which failure each one is guarding against makes them easy to apply yourself.

  • Reproducible. Can somebody else produce the same artifact from the system, today, without you in the room. This guards against evidence that describes a state that never quite existed, which is what hand-assembled evidence tends to do without anybody intending it.
  • Timestamped against a change history. Not "does it have a date on it" but "can you place it in a sequence of changes". A dated file that sits alone tells you the state on one day and nothing about how it got there or what happened after.
  • Comparable. Can it be put next to the same artifact from last quarter and produce a difference. This is the test that actually detects drift, and it is the one most evidence fails, because each round is produced in a slightly different shape by a slightly different person.

Notice that none of the three is about how thorough the artifact is. A short reproducible file beats a comprehensive one that exists only once, every single time.

LiveWhy the screenshot keeps getting sent anyway3 min▶

The screenshot survives because it is the fastest thing to produce under pressure and because it looks like proof to the person sending it. It is a picture of the real system, after all. But it is a picture of one screen, at one moment, chosen by the person being audited, in a format nothing can compare.

  • It cannot be re-run. If the state changed yesterday, the image is silently wrong and there is no way to detect that from the image.
  • Its date is metadata, not history. A file creation date says when the picture was taken, not when the grant was made, by whom, or what it replaced.
  • It cannot be diffed. Two screenshots from two quarters have to be compared by a human reading them side by side, so in practice nobody does it and drift is never found.
  • The framing is chosen by the subject. Not dishonestly, usually. But a screen showing the roles you thought to check is a different thing from a dump of all of them.
LiveThe three artifacts that work4 min▶

Three files, produced together, cover the whole question. They are not impressive individually, and together they answer both halves of what is being tested: what you claim, what is deployed, and whether you would notice a change.

ArtifactWhat it answers
The written access design, in version controlWhat you claim should be true, with the commit history showing when each decision changed and who approved it
A generated grants dump, in a file you can diffWhat is actually deployed right now, produced by a command anybody can re-run
An exception register with a reason and an expiry per rowEvery deliberate departure from the default, why it exists and when it stops being valid

The pairing is what makes it evidence. The design alone is a promise. The dump alone is a state with no standard to judge it by. Put them side by side and the gap between them is your finding list, produced by a comparison rather than by an opinion, which is also exactly what the auditor was going to do with them.

Generate the dump on a schedule, not before an audit. A file produced monthly and committed gives you the change history for free, and it means the answer to "show me last quarter" already exists rather than being reconstructed under time pressure.

Self-studyWhat an exception register row has to carry4 min▶

The register is short and it is read first, so every column on it is doing work. A row that cannot answer these five questions will generate a follow-up, and follow-ups are how a two-day review becomes a two-week one.

  • Which class or column the exception applies to, matching the names used in the design. Different names in the two documents reads as two different systems.
  • Which role holds it, never which person. A person named on a register is a row that becomes wrong the day they change team, and nobody updates it.
  • The reason, in one sentence a stranger can evaluate. Support has to reach the actual human. Not "operational requirement", which cannot be checked and therefore cannot expire.
  • The approver, by name, being whoever owns the table rather than whoever had the ability to grant it.
  • The expiry, as a date. An exception without one is a permanent grant that has been described as temporary, and a register full of those is evidence of the wrong thing.

Empty rows count. A class with no exception role belongs on the register too, written as none, because the strongest statement in the design is invisible if it is only recorded as an absence of rows.

Part 2 · covers recertification, the reportable number and the honest limit

Recertification, and the honest version of it

8 min live

Recertification is meant to catch the grant that outlived its reason. What it usually does is put a list of 200 role names in front of a manager who has no way to evaluate any of them, and collect a signature. The signature is real and the information content is zero, and the fix is not more diligence from the manager. It is a different packet.

Two packets, the same estate, the same hour of somebody's time One asks for a signature. The other asks two questions that have answers. Packet A: the 200-row inventory every role name, one approve button role name, no dates, no usage, no diff analyst_shared support_agent finance_all etl_legacy_loader contractor_apac platform_admin plus 194 more rows, identical in shape Approve all signature, no information Packet B: the diff and the unused list seven rows, two answerable questions New since the last review (3) analyst_eu to mrr, 12 Aug, ticket 4411 support_agent to notes, 3 Sep, no ticket contractor_apac to EU rows, 28 Aug Held but unused for 90 days (4) finance_all: national_id, 0 reads etl_legacy: all columns, 0 reads analyst_shared: dob, last read 2025 Should this new grant exist? Why does this role still hold it? A packet you can evaluate returns information. A packet you cannot returns a name. Neither proves intent: an approved grant to the wrong person still passes.
🔍 Click to zoom - the same hour of attention, spent on seven rows instead of two hundred.
LiveWhat recertification is for, against what it does3 min▶

What it is meant to do. Find the grant whose reason has expired. Somebody moved team, a project finished, an incident was resolved, and the access stayed. Nothing in a warehouse notices any of those events, so a recurring human check is genuinely the right control.

What it usually does. A quarterly export lands in a manager's inbox listing every role their reports hold. Two hundred rows of names like analyst_shared and etl_legacy_loader, with no dates, no usage and no indication of what changed since last time. The manager cannot evaluate a single row and is not being unreasonable about that: the packet contains no information to evaluate against. So they approve all, on time, and the control reports 100 percent completion.

The failure is in the packet, not the person. A control that requires somebody to know something the document does not tell them will be performed and will detect nothing, quarter after quarter, while showing green.

LiveMaking it evaluable: the diff and the unused list4 min▶

Replace the full inventory with two short lists and the same hour of a manager's attention starts producing findings.

  • The diff. What changed since the last review: new grants, removed grants, changed roles, each with a date and whatever ticket or approval is on file. Usually a handful of rows. The question becomes should this new grant exist, which a manager can genuinely answer, because it is about a recent decision they may well have been part of.
  • The unused-privilege list. Privileges the role holds and has not exercised in 90 days, read from query history. The question becomes why does this role still hold something nobody used, and the honest answer is often "no reason", which is exactly the finding recertification was invented to produce.

Both questions have answers. That is the whole design criterion. A packet of 200 role names asks an unanswerable question 200 times and gets one signature; a packet of seven rows asks two answerable ones and gets seven decisions.

Keep the full inventory, do not send it. The complete list still belongs in the evidence pack for anybody who wants to check the diff was honest. It just should not be the thing a human is asked to read, because a human reading it produces nothing.

LiveThe number to put on the monthly report4 min▶

Recertification completion percentage is the metric usually reported, and it is a measure of whether people clicked, not of whether access is correct. The reportable outcome is standing privileges: columns a role can read in clear that the design does not mark clear for that role.

The Saltbox ladder makes the case on its own. One shared analyst role carries 30 standing privileges. The finished design, with masking, a five-way role split, a row policy on region and a pseudonymised modelling view, carries 0, alongside 0 leaks and 0 over-blocks across the same 150 requests.

StateLeaksOver-blocksStanding privileges
One shared analyst role109030
The finished design000
The finished design, plus ACCOUNTADMIN granted109030

That third row is the one to keep in mind when you report a zero. Every policy is still defined and still deployed, and the estate is identical to where it started, because one grant sits above all of it. A number is only evidence if the thing that can silently invalidate it is also being reported.

LiveThe honest limit: a review proves state, never intent3 min▶

Worth saying plainly, and worth saying to the person who signs, because a control oversold is a control that gets blamed later. A review compares deployed state against written design. It cannot see purpose.

A grant that is correctly approved, correctly recorded, within design, and issued to somebody who is going to misuse it passes every test in this session. So does a grant to the wrong person with the right job title. Those are detected by monitoring what was actually read, by separation of duties, and by the fact that somebody notices a colleague pulling records they have no reason to pull.

  • What a review does prove. That the deployed state matches the written design on the date it ran, and that you can show what changed since last time.
  • What it does not. That the design is correct, that the approvals were thought about, or that access is being used for the purpose it was granted for.
  • Why saying so helps. It puts the residual risk somewhere it can be owned, rather than leaving it hidden inside a green control that everybody assumed covered more than it does.
Self-studyThe questions an auditor asks in order4 min▶

Reviews vary, but the sequence rarely does, and knowing the order tells you which artifact to have open.

  • What is the control. Answered by the written access design. If this takes more than one document to answer, everything after it gets slower.
  • Show me it is deployed. Answered by the generated grants dump, produced live if possible. Producing it in the meeting is worth more than any amount of prepared material.
  • Show me the departures. Answered by the exception register, which is why the reason column has to be readable by somebody who does not know your business.
  • Show me last quarter. Answered by the commit history and the previous dump. This is the question the screenshot approach dies on.
  • Who approved this one. Answered by the register and the commit that added it. A change with no approver named is a finding regardless of whether the change was correct.
  • How would you know if it changed. Answered by whatever runs on a schedule and by who reads its output. "We would notice" is not an answer, and it is the most common one given.
Build-along

Make one review reproducible

★ 18 min · everyone builds

One table, three artifacts, and one rewritten packet. Use the table you classified last session, or saltbox.customers with its ten columns, three regions and five jobs. The point of the timing step at the end is that the honest version is usually faster, and nobody believes that until they measure it.

Pick one table and produce the three artifacts for it. The written access design, a generated grants dump, an exception register. All three in the same place, all three named so a stranger can tell which is which. If you have to choose one to start with, start with the design, because the other two are only meaningful next to it.

Generate the grants dump into a file you can diff. Ask the platform team for the command rather than the output, so it can be run again next month by somebody else. Plain text, sorted deterministically, one grant per line. Sorting matters more than it sounds: an unsorted dump produces a diff full of noise and everybody stops reading it by the second quarter.

Write the exception register with expiries. Class, role, reason, approver, expiry. Include the classes where the exception is none. Any row where you cannot write a checkable reason in one sentence is not a documentation gap, it is an exception nobody can currently justify, and that is tonight's most useful finding.

Take one real recertification list and rewrite it as a diff plus an unused-privilege list. Compare the current grants to the previous version for the diff. For the unused list, ask for privileges not exercised in 90 days according to query history. Keep the full inventory in the pack, but do not put it in front of a human.

Time both versions with a real reviewer. Hand somebody the 200-row list and time how long until they approve. Then hand them the rewritten packet and time that, and count the decisions each one produced. The first number is usually smaller and the second number is usually zero.

Write down your standing-privilege count and the date. One number for one table. Next month it is a comparison instead of a fresh estimate, which is the same reproducibility test applied to your own reporting.

Schedule the dump before you need it. The single highest-value thing to leave this session with is a job that produces the grants dump monthly and commits it. It converts "show me last quarter" from a scramble into a file path, and it costs one afternoon.

Homework

Before session 6

30 min
  1. Get the grants dump generating on a schedule for one table and committed somewhere with a history. One table is enough to prove the pattern and to argue for the rest.
  2. Finish the exception register, including the none rows, and send it to each named approver so they know they are on it.
  3. Run the rewritten recertification packet with one real manager and record how many decisions came back. Bring the count to session 6.
  4. Count how many humans currently hold the top administrative role. Any number above two makes every zero you report conditional, and that condition belongs on the report.
  5. Write the one-sentence answer to "how would you know if this changed", and then check whether the person named in that sentence knows it is them.
Check yourself

Three questions

An auditor asks for evidence that your column policy is deployed. Which of these passes reproducible, timestamped and comparable?

The trio answers both halves of what is being tested: what you claim, what is deployed, and whether a change would show up. A screenshot fails all three tests, and a confirmation email is a promise rather than evidence.

A manager is sent 200 role names with no dates and no usage, and approves them all on time. What has the control produced?

The failure is in the packet rather than the person. A control that asks somebody to know what the document does not tell them will be completed on time, report green, and detect nothing.

Against 150 access requests, how do standing privileges compare between one shared analyst role and the finished design?

0 against 30, with 0 leaks and 0 over-blocks alongside it. The figure worth remembering next to it is that granting the top administrative role puts the whole estate straight back to 109 leaks and 30 standing privileges, with every policy still deployed.

Sources covered

What tonight maps to

✓ What an auditor is actually testing Not whether the design is good, but whether you can demonstrate that the claim matches the deployment and that a change would be noticed.
✓ Why a screenshot is not evidence The three tests stated separately, the specific failure each one guards against, and the four reasons a screenshot fails all of them.
✓ The three artifacts that work The design in version control, a generated grants dump, and an exception register with a reason and an expiry per row, including the none rows.
✓ Recertification, and the version that produces findings What it is meant to do against what it does, and the diff plus unused-privilege packet that turns one unanswerable question into two answerable ones.
✓ The standing-privilege number as the reportable outcome 0 for the finished design against 30 for one shared role, and the administrative grant that returns the estate to 109 leaks with every policy deployed.
✓ The honest limit of any access review State, never intent. A correctly approved grant to the wrong person passes every test here, and naming that puts the residual risk somewhere it can be owned.
◐ Generating the evidence as a pipeline The builder track builds it: query history against grants, unused-privilege and over-grant reports, and scheduled evidence generation.
◐ Who approves against who reviews, and the monthly report Session 6. Tonight produces the numbers; session 6 decides who owns them and what a 90-day plan looks like.
· Audit standards and certification schemes Not covered by design. Which framework applies to you is a separate discipline; these three tests are what the evidence has to survive under any of them.
· Identity providers, SSO and MFA Not covered by design. Authentication sits upstream of every control here; all of this begins after a session already exists.

Session 5 cheat sheet

Three testsReproducible, timestamped against a change history, comparable to last quarter.
The real questionNot "is this secure" but "can you show the claim is deployed, and would you notice a change".
Three artifactsDesign in version control, a generated grants dump, an exception register with expiries.
Generate on a scheduleA monthly committed dump makes "show me last quarter" a file path instead of a scramble.
200 rows is not a reviewAn unevaluable packet returns a signature and no information. The packet is the failure.
Send the diff insteadShould this new grant exist, and why does this role still hold something nobody used.
Report standing privileges0 for the finished design against 30 for one shared role, not completion percentage.
State, never intentA correctly approved grant to the wrong person passes every one of these tests.