An audit trail is not a log directory. It is the evidence that a specific control operated over a specific period, and roughly half of it usually sits inside the vendor you are about to leave.
What the trail actually asserts
Before you can migrate a trail you have to be able to say what it claims. In practice a trail over LLM inference is asked to support three assertions, and each one is evidenced differently:
- Every inference over regulated data ran under an approved configuration. Evidenced by a per-call record of the resolved configuration — model identifier, provider, region, safety or redaction policy version, prompt template version — not by a pointer to whatever configuration is current.
- Access to prompt and completion content was restricted and recorded. Evidenced by your application’s access log_and_ by the vendor console’s own audit log, which is the piece teams forget: an engineer who opens a trace viewer or a playground and reads a customer conversation has accessed regulated data, and only the vendor recorded it.
- The records are complete and have not been altered.Evidenced by whatever integrity mechanism you chose — append-only storage, object-lock, a hash chain — plus the ability to show that no period is missing.
A migration threatens the second and third far more than the first. Configuration records are yours and travel with your code. Access records and completeness both depend on things the outgoing vendor controls.
The half of it you do not own
Console audit logs, invocation logs, key usage records and the retention configuration itself are vendor-side artefacts. They are reachable while the account is live, reachable for some wind-down period after termination, and then they are not. If your retention obligation is five years and your evidence for year one lives in an account you closed in year two, you do not have a five-year trail.
So the export is not a nice-to-have at the end of the migration, it is a dated task inside the notice period. Export the console audit log, the key and credential inventory with creation and revocation dates, the list of users who held console access and when, and any invocation-level logging you enabled. Export it in a form that stands alone — a CSV or JSONL file with a documented schema beats a screenshot of a dashboard that no longer exists, and beats an API export you cannot re-run after the account closes.
Wind-down and deletion periods after termination are contract terms, not product behaviour, and they differ per agreement. Read yours before you plan the export date rather than assuming a grace period.
Importing records without back-dating them
Here is the subtle failure. Teams with a hash-chained or append-only evidence store import the outgoing vendor’s export into it and write each record with its original event timestamp. The store now says these events were recorded when they happened. They were not — they were recorded on migration day, from a file, by a person who could in principle have edited the file first. The chain no longer means what it meant.
The honest construction is to import the export as a single attested artefact rather than as rows. Store the file, record its hash, the export timestamp, the account it came from, the identity that ran the export and the tool version, and chain that record. The claim becomes “this file was received on this date and has not changed since”, which is weaker than “these events were recorded as they happened” and is the claim you can actually defend. Auditors are used to that shape; it is how third-party evidence is normally handled.
The correlation key problem
Most trails end up keyed on the vendor’s request identifier because it is the one value that appears in both your logs and theirs. After a migration you have two identifier namespaces with different formats and no relation between them, and a query like “show me every inference for this account in March” quietly returns the half that came from one namespace.
The fix is structural and cheap if you do it before you need it: generate your own call identifier before dispatch, key the trail on that, and store the vendor identifier as an attribute alongside a provider column. Then the trail has one key for its whole life and the vendor identifier becomes what it actually is — a support-desk lookup value. Where each provider surfaces that value is a separate question, and it changes more often than this one.
The window where the trail silently splits
During cutover the same logical operation can be served by either vendor, and for a period both are live. If the trail does not record which provider served each call and why — the routing decision, the configuration version that produced it, whether it was a fallback after an error — then the record of that period is incomplete in a way that is invisible. Nothing errors. The row count looks right. The answer to “under what configuration was this processed” is simply absent for a fortnight.
Two consequences follow. First, add the provider and the resolved configuration hash to the trail schema before you start routing anywhere new, so the field is populated for the pre-migration baseline too and a query does not have to special-case nulls. Second, treat a fallback as a distinct recorded event rather than as a retry that happens to succeed, because a fallback means the data went somewhere your primary control narrative did not describe.
Re-establishing the controls
On the new vendor, the controls have to be stood up again, and the ones that are easiest to miss are the ones that were configured once, years ago, by somebody who has left. Work through them explicitly: named individual accounts with SSO rather than a shared login; console audit logging enabled and exported on a schedule from day one, not retroactively; API keys issued per service and per environment with an owner recorded; the retention or logging configuration set deliberately and its value captured as evidence; and whatever retention terms you negotiated reflected in the account settings rather than only in the contract.
Finally, the migration is itself a change to the control environment. A control narrative that describes a vendor you no longer use is a finding. Version the narrative, date the change, keep the old version, and record the period each one covers — an auditor examining a year that spans the cutover needs to see two descriptions and the boundary between them, not one description that was quietly rewritten. What you choose to record per call is the other half of this; what to log covers the general shape.
Top comments (0)