8 min read

AI agent activity retention: records investigators trust

Set AI agent activity retention rules that preserve action evidence, limit sensitive data, stop tampering, and support incident investigations.

AI agent activity retention: records investigators trust

AI agents turn a familiar logging problem into an evidence problem. A human may spend an afternoon clicking through an application; an agent can make many external calls while a developer is reading its summary. If the record only says "agent completed task," it cannot answer the questions that arrive after a mistaken deletion, an unexpected production change, or a disputed transfer.

Good retention rules preserve the facts needed to reconstruct an action without building a second, poorly guarded copy of every secret and customer record the agent encountered. That distinction determines what you collect, how long you keep it, who can alter it, and when deletion must stop.

Retention begins with the question an investigator must answer

An activity record earns its storage only when it answers a foreseeable investigation question. Start with the questions, not a default number of days copied from another product.

For an agent that can call an HTTP API or open an SSH session, investigators usually need to establish five things:

  • Which execution identity made the request, and which human or service authorized that run?
  • What capability did it attempt to use, against which destination?
  • What operation did it ask the destination to perform?
  • What was the outcome, including rejection, timeout, partial success, or remote error?
  • Can the team show that the record was not quietly edited after the event?

Those questions separate action evidence from operational noise. A CPU graph may help explain a timeout, but it does not establish whether an agent issued DELETE /customers/42. A prompt transcript may explain why the agent thought a deletion was appropriate, but it does not prove the request reached the remote service.

NIST Special Publication 800-92, Guide to Computer Security Log Management, frames log management as a lifecycle: generate, transmit, store, analyze, and dispose of logs. The useful part of that guidance is not a magic retention duration. It is the insistence that an organization define the purpose of its logs and account for storage, access, and disposal. Agent teams often jump straight to collection because collection is easy. Disposal and access discipline decide whether those records help or hurt later.

Write an investigation statement for each record class. For example: "We retain action outcomes long enough to identify and reconstruct an unauthorized external change after normal detection and triage." That statement forces a useful argument about period and fields. "Keep all agent logs forever" avoids the argument and creates a permanent pile of sensitive material.

A record can support more than one purpose, but name them separately. Security investigation, incident response, customer support, release debugging, billing reconciliation, and compliance may need different facts and different periods. If one low-value debugging use keeps a full payload for years, the retention policy has failed.

An action record needs context, not a transcript

AI agent activity retention depends first on the event schema. Capture the smallest set of facts that lets a competent investigator reconstruct the action and connect it to a session, without retaining credential material or irrelevant content.

I use four layers of information.

  1. Identity and authorization context. Record an immutable event identifier, timestamp with timezone, agent process identifier, executable path or package identity, code-signing authority when the operating system exposes it, session identifier, and the approver or service identity associated with the session. Record the authorization decision and the approval mode used.
  2. Requested action. Record the channel, destination host, port when material, HTTP method and normalized route or SSH command class, credential alias or internal reference, and a safe description of the requested operation.
  3. Observed result. Record success, denial, cancellation, timeout, transport failure, remote status code where applicable, response classification, bytes sent and received if relevant, and a redacted error summary.
  4. Evidence bindings. Record the predecessor hash, current record hash, schema version, and identifiers that link related attempts, retries, and follow-up actions.

The distinction between a destination and a request matters. api.example.internal is a destination. PATCH /v1/users/42 is an action. A log that holds only the host cannot tell a credential inventory lookup from an account disablement. A log that stores only a path may omit the target environment, which is often the difference between a harmless test and an incident.

Normalize before you store. Place variable identifiers in a structured field rather than forcing investigators to parse free text. Record route_template: "/v1/users/{user_id}" beside a protected target_identifier field if the identifier matters. For SSH, distinguish a command submitted by the agent from the remote command after shell expansion if your execution path can observe both. Do not claim certainty you do not have.

A practical JSON record can look like this:

{
  "event_id": "01J8...",
  "occurred_at": "2025-03-08T14:22:31.482Z",
  "session_id": "ses_7f...",
  "actor": {
    "process_id": 18422,
    "signing_authority": "Developer ID Application: Example Developer"
  },
  "authorization": {
    "decision": "approved",
    "mode": "session"
  },
  "action": {
    "channel": "http",
    "destination": "billing.internal:443",
    "operation": "POST /v2/invoices/{invoice_id}/void",
    "credential_ref": "billing-production"
  },
  "outcome": {
    "status": "remote_rejected",
    "http_status": 403,
    "error_class": "authorization"
  },
  "previous_hash": "...",
  "record_hash": "..."
}

That record does not contain the bearer token, an authorization header, or an invoice body. It still tells an investigator that a specific signed process, during a particular approved session, attempted a production void through a named credential reference and received a 403.

Do not hide high-risk fields inside a details blob. Free-form blobs become a dumping ground for prompts, headers, personal data, and error traces. They also make retention impossible to enforce by class. If a field has a reason to exist, give it a name, classification, access group, and disposal rule.

Keep evidence classes for different periods

A single duration for every agent record is simple to explain and usually wrong to operate. Retain compact action evidence longer than rich diagnostic content, because the compact record can establish what happened without multiplying exposure.

Use classes that match actual investigation work. A workable starting set is:

Record classTypical contentsRetention decision
Session evidenceprocess identity, approval, start and end, revocationretain through the maximum period for linked actions
Action ledgerdestination, operation, credential reference, result, integrity fieldsretain for the security investigation period
Diagnostic detailbounded error text, timing, selected request metadataretain for a shorter troubleshooting period
Protected payload evidenceredacted fragments or encrypted capture needed for a specific caseretain only when justified and delete on its own schedule
Policy and configuration historyauthorization setting changes, retention rule versions, export eventsretain with the action ledger or longer if required for accountability

The table is a method, not a claim that every team needs every class. If the agent only reads build status, a protected payload class may have no reason to exist. If it changes financial records, an action ledger that omits the exact target identifier may be too thin.

Avoid the common recommendation to retain raw requests and responses "just in case." It is popular because it makes early debugging painless and because storage looks cheap. Storage is not the difficult part. Search access, breach scope, subject access requests, deletion guarantees, and accidental secret capture are the expensive parts.

Retain a cryptographic digest of a body when you need to prove that a particular body was used without preserving its contents. A digest alone does not explain meaning, and it cannot help if the original body no longer exists elsewhere. Use it for correlation and later comparison, not as a substitute for an action description.

Keep failed and denied attempts. Denials often reveal an agent trying the wrong capability, a broken approval path, or a compromised process testing boundaries. They may deserve a different period from successful actions if their volume is much higher, but deleting them first because "nothing happened" removes context investigators need after a successful attempt.

Set the period from discovery and response, not storage cost

Choose a retention period by working backward from the latest point at which you still expect to investigate an event. The calculation is not elegant, but it makes assumptions visible.

For a record class, add:

  • the longest credible time before detection;
  • the time needed to open, scope, and assign an investigation;
  • the time needed to obtain related records from destinations or vendors;
  • any contractual, regulatory, or legal obligation that applies to that class;
  • a modest margin for delayed reporting and clock discrepancies.

Suppose a team discovers a suspicious production action during a monthly review, spends two weeks confirming scope, and may need a month to obtain a remote service's history. A 30-day action retention period has already failed before the investigation starts. The correct answer is not automatically a multi-year period. The team should choose a period that covers its actual detection and response practice, then test it against duties in the jurisdictions and contracts that apply to it.

Separate the rule from the exception. The ordinary schedule should delete records automatically. A case hold should preserve a defined set of records because of an active incident, dispute, audit, or legal instruction. When a hold ends, deletion should resume according to the policy rather than leaving the records indefinitely because no one remembered them.

Do not confuse backup retention with log retention. A database backup that contains deleted activity records may keep them available long after the application says it deleted them. Document whether backups are encrypted, who can restore them, how long they last, and whether a restore could reintroduce records that a deletion process removed. If you cannot purge an individual record from immutable backups, say so in the policy and set the backup period accordingly.

For systems handling personal data, consult counsel and the privacy owner before assigning a period. Privacy law does not usually give a universal number that fits agent activity. It does demand purpose limitation, data minimization, and defensible deletion. A vague security rationale does not justify retaining complete content forever.

Tamper evidence needs a separate trust boundary

Stop actions at the vault
While the vault is locked, Sallyport denies every action through its hardware-gated vault gate.

A record that only the same administrator can write and erase does not give much assurance after a serious incident. Protection from alteration requires both prevention and evidence of later change.

NIST SP 800-53 control AU-9 calls for protecting audit information from unauthorized access, modification, and deletion. That wording matters because immutable-looking storage alone does not solve access control, and access control alone does not reveal every improper change. Build both layers.

First, separate action execution from audit administration. The process that records an event should have append permission, not broad permission to rewrite or purge history. Administrators who manage retention should not casually edit individual event contents. Use a distinct, auditable process for deletion and correction.

Second, bind records into an ordered chain. Each record includes a hash of its prior record and a hash of its own canonical content. An editor who changes an old event breaks the chain at that event and every later link unless they can regenerate the affected sequence. Hash chaining is useful, but it has a limit: an attacker who controls the writer and every stored copy can rewrite the whole chain. Export signed checkpoints to an independent location, or arrange a review process that compares checkpoints outside the writer's control.

Third, protect time. System clocks drift, and attackers may alter them. Record receipt time in the collector, record monotonic sequence numbers where possible, and treat timestamps as evidence to compare with external records rather than solitary truth. RFC 3161 defines a protocol for trusted timestamps. It can strengthen proof that a digest existed at a given time, but it does not prove the request content was correct or authorized.

Fourth, verify rather than merely claim integrity. A verification command should report the first bad sequence, expected predecessor hash, observed predecessor hash, and record identifier. This output shape gives an operator something actionable:

$ audit verify activity.log
records_checked: 18427
chain_status: valid
first_error: none
checkpoint_status: matched

When verification fails, preserve the affected storage before anyone "fixes" it. Run verification against a copied data set, capture the output, identify the last valid checkpoint, and compare against independent exports. Repairing the chain first may destroy evidence about the alteration itself.

A plausible failure exposes what thin logs hide

Consider a coding agent that receives permission for a development task and later attempts an HTTP call to a production billing service. The action gateway rejects the call because the session authorization covers a different process than the one making the request. A few minutes later, a developer retries from another agent run and approves it without noticing the production destination.

The remote service returns a 200 response. The agent's chat transcript says only that it "resolved an invoice issue." The team learns about a customer complaint three weeks later.

With a weak record, the team finds a successful call from an unknown "agent" account and a generic timestamp. They cannot determine whether the first denied call came from the same executable, whether the approval occurred in the same session, which credential was selected, which invoice was affected, or whether anyone changed the record after the complaint. They end up searching shell histories, chat exports, and remote service logs that may have shorter retention than their own system.

With a useful record, the investigator can reconstruct the sequence:

  1. A signed process started a session and received an approval tied to that run.
  2. A process with different identity attempted the production operation and received a denial.
  3. A later session used a specific credential reference, targeted the production host, requested an invoice void against a protected identifier, and received a 200 result.
  4. The activity chain verifies against a checkpoint created before the complaint.

This does not prove whether the developer intended the action. It does establish who approved which process, what the execution path did, and where further investigation should go. Audit records should resist the urge to narrate motive. They should preserve facts that let people evaluate motive later.

Store a correlation identifier across retries, but do not collapse attempts into one final success record. Retries can show a changing destination, a switch of credentials, or a boundary test before a permitted action. Those details matter when the final request caused harm.

Redaction must happen before records enter the ledger

Avoid another policy engine
Use its fixed three-control decision ladder instead of maintaining policy rules for agent actions.

An encrypted audit store protects records at rest. It does not make it acceptable to log passwords, access tokens, session cookies, private keys, or whole customer objects. Once raw content enters a ledger with long retention, every future investigator, restore operator, and breach responder inherits that exposure.

Build a field allowlist for each channel. For HTTP, permit method, destination, route template, selected safe query parameter names, content length, status, and error class. Explicitly drop Authorization, Cookie, Set-Cookie, API tokens, client secrets, and known sensitive headers. Treat request and response bodies as deny-by-default.

Redaction based only on pattern matching will miss novel secret formats and may damage evidence. Use structural controls first: do not ingest fields that should never be present. Apply pattern redaction as a second barrier for error text or data supplied by remote services. Keep a redaction version on the event so investigators know which rules processed it.

Personal data needs the same discipline. An account identifier can be necessary to identify the affected object. A complete profile, document, or support transcript rarely belongs in a general action ledger. Pseudonymization can reduce routine exposure, but do not call a stable reversible identifier anonymous. If someone with another table can restore the identity, it remains personal data for governance purposes.

When a case truly requires content, create a narrow evidence capture with a case identifier, named access group, expiry, and review date. Record that the capture exists in the action ledger, but do not copy its content into every downstream report. This keeps ordinary investigations useful without giving all readers access to the most sensitive material.

Deletion, holds, and corrections must leave their own evidence

Connect approval to a process
Per-session approval identifies a new agent process by its code-signing authority before its run proceeds.

Retention is an operational process, not a paragraph in a security policy. A schedule that nobody tests will eventually turn into accidental permanent storage or an automated purge during an incident.

Run deletion through a recorded job. For each run, preserve the policy version, record class, time range selected, count of records deleted, count skipped because of holds, executor identity, and outcome. The deletion job should use the same append-only discipline as action recording. An operator should not need direct database access to "clean up" records.

A hold needs a scope that a machine can apply. Define it by case identifier plus event time range, session identifier, destination, actor identity, or another stable selector. Avoid holds written as a sentence in a ticket, because a retention job cannot evaluate a sentence. Record the person who issued the hold, the authority for it, review date, and release event.

Corrections deserve similar care. Systems occasionally record a wrong parsed route, a delayed timestamp, or a misleading classification. Keep the original event intact. Append a correction event that names the original event, identifies the changed interpretation, gives the reason, and identifies the person or process that made the correction. Reports should show the correction without concealing the source record.

Test the full process on a nonproduction copy: create records in every class, place a hold over part of the range, run retention, verify expected deletion, release the hold, and run retention again. Then restore a backup and confirm it does not create a hidden, routinely accessible archive that contradicts the stated schedule.

A compact policy is easier to enforce than a perfect document

A retention policy should fit the system that must carry it out. The following template is intentionally plain because every statement maps to an owner, a field, a job, or a verification activity.

Purpose: reconstruct externally executed agent actions and investigate misuse.

Action ledger: retain for [period].
Fields: actor identity, session, authorization decision, destination,
operation, credential reference, protected target identifier, outcome,
integrity fields. Exclude secrets and raw bodies.

Diagnostic detail: retain for [shorter period].
Fields: bounded error text and timing. Apply allowlist and redaction rules.

Protected evidence capture: case-only. Require case identifier, expiry,
access group, and documented approval.

Integrity: append records; verify chain [cadence]; export or compare
checkpoints [cadence]. Record verification failures.

Deletion: execute [cadence]. Record policy version, range, result, and holds.
Holds: suspend deletion for defined selectors. Review [cadence].
Corrections: append a correction record; never overwrite an action record.

Assign named owners for record schema, retention schedule, privacy review, incident holds, and integrity checks. One person may hold several roles in a small team, but the responsibilities still need names. Otherwise, the person operating the agent becomes the person deciding what evidence disappears after an incident.

Sallyport keeps a Sessions journal and an Activity journal projected from one encrypted hash-chained audit log, and sp audit verify can verify that chain offline over ciphertext. That design is useful only if teams decide in advance which fields belong in their records and how their retention jobs, holds, and exports handle them.

Review the policy after the first real incident or a deliberate tabletop exercise. Ask investigators to reconstruct one action using only the records that would have survived the schedule. If they need a secret, a raw transcript, or an administrator's memory to answer basic questions, change the schema. If they can answer the questions but every record carries customer content, cut the schema back before it becomes permanent.

FAQ

What should an AI agent audit log record?

Keep enough context to reconstruct who initiated the run, which executable made the call, when it happened, where the request went, what credential reference was used, what action was requested, and what result came back. Do not keep secrets, raw authorization headers, or bodies whose only purpose is convenience.

How long should AI agent logs be retained?

A 90-day default is often too short for code changes, billing disputes, and slow discovery, while several years can create needless privacy and breach exposure. Pick periods by event class, based on your detection window, investigation time, contractual obligations, and the sensitivity of the fields retained.

Are hash-chained logs enough to prevent tampering?

You need both. A hash chain makes later edits detectable, while access control reduces the chance that someone can edit or delete the records in the first place. Add independent storage or export if an administrator of the action system could also rewrite its local history.

Should we store full API request and response bodies?

Usually no. Store a digest, a length, a content classification, and a redacted summary rather than a raw body. Retain a body only when investigators cannot establish the meaning or impact of the action without it, and give that body a shorter period and tighter access path.

Who is the actor in an AI agent activity record?

Treat the actor as the execution identity, not the human who happened to type a prompt earlier. Record the agent process identity, its code-signing authority where available, the session that authorized it, and the human approver when a system collected one.

How do legal holds affect agent activity retention?

A legal hold must stop scheduled deletion for the records in scope and record who placed the hold, why, and when. Keep the held copy separate from the ordinary retention job, then document the release of the hold before deletion resumes.

What is the difference between session logs and action logs for agents?

Authentication logs prove that a process was admitted. Activity logs prove what that admitted process attempted and what happened. Keep the connection between them, because an investigation often starts with a session and then needs every action inside it.

What should happen when an audit record contains an error?

Do not silently overwrite the old record. Preserve the original event, append a correction that names the affected record and reason, and make reports show both. Silent correction destroys the very history an investigator needs to assess intent and impact.

What is the first retention rule to implement for autonomous agents?

First capture the minimum action record at the point where credentials are used: destination, operation, actor, time, authorization context, and outcome. Then set a short default deletion schedule and a documented extension process. Starting with years of raw payload collection is harder to unwind than most teams expect.

Can a hosted agent platform provide sufficient audit records?

They can, but only if the provider records the execution identity, the requested operation, the final destination, the authorization decision, and the result with enough fidelity for your investigation needs. A generic conversation transcript is not an activity record, and provider-side retention does not remove your own accountability.

Sallyport

Sallyport runs API calls and SSH commands for your AI agent. The keys stay in a local vault on your Mac; you approve each run and every action lands in a sealed journal.

© 2026 Sallyport · Open source under Apache-2.0 · Oleg Sotnikov