Security logs are most valuable after something has gone wrong. That is also when their trustworthiness matters most.
Imagine an application records failed sign-ins, privilege changes, and administrative actions to a file on the same server that runs the application. The logging is detailed and correctly formatted. But if an attacker gains enough control of that server to edit or delete the file, the investigation may lose the very evidence it was supposed to rely on.
The defensive problem is therefore not only what to log. It is also who can change the logs after they are written. This article explains a practical mental model for log integrity: separate the authority to produce events from the authority to alter retained evidence, move important records across a trust boundary, and design detection and recovery around the failures that still remain.
A log is evidence only under stated assumptions
A log entry is a claim that some component makes about an event:
2026-09-07T15:04:18Z user=842 action=role_change result=successThat record can help answer an incident-response question, but it does not prove its own truth. Its usefulness depends on assumptions about the component that generated it, the path that transported it, the system that stored it, and the people or services allowed to modify it.
A useful model is:
event
|
producer
|
transport
|
retained log
|
investigatorEvery stage is a trust boundary. If the same compromised identity can control the event-producing application and rewrite all retained copies, the investigator has little independent evidence about what happened.
The goal is not to make logs magically unquestionable. The goal is to reduce the set of failures that can erase or rewrite useful history without being noticed.
Start with the threat model
Log-integrity controls are especially useful when you want evidence to survive compromise of an application process, service account, host, or ordinary administrator account.
Suppose a web service runs with permission to append local application logs. If that same service identity can also delete yesterday’s logs from the central store, compromising the application gives an attacker both capabilities:
compromise application
|
+--> perform unauthorized action
|
+--> remove evidence of that actionA stronger design separates those capabilities:
application
|
| send events
v
logging boundary
|
| retain under different permissions
v
protected log storeNow application compromise may still let an attacker generate false events, stop producing new events, or manipulate fields before logging. But it does not automatically grant permission to rewrite records that have already crossed the boundary.
That distinction is the core defensive benefit.
This control does not protect against compromise of the logging system itself, misuse by a logging administrator with broad deletion rights, events that were never generated, or false data emitted by a compromised producer. Those residual risks need separate controls.
Do not let the producer own the retained history
The simplest useful improvement is architectural: important security logs should not exist only in storage controlled by the component they describe.
Local logs still have operational value. They can be fast, convenient for debugging, and available during temporary network failures. The problem is treating the local copy as the only authoritative investigation record.
For security-relevant events, send a copy to a destination with a different security boundary. Depending on the environment, that may be a centralized logging service, a dedicated collector, or another storage system whose write and retention permissions are not inherited from the application host.
The important property is permission separation, not a particular product:
application identity:
may submit events
may not rewrite retained events
may not shorten retention
logging administrator:
manages collection and retention
investigator:
may read required records
does not need application write accessExact roles vary, but avoid giving the event producer broad management authority over the destination merely because it needs to send logs there.
Append-only is a permission model, not a magic property
Teams often describe security logs as “append-only.” That phrase is useful only when it is clear for whom and under which boundary.
A file opened in append mode by an application is not meaningfully append-only if the same operating-system identity can reopen, truncate, rename, or delete it. Likewise, an API that exposes only an ingest operation to applications can still have administrative APIs that delete retained data.
Ask concrete questions instead:
- Can the application identity modify an event after ingestion?
- Can it delete a range of historical events?
- Can it change retention settings?
- Can it disable collection without generating an independent signal?
- Which identities can perform those operations?
Storage features such as retention locks or immutable storage can strengthen the design where the threat model justifies them. They also create operational consequences: mistaken or sensitive data may become difficult to remove, storage costs can increase, and emergency administrative procedures need careful control.
For many systems, a simpler first step is sufficient: centralize security events and deny application identities update and delete authority over the retained copy. Stronger immutability is defense in depth for environments where privileged tampering is a realistic concern.
Protect the path to the log store
Moving logs off the application host creates another boundary: transport.
The producer should authenticate the logging destination, and the logging system should authenticate or otherwise identify authorized producers. Protect the connection against unauthorized modification or disclosure using the security mechanisms appropriate to the transport and platform.
Do not assume that encrypted transport makes the event itself truthful. If the application is already compromised, it can send a fabricated event through a perfectly protected connection. Transport protection answers a different question: whether another party on the path can read or alter the event in transit.
Keep these guarantees separate:
protected transport
-> reduces interception or in-transit modification risk
restricted retained storage
-> reduces post-ingestion tampering risk
trustworthy producer behavior
-> determines whether the event was accurate before submissionA sound design may need all three, but none substitutes for the others.
Plan for logging outages without silently losing evidence
Remote logging introduces availability failures. The destination can be unavailable, the network can fail, or the producer can be unable to authenticate.
There is no universal answer to whether an application should stop processing when security logging fails. Blocking every user request because a log collector is briefly unavailable can create a serious availability problem. Continuing indefinitely while silently dropping high-value audit events can create an investigation gap.
Choose behavior according to the consequence of the operation.
For ordinary events, a bounded local queue or durable buffer may allow the application to continue while preserving events for later delivery. The queue itself needs size limits so an outage cannot consume unbounded disk or memory.
For especially sensitive administrative or financial operations, some systems may decide that inability to produce required audit evidence is serious enough to reject or defer the operation. That is a product and threat-model decision, not a default for every application.
Whichever policy you choose, make failure visible. Monitor delivery failures, queue growth, dropped-event counts, authentication errors, and long gaps from expected producers. A logging system that fails quietly creates false confidence.
Detect missing logs, not only suspicious log entries
Attackers do not need to rewrite retained history if they can stop new history from arriving.
A compromised service might disable its logger, terminate the forwarding agent, block network access to the collector, or alter configuration so high-value events are no longer emitted.
This means monitoring should consider absence as a signal when the system has an expected event pattern.
For example, a production service that normally sends heartbeat or routine operational events every minute can trigger an alert after a meaningful gap. A collector can also track the last successful event from each important producer.
Be careful with interpretation. Missing events can result from normal maintenance, scaling changes, or network partitions. The absence signal helps detect a broken evidence pipeline; it does not prove malicious activity.
Independent telemetry can strengthen detection. Infrastructure monitoring may show that a host is healthy while its security-event stream has stopped, which is more informative than either signal alone.
Limit who can read security logs too
Integrity is the focus here, but confidentiality matters because security logs often contain sensitive context.
Logs may reveal usernames, internal identifiers, IP addresses, resource names, administrative actions, error details, or other operational data. They should not contain passwords, session tokens, private keys, recovery codes, or other authentication secrets merely to make debugging easier.
Apply least privilege to log readers. Developers who need aggregate application diagnostics may not need unrestricted access to authentication or administrative audit records. Investigators may need broader read access during an incident without needing permission to alter retention or ingestion settings.
Separating read, ingest, and administration permissions reduces the damage available from any one compromised account.
Preserve context needed for investigation
Tamper resistance is not useful if the retained events cannot answer basic questions.
Security events should include enough stable context to connect actions across systems. Useful fields depend on the application, but commonly include a timestamp, event type, outcome, stable principal identifier when known, target resource identifier, source or request correlation information, and the component that generated the event.
Avoid relying only on mutable display values such as usernames if a stable internal identifier exists. If a user changes a display name after an event, investigators should still be able to associate the old event with the same principal.
Time also deserves attention. Synchronized clocks make events from different systems easier to order, but timestamps should not be treated as cryptographic proof of sequence. Clock drift, delayed delivery, retries, and buffering can all affect observed order.
Record both event time and ingestion time when that distinction materially helps investigation.
Cryptographic chaining has narrower guarantees than it first appears
Some systems add hashes, message authentication codes, or chained records to make modification detectable. These techniques can be valuable, but their guarantee depends on key management and where verification state is kept.
For example, if every record contains a hash of the previous record, changing an old entry breaks the later chain. But an attacker who controls both the log file and the process that creates the chain may be able to rewrite the file and recompute ordinary unkeyed hashes.
A keyed construction can improve the situation only if the attacker cannot obtain the relevant key or forge the protected verification state. Key rotation, loss, verification tooling, partial log streams, and recovery procedures then become part of the design.
Do not add custom cryptography merely to label a log “tamper-proof.” Prefer established platform capabilities or well-reviewed mechanisms, and state the exact threat they address.
For many applications, moving events promptly to separately administered storage provides a larger practical improvement than designing a custom cryptographic log format.
Test the boundary you intend to rely on
A permission diagram is useful, but verify the real system.
Use a non-production application identity and confirm that it can submit an event but cannot update or delete the retained record. Confirm that it cannot change retention settings or grant itself broader logging permissions.
Then test failure paths. Interrupt delivery and verify that the expected buffer, alert, or fail-closed behavior occurs. Fill a bounded queue in a controlled environment and confirm that the system reports drops rather than hiding them. Disable a test producer and verify that missing-log monitoring reacts as designed.
Also test administrative separation. An account intended only for investigation should not be able to alter ingestion configuration. A deployment identity should not automatically receive logging-administrator privileges unless the architecture genuinely requires them.
These tests turn “centralized logging” from a diagram into a security property you can verify.
Know when stronger immutability is justified
Not every service needs the same log-integrity architecture.
A small, low-impact internal tool may reasonably use centralized logs with separate application and logging permissions. The added complexity of immutable retention may provide little value if the realistic threat does not include privileged deletion from the logging platform.
A system where investigations must survive host compromise, powerful insider access, or destructive administrative actions may justify stronger controls: independently administered storage, tightly restricted deletion, immutable retention periods, redundant destinations, or cryptographic verification designed around protected keys.
Stronger retention also increases operational responsibility. Before making data difficult to delete, decide what belongs in the log, how long it should remain, how access is audited, and how privacy or legal deletion requirements interact with the design.
The right control is the simplest one that preserves the evidence required by your threat model.
Conclusion
Security logging is not complete when an application writes an event. The event must remain useful after the failure or compromise you expect it to help investigate.
Start by separating the event producer from the retained history. Let applications submit important events without automatically granting them permission to rewrite or delete those events. Protect the transport, make delivery failures visible, watch for missing event streams, restrict log readers and administrators, and test the actual permissions rather than trusting architecture diagrams.
If your threat model includes compromise of the logging platform or privileged administrators, add stronger retention or integrity mechanisms deliberately. Whatever design you choose, state its assumptions clearly: logs are valuable evidence when the system preserves them across the failures you actually need to investigate.