Change evidence report
Merged changes
Northwind (sample data) · 2 repositories · protected branches · 15 Jul to 13 Oct 2026
- Prepared for
- [Auditor firm]
- Repositories
- northwind/payments-api · northwind/ledger-service
- Changes in scope
- 146 pull requests merged into protected branches and 2 direct pushes, captured from GitHub as they happened.
- Records
- 4,152 sealed records: change records, control-change events and code checks. Signatures verified at generation.
- Engine and rule sets
- toevan-engine 0.9.4 · Clean Architecture 1.4.0 · Security Essentials 2.14.0
- People
- Shown as digests of their GitHub accounts in sealed records. Waivers name their requester and approver.
- Generated
- 13 Oct 2026, 11:42 UTC by [name]
- Report hash
- sha256:3f9a…c21e
This report is evidence for the auditor to assess. Toevan does not express an opinion on whether controls are designed or operating effectively. Every fact states how it was obtained. Controls outside Toevan’s coverage are listed in the scope section and remain the organisation’s responsibility.
1. Summary
Process evidence · how changes got in
Code evidence · what the changes do
What was captured
Toevan captured the merges into protected branches, the changes to review rules, the bypasses and the direct pushes in both repositories as GitHub reported them, and sealed each one as it happened. In the period, 146 pull requests were merged and 2 commits were pushed directly. Reported + sealed
Items for attention
- Two direct pushes to payments-api/release/v1 on 19 Sep, inside a 29-minute window when the review requirement was switched off.Process
- Three pull requests merged without approval by someone other than the author: two in ledger-service before its review rule existed, one by admin bypass during the 19 Sep window.Process
- Rule secret-detection-high fails in production code (1 finding), covered by an approved waiver until 20 Dec.Code, Waivers
2. Scope, provenance and control mapping
How each fact was obtained
- Recomputed
- Toevan computed it from the code or git history itself.
- Re-perform it from the same inputs and get the same result.
- Reported + sealed
- GitHub reported it; Toevan captured it at the event and signed it.
- Rely on it as far as you rely on GitHub. Any later change is detectable.
- Declared + sealed
- The organisation declared it, such as a change to what is checked; Toevan signed the declaration and its history.
- See who declared what, when, and every later change.
- Toevan record, not sealed
- Held in Toevan’s database but not sealed in the ledger, such as a waiver today. Nothing protects it by a signature.
- Treat it as Toevan’s statement, and ask the organisation for the approval behind it.
- Consumed
- Taken from another system’s signed record, such as build provenance, and linked by commit or digest. Planned.
- Check the original record independently.
- Not captured
- No reliable source was available. Toevan does not infer it.
- Obtain it from the organisation by other means.
Evidence and the controls it relates to
| Evidence | Relevant controls | Obtained |
|---|---|---|
| Approval, independent review, approval on final commit | DORA RTS 2024/1774 Art. 17 (planned) · SOC 2 CC8.1 · ISO 27001 A.8.32 | |
| Required checks at merge; review rules in force; rule changes and bypasses | DORA RTS 2024/1774 Art. 17 (planned) · SOC 2 CC8.1 · ISO 27001 A.8.32 | |
| Direct pushes to protected branches | SOC 2 CC8.1 · ISO 27001 A.8.4, A.8.32 | |
| Code rules: architecture boundaries, secure coding, dependencies | ISO 27001 A.8.25, A.8.28 · SOC 2 CC8.1 | |
| Waivers and scope changes | Exceptions to the rules above |
Not covered by this report
- Access reviews, joiner and leaver processesOrganisational
- Runtime monitoring, incident responseOrganisational
- ICT third-party risk, physical securityOrganisational
- Deployments made outside GitHubOrganisational
- Changes made outside GitHub, such as direct database or console changesOrganisational
3. Process evidence
How the 146 pull requests merged in the period were reviewed and merged, captured from GitHub at the moment of each merge.
| Check | Result | Obtained |
|---|---|---|
| Approved by someone other than the author | 143 / 146 · 3 deviations | |
| Approval given on the final commit | 137 / 143 approved · 6 approved an earlier commit | |
| Required checks passed at merge | 146 / 146 | |
| Commit signatures verified by GitHub | 144 / 146 | |
| Review rules in force recorded at merge | 146 / 146 |
Deviations: merged without independent approval
| PR | Merged | Author | Rule in force at merge | Record |
|---|---|---|---|---|
| ledger-service #388 | 24 Jul | 4be1…09c2 | None (rule added 02 Aug) | rec_51b9e20 |
| ledger-service #391 | 29 Jul | c58f…71d0 | None (rule added 02 Aug) | rec_6e07a3d |
| payments-api #1903 | 19 Sep 14:12 | 2a6e…f915 | Switched off 14:02 to 14:31 (admin) | rec_0c88f14 |
Changes to the controls themselves
| When (UTC) | Change | By | Record |
|---|---|---|---|
| 02 Aug 09:14 | Review rule applied to ledger-service: 2 approvals, required checks | 9d07…e3a4 | rec_8a2f61c |
| 19 Sep 14:02 | Review requirement switched off on payments-api/release/* | 2a6e…f915 | rec_3f10b9a |
| 19 Sep 14:31 | Review requirement switched back on | 2a6e…f915 | rec_3f10c02 |
Direct pushes without a pull request
| When (UTC) | Branch | Commit | By | Record |
|---|---|---|---|---|
| 19 Sep 14:09 | payments-api/release/v1 | 7c1e0a2 | 2a6e…f915 | rec_7c1e0a2 |
| 19 Sep 14:22 | payments-api/release/v1 | 91d4b3f | 2a6e…f915 | rec_91d4b3f |
Control changes and direct pushes are captured as events when they happen, so a gap between snapshots can’t go unseen. People are shown as digests of their GitHub accounts; independence is computed from the account ids. Reported + sealed
4. Code evidence
What the code does, checked by reading the code itself on the exact merged version. Rules marked failing apply to production code; documentation and test fixtures are out of scope (see Waivers).
Clean Architecture 1.4.0 · design rules
| Rule | What it checks | Latest release | Findings |
|---|---|---|---|
| layer-dependency-handlers-to-db | Request handlers never call the database directly | Passing | 0 |
| service-boundaries | Services reach each other only through their public interfaces | Passing | 0 |
| role-placement-policy | Abstractions and their implementations sit in the layers the architecture assigns | Passing | 0 |
| layer-dependency-policy | A cross-layer dependency is allowed only where the policy lists it | Passing | 0 |
Security Essentials 2.14.0 · secure coding
| Rule | What it checks | Latest release | Findings |
|---|---|---|---|
| secret-detection-high | No high-confidence credential hardcoded in source or config | Failing | 1 · waiver |
| no-committed-secret-files | No .env, private key or keystore committed | Passing | 0 |
| vulnerable-dependency | No dependency with a known high or critical vulnerability (OSV.dev) | Passing | 0 |
| encryption-at-rest | Storage and database connections encrypted | Passing | 0 |
| iac-network-segmentation | No public exposure of internal services | Passing | 0 |
| iac-encryption-policy | Storage encryption toggles enabled in infrastructure code | Passing | 0 |
| iac-access-control | No wildcard access policies | Passing | 0 |
| sensitive-unsafe-log-flow | Sensitive data does not reach logging sinks | Passing | 0 |
How far the analysis reached
| Repository | Coverage on latest release | Gate | Runs below gate in period |
|---|---|---|---|
| payments-api | 97.9% | 95% | 0 |
| ledger-service | 96.6% | 95% | 0 |
Coverage is the share of the repository’s production source files that the code index parsed at the indexed commit. Below the gate, a run is flagged rather than recorded as passing. Engine and rule-set versions are recorded in every record, so any result can be re-run. Recomputed
5. Waivers and scope changes
Every decision that changed what was checked, or accepted a known deviation.
| Date | Change | Requested · approved | Reason | Record |
|---|---|---|---|---|
| 20 Sep | Waiver: secret-detection-high, payments-api/config/sandbox.yaml (exact file), expires 20 Dec | c58f…71d0 · 4be1…09c2 | Sandbox key with no production access; rotation scheduled | rec_b30e7c5 |
No waivers expired or were revoked in the period. Requester and approver are different accounts for every entry. Waivers are Toevan records that are not sealed in the ledger. Toevan record, not sealed
Rule-set versions used in the period
| Rule set | Version | From | Change |
|---|---|---|---|
| Clean Architecture | 1.4.0 | 15 Jul (whole period) | No change |
| Security Essentials | 2.13.0 | 15 Jul | No change |
| Security Essentials | 2.14.0 | 12 Aug | Rules updated by Toevan |
6. Change records
One change in full, as the auditor sees it when sampling. All records are in the CSV export, and each signed envelope is on the evidence branch in the organisation’s repository.
rec_5b81d4eThe change
- Pull request
- payments-api #1921 · Add tenant check to refund handler
- Reported + sealed
- Author · merged by
- 4be1…09c2 · 9d07…e3a4 · 13 Oct 2026, 10:41 UTC into main
- Reported + sealed
- Merge commit
- 5b81d4e
- Reported + sealed
- Deployed to production
- 13 Oct 2026, 11:20 UTC · production (GitHub’s flag) · rec_9e41b07
- Reported + sealed
Process evidence
- Approvals
- 9d07…e3a4, c58f…71d0 · both on final commit e81b2d0
- Reported + sealed
- Independent of author
- Yes, by GitHub account id
- Recomputed
- Required checks
- ci/test ✓ · ci/lint ✓ · toevan/gate ✓
- Reported + sealed
- Rules in force
- main-protection: 2 approvals, required checks, signed commits
- Reported + sealed
- Commit signature
- Verified by GitHub
- Reported + sealed
Code evidence
- Design rules
- 4 / 4 passing
- Recomputed
- Secure coding
- 7 / 8 passing · secret-detection-high under waiver rec_b30e7c5
- Recomputed
- Coverage · engine
- 98.1% (gate 95%) · toevan-engine 0.9.4
- Recomputed
Path to productionPlanned
- Copied to release
- Matched to the reviewed original by content
- Recomputed
Seal
- Signature
- ECDSA P-256 · DSSE envelope · keyid 8c1f…e0a2
- Previous record
- rec_b7e21f0
- Public anchor
- Sigstore’s public Rekor log · built in, opt-in per organisation
Further records (sample)
| Record | Change | Independent approval | Code rules | Sealed (UTC) |
|---|---|---|---|---|
| rec_b7e21f0 | payments-api #1918 | Yes | 11 / 12 · waiver | 13 Oct 09:58 |
| rec_9d41e02 | ledger-service #412 | Yes | 12 / 12 | 09 Oct 16:21 |
| rec_0c88f14 | payments-api #1903 | No · admin bypass | 12 / 12 | 19 Sep 14:12 |
| rec_7c1e0a2 | direct push 7c1e0a2 | No · no PR | 12 / 12 | 19 Sep 14:09 |
7. How to check this report
You don’t need to trust Toevan or the organisation. Choose the route that fits your role. Only the third needs any tools.
| Check | What it proves | What it doesn’t prove |
|---|---|---|
| Record is genuine and unchanged | The record was signed with Toevan’s published key and hasn’t been altered since. The hash chain shows none was removed. | That the facts inside it are correct: the two checks below cover that. |
| Approval was independent | Approver and author are different GitHub accounts, recomputed from the account ids in the record. | That the review itself was adequate. |
| Code result is reproducible | The same commit, engine version and rule-set version give the same result. | That the rules cover every risk in the code. |
In the organisation’s app
Read-only auditor access, no repository access
- The organisation invites you with the Auditor role: read-only access to the evidence list, the exports and the reports.
- Verify now re-checks the whole ledger, the signatures and any transparency log proofs in the app.
- You open nothing else: repositories, code and findings are refused.
Watch the organisation run it
Screen share or on site
- You choose the samples at the time of the session; an engineer runs the checks while you watch.
- Verification of each record you sampled: chain, signature, unchanged.
- Author and approver accounts for each sample, compared on screen.
Run it yourself
IT audit specialists with temporary read access
- Use git, openssl and the toevan command, which Toevan provides on request. No Toevan account is needed.
- Check that a copy’s branch tips match the tips recorded in the report.
- Run the commands in the appendix and compare against the report.
8. Planned additionsPlanned
Later layers of the evidence chain. They are not in v1.4.0 and nothing in this report depends on them. Each says how its facts will be obtained.
Designated production branches (v1.4.1)
Branches the organisation designates as production, such as a release branch, each designation declared and sealed with every later change. Each gets the same population as the default branch: every commit listed straight from git and matched to a record or flagged.
Copied fixes matched by content
A fix reviewed on main and copied to a release branch gets a new commit ID. Toevan will match it to the reviewed original by content (git patch-id), and flag copies whose content changed.
Appendix · Commands for technical reviewers
The commands an engineer runs for you, or you run yourself.
Check that a record is genuine and unchanged
$ openssl dgst -sha256 -verify toevan.pub \
-signature sig.der \
pae.bin
Verified OK
$ toevan audit verify --path evidence-clone --pub-key toevan.pub
✓ chain intact · 4,152 records
✓ signatures verify under the published keyThe two files come out of the record’s DSSE envelope through the sed and printf lines printed on the evidence branch: the signature, and the exact bytes that were signed. Expect “Verified OK” for every record you check. Any failure means the record was altered or not signed with the published key.