Which questions does 'we retain logs' leave unanswered?
An investigation needs more than the existence of a retained file. A reviewer may need to establish its source, detect content changes, identify missing records and understand the actual interval covered. These are distinct properties. Restricting filesystem access reduces the opportunity for changes but does not cryptographically establish what a past administrator did. Begin by describing the claim the system is intended to support and where the evidence for that claim is produced, stored and independently checked.
Our illustrative threat model assumes an actor can rewrite archive files after collection but cannot change a previously trusted checkpoint held elsewhere. A compromised source can still generate false events; signing them cannot prove the real-world action occurred. Compromise of the signing key creates another failure class. Without these boundaries, 'immutable logs' becomes an overly broad promise. The mechanisms discussed here are a design analysis, not a disclosure of Batur's internal implementation or a claim that one mechanism solves all evidence problems.
What must be defined before signing records?
Define source identity, event identity or sequence, source time, acceptance time, schema revision and the relationship to original payload bytes. Parsed fields make searching easier but should remain traceable to their source. An adapter that removes empty fields or converts a number to a string changes the bytes that could be signed. Document the representation being protected, transformations performed and how a search result relates to the original. Mark derived attributes so they are not confused with statements made by the source system.
JSON property ordering, whitespace and number representation can produce different bytes for equivalent data. RFC 8785 defines a JSON canonicalization approach. The small example below deliberately does not claim to implement it: the example uses fixed-position arrays of strings and verifies them with the same JavaScript encoding. Cross-language production implementations need agreed canonical representation and interoperability test vectors. OpenTelemetry's data model is an additional reference for separating source event time from observation time; neither timestamp should be silently substituted for the other.
Section references: RFC 8785 — JSON Canonicalization Scheme ↗OpenTelemetry — Logs Data Model ↗
Which changes can a hash chain expose?
A standalone file digest helps only if a trustworthy comparison value exists. A chain also incorporates the previous digest into each step. Our illustrative construction hashes a domain marker, fixed-width index, previous digest, fixed-width payload length and payload bytes. Fixed widths make the field boundaries unambiguous; the initial digest and encoding version are defined as well. Changing an event changes the resulting chain root. Verification compares that result against a trusted endpoint rather than trusting a root stored beside an equally editable archive.
Someone who can rewrite both an archive and its adjacent root can recompute an internally consistent chain. A truncated prefix can also be internally valid when later records have disappeared. An external checkpoint should therefore bind the root to a record count and interval or batch identity. Detecting an entirely missing interval additionally requires an inventory of expected intervals. Cryptographic consistency cannot independently discover an event that the source should have produced but never emitted; completeness needs separate operational evidence.
How can edits, deletion and reordering be tested?
The standalone Node.js example requires no additional packages. It creates a root for three events and checks that a payload edit, truncated list and reordered list fail verification against a checkpoint. Creating that checkpoint in the same process is a demonstration convenience, not a secure trust arrangement. A real verifier must obtain its trusted checkpoint through an independently protected channel. The code does not implement digital signatures, key custody or a standards-compliant signed syslog service; those remain separate engineering responsibilities.
Extend the exercise with empty intervals, oversized records, invalid encoding, repeated identities and missing checkpoints. Distinguishable failure categories are more useful to a reviewer than one generic hash-error message. Bound input size and record counts so verification does not require unlimited memory. Large archives can be checked as streams, provided file boundaries remain tied to the signed interval definition. Running the verifier independently of the collector is another useful acceptance condition: a successful producer-side self-check alone offers limited independent assurance.
const { createHash } = require('node:crypto');
const assert = require('node:assert/strict');
const u64 = (n) => {
const b = Buffer.alloc(8);
b.writeBigUInt64BE(BigInt(n));
return b;
};
function root(events) {
let previous = Buffer.alloc(32);
for (const [i, event] of events.entries()) {
const payload = Buffer.from(JSON.stringify(event), 'utf8');
previous = createHash('sha256')
.update('editorial-chain-v1\0')
.update(u64(i)).update(previous)
.update(u64(payload.length)).update(payload).digest();
}
return previous.toString('hex');
}
const events = [
['2026-10-19T10:00:00Z', 'login', 'operator-1'],
['2026-10-19T10:01:00Z', 'read', 'record-7'],
['2026-10-19T10:02:00Z', 'logout', 'operator-1']
];
// Treat this checkpoint as independently trusted input.
const checkpoint = { count: events.length, root: root(events) };
const verify = (rows, c) => rows.length === c.count && root(rows) === c.root;
assert(verify(events, checkpoint));
const changed = structuredClone(events);
changed[1][2] = 'record-9';
assert(!verify(changed, checkpoint));
assert(!verify(events.slice(0, 2), checkpoint));
assert(!verify([events[1], events[0], events[2]], checkpoint));
console.log('Original accepted; edit, truncation and reorder rejected.');What do digital signatures and independent checkpoints add?
A signed checkpoint can bind an interval identity, boundaries, record count, root digest, schema revision and key identity. Explain how the verifier obtains the correct public key from a trusted record. RFC 8032 specifies EdDSA algorithms; citing it does not claim that Batur uses a particular algorithm. Changing the signed representation can invalidate verification. Associate key rotation with archive intervals so historical signatures can be checked with the appropriate key and an understood trust policy.
RFC 5848 provides a separate standards-based approach to signed syslog; the simplified chain here is not a replacement implementation. Evaluate device support, collector architecture and independent verification requirements before choosing an approach. Holding signed checkpoints in a separate administrative domain can make silent archive rewriting harder. It still leaves distinct questions about compromised keys, false source data and intervals never delivered. A date string inside a record does not by itself establish a trusted time of occurrence or an independent timestamping service.
Section references: RFC 5848 — Signed Syslog Messages ↗RFC 8032 — EdDSA ↗
How do integrity, completeness and clock accuracy differ?
Integrity asks whether available data matches its protected representation. Completeness asks whether the expected events or intervals are present. Clock accuracy asks whether the stated time is dependable. Source sequence numbers, heartbeats and interval inventories can expose gaps after a collector outage, but sources do not always provide all these signals. State source-specific evidence quality instead of filling missing fields with assumptions. A report should identify properties it could not verify rather than allowing a successful hash comparison to imply them.
Use the matrix below during acceptance review. Every available hash could be correct while the final hour's archive is missing: verification covers the available portion, while coverage remains incomplete. A chain can also be correctly ordered despite an inaccurate source clock. Review tools should expose these states separately. Distinguish derived verification status from original source attributes so the operator does not mistake a collector's inference for a statement actually made by the originating system.
| Question | Mechanism | Does not independently establish |
|---|---|---|
| Were bytes changed? | Comparison with a trusted root | That the event actually happened |
| Is the interval complete? | Counts, sequences and interval inventory | Events never emitted by the source |
| Is the time accurate? | Clock state and independent timing evidence | Truth of the content |
| Was identity verified? | Signature and trusted key record | That the key was never compromised |
How should log retention capacity be calculated?
For a hypothetical 5,000 events per second averaging 700 bytes of original payload, the raw stream is 3,500,000 bytes per second or 302.4 GB per day. Thirty days requires 9.072 TB; two copies require 18.144 TB of raw payload alone. These are decimal units. Indexes, parsed fields, checkpoints, backups and working headroom are additional. Do not subtract compression until it has been measured on representative sources, and sample peak rates as well as averages so a burst does not silently overrun ingestion capacity.
Define deletion timing for every copy and the retention policy for checkpoints. Keeping a root after deleting its archive cannot reconstruct the underlying events. The existence of backups is likewise insufficient without restore-and-verify exercises. Restore a representative interval and validate it together with historical verification-key records. If source filtering reduces cost, document the excluded event classes and resulting coverage change. Otherwise lower storage use may be misread as evidence of a quieter system rather than a narrower collection policy.
How should a log-integrity solution be tested?
Prepare original records, an expected interval inventory and independently trusted checkpoints. Test one-byte edits, deletion from the middle, truncation, record swaps and relabeling an old interval as a new one. Specify the expected failure for each manipulation. Include combinations such as a valid signature with incomplete interval coverage. This tests whether the verifier recognizes a wrong archive being presented as the right one, rather than merely finding an expected digest inside a convenient file.
Exercise key rotation, missing historical key records, damaged signatures and schema changes. An unknown verification key should produce an unverifiable result rather than being silently treated as an acceptable unsigned archive. Perform manipulation tests on authorized copies, not by damaging real operational records. Keep integrity and coverage outcomes separate, associate findings with archive identities and record the verifier version used. That allows later reviewers to reproduce the finding and assess whether a software update changed the interpretation.
- Tampering, incomplete coverage and unknown keys produce distinct outcomes.
- Checkpoints are obtained through a trust relationship independent of the archive.
- Restored archives are checked again with an independent verifier.
What should a technical review of Batur cover?
Batur is publicly positioned as a selected-customer pilot for log collection, signing and adapter-based analysis. The example chain and checkpoint do not disclose its algorithm choices. Ask which sources are supported, how original records are preserved, exactly which representation is signed and how independent verification works. Base the discussion on demonstrable technical outputs rather than assuming certification, legal evidentiary status or automatic compliance with every requirement. Those conclusions do not follow from adding a signature field to a record.
A useful review package can combine source samples, an archive interval, an interval manifest, verifier output and failure scenarios. Data and observability engineering is relevant to collection health, delay and missing intervals. A useful result identifies the file, interval, key and scope to which its conclusion applies, rather than displaying only a reassuring integrity badge. That evidence package turns a product discussion into testable acceptance work and gives the buyer a practical way to compare proposed implementations.
Technical references
Want to apply this approach to your system?
Discuss your technical requirements →