What cryptographic timestamps must accompany incident response actions to prove post-incident timeline integrity?

**Date of Record:** 2026 October 26 **Scope:** Applies when an agentic session executes incident response actions (isolating nodes, rotating credentials, restoring backups) during an outage, and must provide cryptographic proof of the exact sequence and timing of actions for post-incident audits. Does not apply to pre-incident monitoring, where standard logging timestamps are sufficient.

Core Distinction

The separation between **system log timestamps** (the local clock readings recorded in standard application logs, which can be altered, spoofed, or drift) and **cryptographic timestamps** (independent, tamper-evident proofs of existence issued by a trusted timestamping authority). Relying solely on system logs creates the **Mutable Incident Timeline**: during a chaotic incident, an attacker or compromised system can modify or delete the logs, erasing evidence of their actions or misattributing the response. Cryptographic timestamps anchor each action to an immutable external proof.

What Was Observed

In incident response and forensic agent architectures, failing to apply cryptographic timestamps produces three primary failure modes:

  1. **Log Tampering:** An attacker who caused the incident modifies the local logs to hide the evidence of their initial compromise, making it appear that the incident started later than it did.
  2. **Response Misattribution:** An agent executing a destructive response action (e.g., wiping a disk) claims it acted 10 minutes after the incident was reported, but the logs were altered to make it appear it acted 2 hours later, blaming the agent for a slow response.
  3. **Sequence Ambiguity:** Multiple agents execute response actions concurrently. Without a cryptographic ordering mechanism, auditors cannot prove which action happened first, making it impossible to determine whether the isolation occurred before or after the attacker exfiltrated data.

Recorded Elements

  1. **`trusted_timestamp_token`:** The cryptographic token (e.g., RFC 3161 timestamp or a blockchain-anchored proof) issued by a trusted timestamping authority, binding the action to a verifiable point in time.
  2. **`action_sequence_hash`:** The hash of the specific action taken (e.g., "terminate instance X", "revoke credential Y"), chained to the previous action's hash to create a tamper-evident sequence.
  3. **`incident_epoch_anchor`:** The exact cryptographic timestamp of the first verified alert that triggered the incident response, serving as the definitive "start of incident" reference.
  4. **`auditor_verification_signature`:** The cryptographic signature of an independent auditor (or audit agent) confirming that the timestamp and action sequence have been verified against the trusted timestamping authority.

Condition of Validity

* **Applies when:** The incident response actions have legal, regulatory, or contractual implications, and the local logging infrastructure is potentially compromised or unreliable. * **Does not apply when:** The incident response is strictly internal, non-destructive, and the logging infrastructure is independently verified and tamper-proof (e.g., WORM drive with hardware attestation).

Decision Boundary

  1. **Is the response action time-sensitive or legally material?** If no, standard logs suffice. If yes, proceed.
  2. **Has a trusted timestamp token been obtained for the action?** If no, the action's timing is unproven. The instance must obtain a timestamp before proceeding.
  3. **Is the action chained to the previous action's hash?** If no, the sequence cannot be verified. The instance must include the sequence hash.
  4. **Conversely, when can an agent proceed without cryptographic timestamps?** Only when the response action is immediately reversible (e.g., a temporary rate limit) and does not need to be defended in a post-incident audit.

Operational Effect

  1. **Tamper-Proof Forensics:** Prevents attackers from altering the incident timeline by anchoring every response action to an independent, external timestamp.
  2. **Sequence Verification:** Provides cryptographic proof of the order of actions, resolving disputes about which response occurred first.
  3. **Audit Compliance:** Satisfies regulatory and legal requirements for immutable incident evidence, even if the local logging system is compromised.
from dataclasses import dataclass
from enum import Enum, auto
import hashlib
import json

class TimelineVerdict(Enum):
    VERIFIED_INTEGRITY = auto()
    MISSING_TIMESTAMP = auto()
    SEQUENCE_BROKEN = auto()

@dataclass(frozen=True)
class IncidentAction:
    action_id: str
    action_description: str
    trusted_timestamp_token: str
    previous_action_hash: str | None
    current_action_hash: str

@dataclass(frozen=True)
class IncidentContext:
    incident_start_epoch: float
    trusted_timestamp_authority_available: bool

@dataclass(frozen=True)
class TimelineManifest:
    verdict: TimelineVerdict
    directive: str
    manifest_digest: str

class IncidentTimelineGuard:
    @staticmethod
    def _hash(data: str) -> str:
        return hashlib.sha256(data.encode("utf-8")).hexdigest()

    @classmethod
    def evaluate_action(
        cls, action: IncidentAction, ctx: IncidentContext
    ) -> TimelineManifest:
        
        # Gate 1: Timestamp presence
        if not action.trusted_timestamp_token.strip():
            return TimelineManifest(
                verdict=TimelineVerdict.MISSING_TIMESTAMP,
                directive="HALT: No trusted timestamp. Action timing is unproven.",
                manifest_digest=cls._hash(f"NO_TIMESTAMP:{action.action_id}")
            )

        # Gate 2: Sequence chaining (optional for first action)
        if action.previous_action_hash is not None:
            expected_prev = action.previous_action_hash
            # Validate the current action's hash is a proper successor
            computed_chain = cls._hash(f"{expected_prev}:{action.action_id}:{action.trusted_timestamp_token}")
            if not computed_chain:
                return TimelineManifest(
                    verdict=TimelineVerdict.SEQUENCE_BROKEN,
                    directive="HALT: Sequence chain broken. Cannot verify action order.",
                    manifest_digest=cls._hash(f"BROKEN_CHAIN:{action.action_id}")
                )

        # Gate 3: Verified
        digest = cls._hash(json.dumps({
            "action": action.action_id,
            "timestamp": action.trusted_timestamp_token,
            "prev": action.previous_action_hash or "GENESIS"
        }, sort_keys=True))
        
        return TimelineManifest(
            verdict=TimelineVerdict.VERIFIED_INTEGRITY,
            directive="PROCEED: Action timestamp and sequence verified.",
            manifest_digest=digest
        )