Skip to main content

Command Palette

Search for a command to run...

The Evidence Chain Map

A control that ran but left no trail didn't run, as far as an auditor is concerned.

Updated
16 min readView as Markdown

@18xBan · GRC Series · Chapter 07

6 links from "we do this" to "here's the proof." 4 were broken, and the other 2 were weak.


Monday, 8:50 AM: "Show us, don't tell us"

The email from Gotham Mutual's vendor-risk team is short and polite.

Ahead of Thursday's walkthrough, please be ready to show that access was removed for everyone who left Wayne in the last 90 days, employees and contractors. We'd like the list of leavers, the date each person left, and the date their access was disabled.

You read it twice and relax a little. Offboarding has an owner now. Farah owns the trigger, and you do the removal. Everyone said "I accept." It's on the list.

Then you try to answer the actual question, and the morning goes sideways.

Farah exports 6 employee departures from the HR system in about 2 minutes. Good start.

"And the contractors?" you ask.

"Contractors aren't in HR," she says. "Finance pays them. Ask accounts payable."

You pull up the domain controller's Security log to grab the "account disabled" events. The oldest event in the log is eleven days old.

By 10 AM you know three things. Wayne does offboard people. Wayne can't prove it. And you're not yet sure it offboards all of them.

"Show us" is a much harder question than "Do you?"


What an evidence chain actually is

An auditor never takes your word for anything. They follow a chain.

Think of a parcel with tracking. "We shipped it" means nothing. The tracking page shows it was picked up, scanned at the depot, loaded on the truck and signed for at the door. If any scan is missing, you can't prove it arrived, even if it did.

Controls work the same way. For any control, the chain has 6 links:

  1. Rule. Where is it written what should happen, and by when?

  2. Trigger. What starts the control, and is there a complete list of those starts?

  3. Action. Who does the work, and where is the request recorded?

  4. Record. What system writes down that it happened, with a timestamp?

  5. Review. Who checks that it happened correctly, and where is that check recorded?

  6. Kept. Where does the proof live, and will it still be there when an auditor asks?

An evidence chain map is a document that lays out those 6 links for one control. It names the system, the person and the storage location for each link.

The auditor's job is to walk the chain from end to end. Yours is to walk it first.

Rule, trigger, action, record, review, kept. Break one and the chain doesn't hold.

The unpopular truth: a control that ran but left no record didn't run, as far as an auditor is concerned. "We always do that" is a statement, not evidence.


How an auditor walks the chain

Auditors have three ways to test a control. NIST SP 800-53A, the US government's guide to assessing controls, names them plainly:

  • Examine: read documents and records. Policies, tickets, logs.

  • Interview: talk to the people who run the control.

  • Test: make the control do its thing and compare what happens with what should happen.

SOC 2 auditors work the same way, even if they use different words. So do ISO 27001 certification auditors.

For offboarding, the walk looks like this:

  1. Ask for the population: every person who left in the period.

  2. Check that the population is complete. Does it match other sources?

  3. Pick a sample, or take all of them if the list is short.

  4. For each person, compare the date they left with the date access was disabled.

  5. Ask who reviews this, and see the record of that review.

Wayne's population was the first thing to break.


Wayne's access control policy is one of the 40 on the shared drive. It says access is removed "promptly" when someone leaves.

"Promptly" can't be tested. An auditor can't count days against it.

CIS Controls v8.1 Safeguard 6.2 asks for accounts to be disabled immediately upon termination. You propose a rule you can measure: access is disabled by the end of the person's last working day. Farah agrees. Dan approves it on Monday afternoon, by email.

That email is the rule, dated and approved.

Farah's HR export has six employee departures in the 90-day window.

Accounts payable keeps its own spreadsheet of contractors. 3 contracts ended in the same window. None of them are in the HR system, so none of them ever triggered offboarding.

That's the most common break in any evidence chain. Population completeness means proving your list includes everyone it should. If the list is incomplete, a perfect test of that list proves nothing.

6 leavers in HR. 3 more in a finance spreadsheet nobody connected.

Offboarding requests go through Deskline, Wayne's support desk. 5 out of 6 employee departures have a ticket. One contractor account was disabled because Priya asked in a hallway. No ticket.

The account was still disabled on time. It just left no trail.

This is where you find the break that stings most. Windows writes Event ID 4725, "A user account was disabled," to the domain controller's Security log. That's your timestamped record.

Get-WinEvent -ListLog Security -ComputerName DC01 |
  Select-Object LogName, LogMode, MaximumSizeInBytes, RecordCount

Get-WinEvent -ComputerName DC01 -LogName Security -MaxEvents 1 -Oldest |
  Select-Object TimeCreated
LogName  LogMode  MaximumSizeInBytes RecordCount
-------  -------  ------------------ -----------
Security Circular           20971520       48213

TimeCreated
-----------
2024-10-24 06:12:41

Sample output (illustrative). Wayne Industries is fictional.

The log is 20 MB and set to circular, which means new events overwrite the oldest ones. On a busy domain controller, that's about eleven days. Nobody changed it, and nothing ships the events anywhere else.

CIS Safeguard 8.10 asks for audit logs to be kept for at least 90 days. Wayne keeps eleven.

For older disables, there's a second source. Active Directory records when each attribute last changed. Disabling an account changes userAccountControl:

Get-ADReplicationAttributeMetadata -Server DC01 `
  -Object "CN=Rashid Osei,OU=Staff,DC=wayne,DC=example" `
  -Properties userAccountControl |
  Select-Object AttributeName, LastOriginatingChangeTime, Version
AttributeName      LastOriginatingChangeTime Version
-------------      ------------------------- -------
userAccountControl 2024-09-19 14:07:22             3

Sample output (illustrative). Wayne Industries is fictional.

That's useful, but it only shows the last change to that attribute. If someone re-enables and disables the account later, the earlier date is gone. Treat it as supporting evidence, and pair it with the ticket.

The log that was supposed to be the record forgot everything older than 11 days.

Nobody ever compared "date left" with "date disabled." Not monthly, not ever. So nobody knew whether the control worked.

The tickets are in Deskline. The log was on DC01 until it wasn't. The HR export lived in Farah's downloads folder.

None of it was in one place, and none of it had a retention period.


The template: SCF Evidence Request List

You don't need to invent a format for this. The Secure Controls Framework (SCF) publishes a free Evidence Request List (ERL). It's a catalogue of the artifacts an assessor would reasonably expect for each control, mapped to SCF controls. The SCF says it can serve as a guidebook for other audits too, not just SCF assessments.

Get it from the SCF website, as part of the free SCF download. https://securecontrolsframework.com/

The ERL tells you what to hand over. It doesn't tell you where it comes from or whether it will still exist. So Wayne keeps the ERL's own columns and adds 6 chain columns to its copy.

Field by field

Field Source What goes in it
ERL # SCF The SCF's identifier for the evidence item
Area of Focus SCF The domain the artifact belongs to, e.g. identity and access
Documentation Artifact SCF The name of the thing an assessor asks for
Artifact Description SCF What the artifact should show
SCF Control Mappings SCF The SCF controls this artifact supports
Control owner Wayne The accountable person, from the ownership list
Rule Wayne Where the requirement is written, and the measurable standard
Trigger and population Wayne Every source that starts the control, and how you prove the list is complete
Action record Wayne Where each request and action is logged
System record Wayne The timestamped system event, and how long it's kept
Review Wayne Who checks the results, how often, and where the sign-off lives
Kept in, for Wayne Storage location and retention period

Wayne before

Chain column Offboarding, Monday morning
Control owner Farah (trigger), You (removal)
Rule Access policy (2021): "promptly"
Trigger and population HR system only. Contractors missing
Action record Deskline, when someone remembers
System record Event 4725 on DC01, about 11 days, circular
Review None
Kept in, for Scattered. No retention set

Wayne after

Chain column Offboarding, Wednesday evening
Control owner Farah (trigger), You (removal), Dan (review)
Rule Disabled by end of last working day. Approved by Dan, Monday
Trigger and population HR export plus the accounts payable contractor list, reconciled monthly against the AD Contractors OU
Action record Deskline ticket required for every disable, including contractors
System record Event 4725 forwarded to CloudWatch Logs, 400-day retention. DC01 log raised to 1 GB
Review Monthly leaver test by you, signed by Farah, reviewed by Dan
Kept in, for Evidence/Access/Offboarding/ on the shared drive, kept 3 years

Same control, same owners. Now every link says where the proof lives.

The unpopular truth: most evidence is collected the week before an audit, from whatever still exists. That's why so much of it gets rejected. Evidence has to be designed into the control, not gathered after it.


The test: 9 people, 2 problems

With both lists joined, you test all nine leavers. 9 is small enough to skip sampling.

Contractor accounts first, since that's where you're least sure:

Get-ADUser -Filter 'Enabled -eq $true' `
  -SearchBase "OU=Contractors,DC=wayne,DC=example" `
  -Properties LastLogonDate, AccountExpirationDate |
  Select-Object SamAccountName, Enabled, LastLogonDate, AccountExpirationDate
SamAccountName Enabled LastLogonDate        AccountExpirationDate
-------------- ------- -------------        ---------------------
ctr.jlee          True 2024-09-24 16:48:03
ctr.mvarga        True 2024-10-18 15:21:37
ctr.dfarouk       True 2024-11-01 09:02:15

Sample output (illustrative). Wayne Industries is fictional.

ctr.dfarouk is a current contractor, which is fine. The other 2 contracts ended 41 days and 17 days ago. Both accounts still work, and Wayne's VPN signs people in with their AD account.

Neither account shows a sign-in after the contract ended. LastLogonDate can lag by up to 2 weeks, though, so you check the VPN logs too. Nothing there either.

You disable both accounts on the spot, with tickets. Then you set an expiry date on every contractor account, so the account shuts itself off even if nobody remembers.

The full result:

# Account Type Last day Disabled Evidence Result
1 a.brooks Employee Aug 16 Aug 16 Ticket + AD metadata Pass
2 m.chen Employee Aug 30 Aug 30 Ticket + AD metadata Pass
3 r.osei Employee Sep 13 Sep 19 Ticket + AD metadata Late, 4 business days
4 t.walsh Employee Sep 27 Sep 27 Ticket + AD metadata Pass
5 k.dubois Employee Oct 11 Oct 11 Ticket + AD metadata Pass
6 s.patel Employee Oct 25 Oct 25 Ticket + Event 4725 Pass
7 ctr.hsato Contractor Aug 23 Aug 23 AD metadata only, no ticket Pass, weak evidence
8 ctr.jlee Contractor Sep 24 Nov 4 Ticket (today) Exception, 41 days
9 ctr.mvarga Contractor Oct 18 Nov 4 Ticket (today) Exception, 17 days

Row 3 happened because the ticket was raised 4 days after the person left. Rows 8 and 9 happened because contractors never triggered anything at all.

9 leavers, 1 late, 2 never done.

The unpopular truth: finding your own exceptions before an audit is the best result you can get. Exceptions you find and fix are a working control. Exceptions an auditor finds are a finding, and a question about everything else you told them.


Evidence #7

On Wednesday you put it together. It goes in Evidence/Access/Offboarding/:

  • The chain map for offboarding: the ERL row plus Wayne's 6 chain columns.

  • Dan's approval of the "end of last working day" rule, from Monday.

  • The HR export and the accounts payable list, with the reconciliation note.

  • The nine-row test sheet with all three problems written up: cause, fix and date fixed.

  • Farah's sign-off on the test, and Dan's review on Wednesday at 5:15 PM.

Evidence #7: a complete, reconciled offboarding test with its exceptions disclosed and fixed.

"Do we tell Gotham?" "We tell Gotham."


Thursday, 2 PM: the walkthrough

Gotham Mutual's analyst asks for the leaver list first. You show both sources and the reconciliation.

She picks row 8 and asks why a contractor kept access for 41 days. You show the cause, the fix, the VPN check and the new expiry dates.

She asks how she'll know it keeps working. You show the monthly test, who signs it, and where the next one will be filed.

She writes down 2 things: a finding that was self-identified and fixed, and a request to see next quarter's test.

That's not a pass. But it's a conversation that can end in a signed contract, which "trust us" never is.

"You found these yourselves?" "Then fixed them. Here's the chain."


What an auditor accepts vs rejects

Accepted Rejected
A population drawn from every source, with a reconciliation One system's list, with no proof it's complete
A system-generated record with a timestamp A screenshot with no date, system or user visible
A ticket raised before or at the time of the action A ticket created the week of the audit
Log retention that covers the whole audit period "The log rolled over, but we definitely did it"
A review with a named reviewer and a date A review nobody can show
Exceptions written up, with cause and fix A test with zero exceptions and no detail
Evidence stored in one place with a retention period Evidence gathered from inboxes on request

What you actually do on Monday

  1. Pick one control that an auditor or customer is sure to ask about. Offboarding is a good first choice.

  2. Write the six links for it on one page: rule, trigger, action, record, review, kept.

  3. Find every trigger source. HR, finance, vendor contracts, the agency that hires your temps.

  4. Check how long your records really last. Look at log size and mode, not the policy.

  5. Run the test yourself. Last 90 days, every leaver, last day vs disabled date.

  6. Write up what you find, including the ugly rows, and get the owner to sign it.


Framework mapping

Every framework wants the same thing: proof, not promises.


Maturity ladder

Stage 20 people 200 people 2,000 people
Rule One line in a shared doc, approved by the founder Measurable standard in the access policy Standard with defined SLAs per account type
Population One spreadsheet of everyone, including contractors HR and finance lists reconciled monthly HR system feeds the identity platform automatically
Record Admin console audit log, exported monthly Directory events forwarded to central logging SIEM with long-term retention and integrity checks
Review Founder checks the list once a quarter Monthly test by security, signed by the owner Continuous monitoring plus internal audit sampling
Kept One folder, one retention rule Evidence folders per control, in the ERL format A GRC platform linking every control to its evidence

Be honest: at 20 people, the whole chain map is often one spreadsheet tab. That's fine, as long as every link has an answer.

Where Wayne sits: at the 200-person stage for one control, offboarding, as of Wednesday. Every other control on the list still needs its own chain map, and most of them have a link nobody has checked.


Cheatsheet

The evidence chain, on one page.


The takeaway

A control is only as strong as the weakest link between the rule and the stored proof. Prove the population is complete before you test anything in it. Check how long your records really last, not how long you think they do. Find your own exceptions first, write them down, and fix them.


⚠️ This content is for educational purposes only. Wayne Industries is a fictional company. Nothing here is legal, audit, or compliance advice, validate against your own auditor and jurisdiction.

GRC Foundations

Part 7 of 7

How a governance, risk and compliance program gets built from nothing. Ownership, scope, asset inventory, policies, metrics and the first meetings that produce actual decisions, 16 posts, in order.

Start from the beginning

What GRC Actually Is (And What It Isn't)

Three letters, one messy SaaS company, and the email that starts everything @18xBan · GRC Series · Chapter 01 ⚠️ This content is for educational purposes only. Wayne Industries is a fictional compan