<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: gentlyding</title>
    <description>The latest articles on DEV Community by gentlyding (@gentlyding).</description>
    <link>https://dev.to/gentlyding</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4110469%2F8f18dbaa-3fd6-401b-85a3-0de9dd7ea150.jpg</url>
      <title>DEV Community: gentlyding</title>
      <link>https://dev.to/gentlyding</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gentlyding"/>
    <language>en</language>
    <item>
      <title>How We Built a Tamper-Evident Audit Log for SOC 2 and ISO 27001 Evidence</title>
      <dc:creator>gentlyding</dc:creator>
      <pubDate>Sat, 05 Sep 2026 01:21:43 +0000</pubDate>
      <link>https://dev.to/gentlyding/how-we-built-a-tamper-evident-audit-log-for-soc-2-and-iso-27001-evidence-jl4</link>
      <guid>https://dev.to/gentlyding/how-we-built-a-tamper-evident-audit-log-for-soc-2-and-iso-27001-evidence-jl4</guid>
      <description>&lt;p&gt;Most teams treat "audit logging" as an afterthought: pipe everything into a SIEM or a big Elastic cluster, then hope the auditor is satisfied. In practice, that's where the pain starts.&lt;/p&gt;

&lt;p&gt;I'm Qin Kang, and I built &lt;strong&gt;Log Audit Platform&lt;/strong&gt; after watching a client burn roughly six engineering-months duct-taping Splunk + spreadsheets together for an ISO 27001 audit. The result was expensive, fragile, and the auditor still asked the one question that sinks most log pipelines:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"How do I know these logs weren't edited after the fact?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This post walks through how we designed an audit log that an auditor can actually trust — without sending your data to a third party.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Why auditors don't trust raw logs
&lt;/h2&gt;

&lt;p&gt;A raw log file is just text. Even if it's shipped to a "secure" bucket, nothing cryptographically ties one line to the next. An attacker (or a well-meaning operator) who gains write access can quietly rewrite history:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Change a &lt;code&gt;DELETE&lt;/code&gt; into a &lt;code&gt;READ&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Backdate an event.&lt;/li&gt;
&lt;li&gt;Remove the record of a privilege escalation entirely.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When an auditor asks "can you prove this wasn't altered?", a raw log answers with &lt;em&gt;trust me&lt;/em&gt;. That's not good enough for SOC 2 (CC7.2 / CC8.1) or ISO 27001 (A.8.15 / A.8.16).&lt;/p&gt;

&lt;p&gt;The fix isn't "more storage". It's &lt;strong&gt;integrity by construction&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. What SOC 2 and ISO 27001 actually want from logging
&lt;/h2&gt;

&lt;p&gt;Stripped of jargon, the control families want three things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Completeness&lt;/strong&gt; — you captured the events that matter (auth, admin actions, config changes, data access).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integrity&lt;/strong&gt; — a record, once written, can't be silently changed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Availability for review&lt;/strong&gt; — an auditor (or your own security team) can independently verify both of the above.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Notice the word &lt;em&gt;independently&lt;/em&gt;. SOC 2 and ISO 27001 auditors don't just take your word for it; they want evidence they can re-run. That's the design goal we optimized for.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Hash-chain design: why a sequential hash works for audit logs
&lt;/h2&gt;

&lt;p&gt;Instead of storing events as isolated rows, every record carries the hash of the &lt;strong&gt;previous&lt;/strong&gt; record's hash chain. Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;record[0].hash = H(payload[0])
record[n].hash = H(payload[n] || record[n-1].hash)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9ksmh7q2svxc4s3yni8x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9ksmh7q2svxc4s3yni8x.png" alt=" " width="799" height="415"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;If an attacker tampers one record, its hash changes and every subsequent link fails verification — the auditor sees exactly where the chain breaks.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Verification walks the chain from the oldest record to the newest. If any payload was altered — even a single character — the recomputed hash at that link no longer matches the stored hash, and every subsequent link breaks too. The verification report marks exactly where the chain was broken.&lt;/p&gt;

&lt;p&gt;Why a simple sequential chain rather than a full Merkle tree? For an audit log, records are append-only and verified in order, so a linear chain is simpler to verify, easier to explain to an auditor, and has no reconstruction complexity. (We're looking at optional RFC 3161 timestamp anchoring as a future external-WORM option, but the in-chain integrity is the core.)&lt;/p&gt;

&lt;p&gt;The practical takeaway: &lt;strong&gt;editing one record is mathematically impossible to hide.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  4. GDPR right-to-erasure without breaking the chain
&lt;/h2&gt;

&lt;p&gt;GDPR's right to erasure (Art. 17) collides with an immutable log: you can't just &lt;code&gt;DELETE FROM audit_log&lt;/code&gt; a user's rows, because that breaks the chain and the audit trail.&lt;/p&gt;

&lt;p&gt;Our approach is &lt;strong&gt;cryptographic erasure / anonymization&lt;/strong&gt;, not physical deletion:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Personal data is stored in a separate, keyed store, referenced by token from the audit record.&lt;/li&gt;
&lt;li&gt;On a valid erasure request, we destroy the key material for that subject. The audit record remains (required for the integrity trail), but the linked identity becomes unrecoverable ciphertext.&lt;/li&gt;
&lt;li&gt;The hash chain stays intact, because we erase &lt;em&gt;the key&lt;/em&gt;, not &lt;em&gt;the log&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This satisfies both sides: the regulator gets erasure; the auditor keeps a verifiable timeline.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Evidence pack automation: turning logs into auditor-ready ZIPs
&lt;/h2&gt;

&lt;p&gt;The second thing auditors hate is &lt;em&gt;hunting&lt;/em&gt;. They don't want your raw database; they want the control mapped to the evidence.&lt;/p&gt;

&lt;p&gt;So we ship &lt;strong&gt;evidence packs&lt;/strong&gt;: pre-built, exportable bundles that map collected events to specific control IDs (e.g. SOC 2 AC-2, ISO 27001 A.8.16). One click produces a ZIP containing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The relevant filtered records.&lt;/li&gt;
&lt;li&gt;A hash-chain verification report (proving the bundle itself is intact).&lt;/li&gt;
&lt;li&gt;A control-to-evidence mapping sheet.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The auditor runs the verification themselves. No spreadsheet gymnastics, no "trust me".&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Self-hosted deployment: one JAR
&lt;/h2&gt;

&lt;p&gt;Compliance data shouldn't leave your perimeter. Log Audit Platform runs &lt;strong&gt;self-hosted&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Backend: Spring Boot 3 + Java 17+&lt;/li&gt;
&lt;li&gt;Frontend: Vue 3 admin UI, embedded in the build&lt;/li&gt;
&lt;li&gt;Storage: PostgreSQL&lt;/li&gt;
&lt;li&gt;Shipping: a single runnable JAR + Docker Compose&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No vendor backend, no telemetry pipe, no API calls home after activation. It runs in your VPC, on-prem, or air-gapped. For teams that can't use a cloud SIEM for regulatory reasons, that's the whole point.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Pricing: one-time license, not a per-seat SaaS tax
&lt;/h2&gt;

&lt;p&gt;SIEM pricing scales with ingest volume and seats — exactly the metrics that go up when you start taking compliance seriously. We priced it as a &lt;strong&gt;one-time license&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Single — $199 (one instance)&lt;/li&gt;
&lt;li&gt;Business — $699 (up to 5)&lt;/li&gt;
&lt;li&gt;Enterprise — $2,499 (full source + white-label + OEM)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Optional annual maintenance for updates. No per-seat tax, no surprise overage bills right before your audit.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;If you're preparing for a SOC 2, ISO 27001, or GDPR audit and want an audit log that auditors can verify independently, take a look:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://logaudit.toolsder.com" rel="noopener noreferrer"&gt;https://logaudit.toolsder.com&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I'd genuinely like feedback from security engineers and compliance folks — what logging controls have been the biggest pain in your audits? What would make you trust a self-hosted log like this one?&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Qin Kang — independent developer, building self-hosted compliance tooling.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>backend</category>
      <category>security</category>
      <category>systemdesign</category>
    </item>
  </channel>
</rss>
