Skip to content
← Blog & Education · compliance 21 min read

Who touched the evidence

An auditor rarely doubts that your evidence is real. They doubt that it is the same file you collected. Chain of custody is the record that answers them — and the difference between a file Talarity has checked and one it has only been told about.

By The Talarity team · August 24, 2026

An auditor rarely doubts that your evidence is real. What they ask is narrower and harder: is this the same file you collected, and can you show who has had it since?

Most programmes cannot answer. The screenshot was taken in March, emailed to a manager, saved to a shared drive, renamed, and attached to a control in July. Every step was legitimate. None of them was recorded. By the time anyone asks, the honest answer is “we think so”, and in an investigation or a dispute, “we think so” is the same as “no”.

Chain of Custody is the register that makes the answer checkable. It records who collected a piece of evidence, who has held it since, who looked at it, whether the bytes still match what was collected, and — when its life ends — how it was disposed of and under what authority.

Where it lives

Chain of Custody is the fifth tab of Evidence Freshness, at /app/evidence/chain-custody, beside Freshness, Collection, Gap Detection, Review and Automation. The sidebar carries the one Evidence Freshness entry; the six tabs appear in a strip across the top once you are on it. That grouping is the right mental model: those tabs are the life of a piece of evidence, and custody is the part of that life concerned with who was holding it.

One thing to know before you go looking: Legal Holds is a separate feature on a different hub — the Artifact Repository, alongside Smart Evidence Intake and Smart Request Intake. Holds can be placed from either place, and the section on holds below is about why that matters.

The page itself opens on an Overview: summary cards over the five most recent chains.

The chain of custody Overview tab: summary cards for total chains, active, disposed, on legal hold, integrity verified, integrity attested and check failed, above a list of the most recent chains

Those cards count the whole register, not the page you are looking at — they are SQL counts that ignore whatever filter is applied, so they keep meaning the same thing while you narrow the list. Six are always there; Check Failed appears only when there is a failed check to show, which is why a healthy register shows one card fewer rather than a reassuring zero. Total, Active and Disposed are informational. On Legal Hold turns its figure amber when it is non-zero, because a hold is a state somebody must remember. The integrity cards are the ones worth learning to read, and the next section is about why.

The register itself is the Chains tab beside it. That is where the custodian, status and integrity columns live, under a filter bar the next section comes back to.

The Chains tab: the custody register, with its evidence, custodian, status and integrity columns above the legend defining the four integrity states

Verified, attested, checked, not checked

Talarity draws a line that most evidence tooling blurs, and the whole page depends on it.

Verified means the platform re-read the stored bytes and hashed them itself. The comparison was made against a file Talarity holds, using a hash Talarity computed. Nobody had to be believed.

Attested means the recorded hash matched one the caller supplied. That is a real and useful check — it proves the caller’s copy is consistent with what was registered — but it says nothing about bytes Talarity has never seen. Off-platform evidence, a file held in someone else’s system, an artifact whose contents were never uploaded: these can reach Attested and cannot reach Verified.

The two get separate cards for a reason. Folded into one number, the headline would overstate the guarantee for every off-platform artifact, which is the single thing this page exists not to do.

The other two states are about work rather than outcome. A chain begins as Not checked — recording a hash at collection is not the same as verifying one, and a chain is not permitted to claim a verification that has never run. Check failed means a check ran and did not match, for any of three reasons: the bytes are not what was collected, an event in the timeline has been altered, or an event has been removed. The third is the one people forget, and it is why the export reports the three checks separately rather than as one verdict. That is the state an auditor most needs to see, so it appears as its own card, its figure in red, the moment it is non-zero — and never before. A permanent “Failed: 0” trains the eye to skip exactly the position where the number would one day appear.

Starting a chain

A chain begins at collection. Two paths open one for you without your asking: whoever a work task is assigned to uploading a file against it — an external guest or one of your own people, the rule is assignment rather than account type — and attaching a destruction certificate or an access-revocation screenshot to a vendor’s offboarding checklist; that second kind of evidence is exactly what gets questioned later, so it gets a custody record the moment it arrives.

Everything else starts here, on the register, with the form below — including files already sitting in your Evidence Library, because uploading to the library does not open a chain on its own. All of them build the chain through the same shared shape, so a task-collected artifact carries exactly the record an admin-collected one does.

The initiate chain of custody form after a library record has been picked — the chosen record confirmed on its own line beneath the evidence field — beside the evidence type, collection method and source system fields

The evidence field is a picker over your Evidence Library, not a free-text identifier — which is what the line beneath it is for: once you choose a record, the form names the record it resolved to rather than leaving you to trust the box. That matters more than it sounds: an identifier typed by hand is right until somebody mistypes it, and a chain pointing at nothing looks exactly like a chain pointing at something. If your permissions do not extend to listing the library, the form says so and falls back to an ID field, rather than showing you a search box that silently returns nothing.

There is no custodian field, and that is deliberate: whoever collects the evidence holds it, so the chain opens in your name and changes hands only through a recorded transfer.

Collection method and source system are the two fields people skip and later need. They are the difference between “collected 14 March” and “exported from the production console on 14 March by the platform team” — the second answers a follow-up question before it is asked.

Finding one chain among many

A register that only works at demo scale is not a register. Chains can be narrowed by status, by evidence type, by tag, by whether a legal hold is in force, by whether a hold is lapsing within the next thirty days, by custodian, and by a free-text search over the register — and the filters combine.

The register's filter bar with a tag typed into the Tags field, and the table narrowed to the matching chains

Five of those seven sit in the filter bar as controls you can see, and the sixth is the search box beside them, so their state is never in doubt — including when you did not set them yourself. A card that drops you into the register with a status already applied moves the control to match it, rather than leaving the bar reading “All Statuses” over a table showing four rows. The seventh is not a control at all, and neither is one more that does not appear in the list above, because you never choose those: you arrive on them. Both are worth knowing about.

Clicking a custodian in the table filters to everything that person holds — the question an offboarding conversation actually starts with. The other is the one you meet without asking for it: the Check Failed card opens the register already narrowed to the chains that failed their check. The On Legal Hold card does the same for the chains on hold. Each of the seven cards opens exactly the set it counted — Total Chains included, which opens the register with every filter cleared — and that sounds too obvious to state until you meet a number that opens something else: the count and the link have to be derived from the same question, or the card is quietly lying about what it is offering you.

A badge on the Chain of Custody tab counts two things together: checks that ran and failed, and holds within thirty days of their stated expiry — including any already past it. Not every hold, which is why the badge usually reads lower than the On Legal Hold card: a hold with years left to run is not something to chase this week, and a lapsed one is. The Evidence Freshness row in the sidebar carries a badge too, but it is the hub’s total — Chain of Custody’s count plus every other tab’s — so expect it to read higher than the tab’s own. Neither badge narrows the register, and that is deliberate: they count two different problems, and a filter that picked one of them would send half its readers to an empty page.

Neither is a control you can see, so both announce themselves the same way — a removable chip above the register, naming whose holdings you are looking at, or which integrity state you are seeing: failed checks, or the verified and the attested sets that the two cards beside that one open. A filter you cannot see is indistinguishable from missing data, and a register that appears to have lost most of its rows is alarming in a way a filtered one is not. That is most true of the integrity filter, because the reader who arrives on it followed an alarm to get there.

The register filtered to a single custodian, with a removable chip above the table naming them

The chain itself

A chain detail page's panel grid: the evidence description, current custodian, status, retention and integrity panels side by side

The Detail tab answers four questions in one screen: what this is, who has it now, what state it is in, and what has happened to it. A single chain has its own address, so you can send somebody straight to it rather than to the register with instructions to go and find it — which is also how the notification works when custody is transferred to you. The last of the four is the timeline.

The custody event timeline showing collection, access and transfer entries with actor names and timestamps

Ten kinds of event go into the record: collection, access, transfer, integrity check and disposal, a legal hold or a retention requirement being placed and being lifted, and a correction to the record’s own details. Every one carries who did it and when, and the ones where it matters most — transfers, access, disposal, corrections — carry why. So putting a chain on hold is itself part of its history, not a quiet change to a field somewhere.

That last kind deserves a word, because it is the one that sounds wrong. A custody record whose description can be edited sounds weaker than one that cannot. It is the opposite. What a chain fixes in place is the evidence, the hashes, the custodians and the timeline — none of which a correction touches. What it does not fix is how somebody first described the thing, and a register that cannot correct a mistyped name or apply a tagging convention adopted later does not stay accurate; it gets a second chain opened for the same evidence, which is the one outcome a custody register cannot survive. So a correction is allowed, it records the previous values inside what gets signed, and it appears in the timeline like everything else.

Each event is signed. Talarity computes an HMAC-SHA256 over a canonical form of the event — keys sorted recursively, so field ordering cannot change the result — using a key held in managed secret storage — never in the code or the database — and compares it later in constant time. If the key is missing, signing fails closed rather than falling back to something predictable: a signature anyone could forge is worse than no signature, because it looks like protection.

Each event also names the one before it, by hash, inside what gets signed — which is the part that makes a chain a chain rather than a pile of signed receipts. The distinction matters more than it first appears. Per-event signatures catch an edit: change a timestamp, a reason or an actor and the recomputed signature stops matching. On their own they catch nothing else, because the useful tampering is not editing an event — it is removing one. Delete the hour somebody had the file and would rather not account for, and every surviving signature is still perfectly valid.

Because each event carries its predecessor’s hash and its own chain’s identity, three moves that would otherwise leave no trace are all detectable: deleting an event, reordering the timeline so the transfer appears to precede the access, and transplanting a genuinely signed event from a different chain.

There is a fourth, and it is the one the other three cannot catch. Linking each event to the one before it finds a deletion from the middle or the front, because whichever event survives on the far side names a predecessor that is no longer there. It cannot find a deletion from the end — nothing downstream is left to notice, and the end is exactly where the interesting event usually is, being the one that records what just happened. So the chain separately records the hash of its own last event, stored outside the timeline rather than in it. Truncate the timeline and the two stop agreeing. A chain written before that record existed says so and is treated as predating the check, never as evidence of tampering — accusing every older chain would be a worse failure than the gap it describes.

One honest limit, and it applies to both the signatures and the links: events written before either existed cannot be retro-fitted with them, because doing so would mean re-signing history — and a custody system that rewrites its own history so the history verifies is not a custody system. A check counts those events separately and gives the reason, rather than quietly counting them as either intact or broken. The same applies to a correction in the signing itself, which happened in August 2026: signatures written under the earlier scheme cannot be recomputed under the new one, so a check on a chain older than that reports those events as predating a correction to the signature format, rather than re-signing them into agreement. If your programme predates this, the honest reading of an older chain is that its record is what it always was: trustworthy to the degree its keeper was, which is precisely the position this feature exists to improve on from here.

Handing it over

The transfer custody dialog with new custodian, reason and transfer-method fields

A transfer names the person receiving the evidence, the reason, and how it is being handed over. If the email matches somebody in your organisation, the chain records the actual user and notifies them — a custody transfer the recipient never hears about is a transfer that has not really happened. If it does not match, the chain records an external custodian rather than silently inventing an internal one.

Both are legitimate. Evidence does leave for outside counsel and for an external auditor. What matters is that the record says which of the two occurred.

Looking at evidence is also an event.

The record access dialog capturing purpose and access method

Recording access is what turns a custody chain from a delivery receipt into a usable audit record. “Nobody else opened it” is only ever provable if opening it leaves a mark.

The dialog asks for the purpose and how the evidence was accessed. It also offers an optional Location — the office or site you were at — and labels it as recorded on your word, because it is. What it never asks for is your IP address or your browser: those are observed by the platform and signed into the event with everything else. A value the person being recorded gets to choose has no business masquerading as one the system witnessed. It is a small distinction and it is the difference between a log and evidence about the log.

Checking the bytes

The Verify Integrity dialog on the change advisory board minutes chain, showing the hash recorded at collection, an empty hash field, and the hint stating both cases: ignored where Talarity holds the file, required where it does not

The dialog asks for the hash you are checking against, and whether you need to fill it in depends on who is holding the file — so its hint states both cases rather than assuming one. Where Talarity has the bytes, it re-reads and re-hashes them itself and anchors the verdict to that; anything you type is ignored. Where the evidence lives somewhere else, your hash is the only thing there is to compare against, and the check refuses without it — naming that as the reason rather than simply failing. The chain above is the second kind, which is what the empty field’s own label is telling you: required, because these are bytes Talarity has never seen. The panel below is where a result lands.

The Integrity panel for the change advisory board minutes chain, reporting all three checks separately — Timeline Links intact, the hash you supplied matching what was recorded at collection, and Event Signatures verifying — above both hashes and a Last Checked line reading "attested" rather than "verified"

Running a check then does three things at once and reports one answer. It compares the file hash, it re-verifies every event signature it can, and it walks the links between those events. The chain is intact only if all three hold.

That combination is the point. A tampered timeline over intact bytes is not integrity — the file is fine and the story about it has been rewritten, which in a dispute is the more useful thing to falsify. A verdict that ignored the timeline would report that chain as verified.

The check also records how it reached its answer, which is what fills in Verified versus Attested above. Where Talarity holds the bytes it re-reads them; where it does not, it says so instead of implying otherwise.

You do not have to remember to do this. Talarity re-checks chains on a schedule: chains nobody has checked, and chains whose last verdict has gone stale, are re-verified without being asked, oldest verdict first. The nightly run takes up to twenty-five chains per organisation, which is a deliberate ceiling rather than an oversight — a job that re-hashed an unbounded number of files would be a nightly load nobody sized. It also means the largest register the schedule can keep current is twenty-five times your cadence in days: two thousand two hundred and fifty chains at the default. That figure assumes the run reaches you every night, which it does until the platform is sweeping more than fifty organisations; past that it rotates, each organisation is visited every few nights, and the sustainable figure divides by the same factor. Past either limit the run says so in its logs — naming the rotation where it applies — rather than quietly falling behind. By default a verdict stands for ninety days before it is re-earned, which is roughly how often an auditor asks and keeps a year of evidence to four checks rather than three hundred and sixty-five. If your regulator expects substantiation more often than that, the interval is yours to set in organisation settings — anything from a week to a year. A default is a starting position, not a house view about your obligations.

This is the part that makes the register worth having rather than worth remembering. A custody record whose assurance depends on somebody opening the page is only as current as the last time they did, and the honest state of most registers under that arrangement is “we have not looked”. The scheduled check is also why the sidebar count below can appear at all: something has to run for a failure to be found.

Which is why the register prints not just the verdict but when it was earned — “checked 3 days ago” beneath the state, and overdue against your own cadence when the schedule has not managed to re-earn it. A verdict with no date on it reads as a current measurement however old it is, and at the register sizes above — where the run can no longer reach every chain — that is precisely when a number stops being one. “Verified” and “verified, four hundred days ago” are different claims, and a register that renders them identically is answering a question nobody asked.

Finding it is only half the job, so a failed check is not left sitting on a screen waiting to be noticed. The recorded custodian is told, and so are the people your organisation has named to receive compliance notifications — or your administrators, if you have not named anyone. The message says which of the three things failed rather than “integrity check failed”, because the stored hash no longer matching the file, an event no longer verifying, and a gap in the timeline are three different problems with three different explanations, and it links straight to the chain rather than to the register to go and find it.

Two limits, stated plainly. A chain whose bytes live somewhere else cannot be re-hashed by a schedule, because nobody is there to supply the copy being checked. And a chain that recorded no hash at collection has nothing to compare against — the hash field is optional when you open one by hand, and a chain opened without it can never be verified automatically, only re-collected. Both stay as they were: reported as not checked, which is true, rather than quietly counted as passing. Neither is left circling the queue either, and the two are set aside by different means. A chain with no recorded hash can never become checkable on its own, so it is excluded from the backlog outright. A chain whose bytes live elsewhere might become checkable the moment somebody uploads them, so it is not excluded permanently: the refusal is stamped as an attempt, which takes it out of the running for one cadence and then offers it again. What neither does is what both used to — sort to the head of the list every night, get skipped, and take a slot from a chain that could actually have been checked. The stamp records an attempt and never a check: a chain that was refused is still reported as not checked, because that is what it is.

Holds

Evidence under legal hold cannot be disposed of. The hold form records who authorised it and when it expires, alongside the case reference.

The legal hold dialog with case reference, the authorising role, and an expiry date whose hint states it is recorded on the chain and does not lift the hold

Authorised-by and expiry are not decoration. A hold with no named authority is one nobody can lift with confidence, and a hold with no expiry is one that quietly becomes permanent. Both are recorded on the chain, where the next person to look will see them.

Be clear about what the expiry does, because the form is: it is a date recorded on the chain, not a timer. Nothing lifts a hold automatically — releasing one is a deliberate act that requires an organisation administrator, which is the point. The date is what puts the hold in front of somebody before it lapses: the register can be filtered to holds expiring within thirty days, and the same thirty-day horizon feeds the attention badge.

That badge counts a union rather than a single set, and the choice is worth understanding, because it is the difference between a number that pulls you somewhere useful and one you learn to ignore. It counts every chain that is either inside that thirty-day hold window or has failed an integrity check — two unrelated conditions sharing one remedy: go and look at the register. A chain in both states is one thing to go and look at, so it is counted once.

The window is open at the bottom, and that is deliberate. Because nothing lifts a hold automatically, a hold whose date has already gone by is still in force, and it is the one nobody has looked at; dropping it once the date passed would quietly retire the most overdue case at the moment it became overdue. So the badge says expiring within 30 days, including any already past — both ends, because a sentence naming only one of them sends the reader hunting for something that is not there. Chains that have never been checked are deliberately left out. That is work not yet done rather than an alarm, and counting it would make the badge permanently non-zero and therefore invisible.

The consequence is that the badge cannot hand you a filtered register, because a filter can only narrow by and, and this number means or. So it does the honest thing instead: it states both conditions in words and drops you on the register itself, rather than applying a filter that would show you one half of the count and quietly hide the other.

Placing a protection and removing one are not the same act, and Talarity does not treat them as one. Anyone who can manage custody can place a hold or set a retention date — making evidence harder to destroy should never be the guarded direction. Releasing a hold, clearing a retention requirement, or bringing a retention date forward all require an organisation administrator. That third one matters more than it reads: setting retention to next month is the same removal spread over two days, and it wears the protective verb. A custodian can extend; only an administrator can shorten.

Here is how that reads on a chain already carrying one — a different record, the vendor breach notification thread, so you can see the fields as the next person finds them rather than as the person who typed them:

The Retention and Legal panel of a chain under hold, showing the case reference, the reason, the authorising role and the expiry date

A hold can also come from the Legal Holds feature, which places it on the evidence record rather than on the chain. Disposal checks for both, and refuses if either is present — a hold that only one surface can see is a hold that will be missed by the other.

There is a third case worth knowing, because it surprises people: a hold protects the evidence, not just the chain you are looking at. If the same artifact carries more than one custody chain and any of them is held, none of them can be disposed of. That is the correct answer — the point of a hold is that the material survives — but it means the chain refusing you may not be the chain holding you. The screen says which of the two situations you are in: a hold recorded in Legal Holds, or one sitting on another custody chain for the same evidence. They are released in different places, and being told the wrong one sends you somewhere with no record of your hold.

It also refuses when it cannot tell. If either lookup fails, disposal stops and says so rather than treating an unanswered question as a clear one. That sounds like a detail and is not: a failed query and “no hold on this evidence” are the same silence, and only one of them is a reason to destroy something irreversibly.

Retention, then disposal

The retention dialog with retain-until date and governing policy fields

Retention records how long the evidence must be kept and under what policy. Disposal before that date is refused.

A disposed chain showing the disposal method, the reason, who performed it and when, and the authority it was carried out under with the name of the witness

Disposal is a recorded act, not a delete. The chain remains, and gains a final event naming the method — secure delete, physical destruction, archival, or transfer out — and the reason, both of which it refuses to proceed without. It also carries the authority the disposal was performed under and the name of a witness; those two are offered rather than compelled, because not every records schedule produces a reference number and not every disposal has a second person present. Where your policy expects them, fill them in: an unwitnessed disposal is not wrong, but it is a weaker record. Both rows always appear on the chain afterwards, reading Not recorded where nothing was given — a stated absence rather than a missing row, so a reader can tell “nobody witnessed this” from “this panel does not mention witnesses”. Be precise about what that method is: it is your attestation of what you did with the evidence, not an action Talarity performs on your behalf. The stored file is deliberately kept, because the chain and its hashes have to remain checkable after the fact — a custody record you can no longer verify is not much of a record. Those last two are the ones an auditor asks for, so they sit on the chain’s own Disposal panel rather than only in the timeline below it. The register keeps disposed chains and counts them separately.

There is no delete button for a chain anywhere in the product, which is deliberate: a custody record that can be quietly removed is not a custody record. For the same reason, an artifact in the library cannot be deleted while an open chain refers to it — on any route that can delete one. It is enforced at eleven of them, and the list is derived rather than remembered: the interactive delete, across every version of the artifact; the file delete, which is where the evidence from a work-task upload actually lives; the vendor routes; the policy and linked-account paths; the housekeeping that clears a pending or superseded file; and the unattended sweeps that expire old evidence overnight. Those last ones matter more than they sound, because they are the routes with nobody watching; a legal hold already blocked them, but an open chain that is merely open had to be taught to. It fails closed at each: if the lookup itself cannot answer, the deletion is refused rather than allowed, since a retry costs a night and the alternative costs the evidence.

Eleven is not a number anybody counted to on purpose. It is what a scan returns, and the scan is the point: a test walks the codebase for anything that both names an evidence store and destroys a row, and every hit must be guarded or carry a written exemption, or it fails. A hand-kept list stays green while somebody adds a twelfth. That is not hypothetical here — the eleventh was found by widening the scan itself, after it turned out to be blind to a deleter that builds its table name at runtime instead of writing it out. A disposed chain does not block, because its record is closed.

Getting it out

There are two exports, because auditors ask two different questions. The register exports to CSV for the question “what is the state of my chains”: custodian name and email, status, retention, hold and case reference, and integrity — one row per chain. A single chain exports its own timeline to CSV for the other question, “what happened to this one, and in what order”: every event, not the twenty-five the page shows, each with its actor, its timestamp, the reason or purpose recorded with it, and whether it carries a signature.

Integrity is not one column but five, because a single verdict is not enough to work from. Alongside the overall result the export carries the verification method — so a reader can tell a server-side recompute from a caller’s attestation without asking — and then the three checks separately: file hash matches, event signatures valid, and timeline links intact. An auditor reading a failure needs to know not just that the story about the bytes is wrong but how: an event that no longer verifies has been altered, and a break in the links means one has been removed. Those are different findings and they send you to different places. Every one of these columns also exports “Not checked”, which nobody should have to guess is different from a check that ran and failed.

The end of a chain travels too. A disposed chain exports when it was disposed of and by whom, the method, the reason, the authority it was carried out under and who witnessed it — and a held chain exports when its hold expires. Those are the questions somebody reads a custody register to answer, and an export that could show a chain had ended without showing under whose authority would be handing over the weaker half of the record.

Custody also travels with the evidence rather than only beside it, in two places. An evidence package shows, on each file it includes, whether that file is under custody, what state the chain is in and whether its integrity has been checked — with a link straight to the chain. And an evidence bundle, the sealed package you hand to somebody outside the platform, carries each chain as its own custody entry — named for the file it belongs to — beside a time-limited download link for that file. The bundle is a JSON manifest rather than an archive, so what the recipient receives is the record plus the means to fetch the bytes, not a folder of both. A file handed to somebody who was not there is exactly the artifact whose provenance they cannot take on trust, which is the one place it should never have been missing.

What you walk away with

  • A record of who collected each piece of evidence, and who has held it since
  • Signed events, so an altered history is detectable rather than merely unlikely
  • An honest difference between evidence Talarity has checked and evidence it has been told about
  • Disposal that cannot happen under a hold or before a retention date, whichever surface set it
  • A count on the nav that brings you back when a check fails or a hold is about to lapse
  • A check that runs on your cadence without being asked, and tells the custodian when it fails
  • Custody that travels with the evidence into the package an auditor is handed
  • An answer to “is this the same file?” that does not begin with “we think so”
Loading…

Keep reading

See Talarity in action.

A 30-minute walkthrough or a 7-day trial — your call.