Proving Who Changed What in Dynamics 365: Audit Trails That Survive a Regulator

A technical guide to what Dataverse auditing records, scoping it, retrieving change history, exporting it to immutable storage and documenting the periods when it was off.

Dataverse auditing uses log capacity, so it is often switched off or scoped down, and then a regulator asks for two years of history. Auditing records creates, updates and deletes on audited tables and columns with old value, new value, user and time, plus relationship and role changes; user access logging is a separate setting, and ordinary reads are not recorded by default. Enable it for the tables and columns that carry evidence, retrieve history through the Web API audits entity set or RetrieveRecordChangeHistory, and export it on a schedule to immutable storage so retention stops competing with capacity. For periods when auditing was off, reconstruct what you can and give the auditor a dated statement of the gap.

Why do Dynamics 365 audit trails fail when a regulator asks for history?

Rarely because the platform cannot audit. The usual story is capacity. Audit records accumulate in log storage, someone sees the capacity report turning red, and auditing is switched off for noisy tables, scoped down to nothing useful, or old logs are deleted to free space. Nobody records the decision. Months later an auditor asks who changed a credit limit, a consent flag or a case outcome over the last two years, and the history is either missing or has a hole in the middle.

The fix is to separate two jobs that are usually treated as one. Operational auditing inside Dataverse answers day to day questions about recent changes. Evidential retention, the multi year record a regulator can rely on, belongs in storage designed for it. Once those are separate, you can keep auditing on without fighting over capacity. This page is technical guidance; what your regulator requires, and for how long, is for your compliance team and advisers to decide.

What does Dataverse auditing actually record?

Each audit record captures an operation on a row: which table and row, what kind of operation, who performed it (including when one user acted on behalf of another), when, and for updates the old and new values of each audited column that changed. Audit records cannot be edited through the application or the API, which is why they carry weight as evidence. They can, however, be deleted by anyone holding the relevant privilege, which matters later on this page.

EventRecorded when auditing is enabled?Notes
Create, update and delete of rowsYes, for audited tablesUpdates carry old and new values for audited columns only.
Associate and disassociate on many to many relationshipsYesUseful for security role assignments to users and teams, and marketing list membership.
Assign, share and security role changesYesOwnership changes and privilege changes on roles are auditable events.
Changes to audit settings themselvesYesSwitching auditing off for a table or the environment is itself logged, which helps date a gap.
User access (sign-in to the environment)Only if the separate user access logging setting is onRecords that a user accessed the environment, not what they viewed.
Reading or opening a recordNot by defaultRead activity can be captured through Microsoft Purview activity logging where your licensing and configuration support it. Check current Microsoft documentation before relying on it.
Some tables and column typesNot alwaysNot every table and column can be audited. Check the auditing option on each table and column you need.

How do you enable auditing and scope it to the columns that matter?

Auditing works at three levels, and all three must be on for a change to be recorded. The environment switch is in the Power Platform admin center under the environment's auditing settings, alongside the user access logging option. The table switch is the Audit changes to its data setting on each table in the maker portal. The column switch is the auditing option on each column, which is on by default for columns of an audited table.

That last default is where capacity goes. A table audited with every column on records every system or integration update to fields nobody will ever be asked about. Scope deliberately instead.

  • Start from the evidence: list the questions an auditor or regulator could ask, such as who changed this limit, this status, this consent or this owner, and map each to a table and column.
  • Turn on auditing for those tables, then turn column auditing off for technical, calculated or integration housekeeping columns that change constantly and carry no evidential value.
  • Audit security: role assignments, team membership and business unit changes are evidence of who could do what, and are cheap to keep.
  • Check integration users. An integration that rewrites every column on every sync creates an audit record per column change, so fix the integration to send only changed values rather than disabling the audit.
  • Record the configuration: export the list of audited tables and columns with a date, and keep it with your compliance records. Solutions carry table and column audit settings, so review them in pull requests like any other change.

Does audit history count against Dataverse storage capacity?

Yes. Audit records are stored as log data and count against your log capacity, alongside plug-in trace logs. That is the pressure that causes most gaps: when the tenant goes over capacity, deleting audit logs looks like the quickest win. Our sibling guide on Dataverse storage capacity cleanup covers how to free capacity without touching evidence.

The environment also has an audit retention period setting in the admin center, which controls how long new audit records are kept before the platform removes them. The available periods and the defaults have changed over time, and changing the setting may only apply to records created afterwards, so check current Microsoft documentation before relying on it. Treat that setting as operational housekeeping. It should never be the only thing standing between you and a regulator's retention requirement.

How do you retrieve who changed a record through the Web API?

There are two routes. For one record's history with old and new values resolved per change, call the RetrieveRecordChangeHistory function with the record as the target. For a population, such as every change to a table in a period, query the audits entity set and filter on the audited record, the table and the date, then expand to details for the rows you need.

An illustrative pair of requests, shown as text rather than code to copy: GET [org]/api/data/v9.2/RetrieveRecordChangeHistory(Target=@t)?@t={'@odata.id':'contacts(<record id>)'} returns the change history of one contact. GET [org]/api/data/v9.2/audits?$filter=_objectid_value eq <record id> and createdon ge 2025-01-01T00:00:00Z&$orderby=createdon asc returns the audit rows for that record from a date. The caller needs the View Audit History privilege, and for bulk extraction you should page through results and run under a dedicated identity whose own access is logged.

Check parameter names and the shape of the returned audit detail against current Microsoft documentation for your API version. For an analyst who only needs to read one record's history on the form, our free Easy Audit PCF control turns the native audit grid into a sortable, filterable change history view with CSV export. It reads the audit data that exists; it does not retain anything beyond it, so it is a viewing tool, not a retention answer.

How do you export audit logs to long-term immutable storage?

Retention that survives a regulator lives outside the operational environment, in storage nobody can quietly edit or empty. The common patterns on the Microsoft stack are below. Each depends on current product capabilities and licensing, so validate the exact option against Microsoft documentation before designing around it.

PatternHow it worksWhat to check
Scheduled export to Azure storageA scheduled job reads new audit rows through the Web API since the last run and writes them, with details resolved, as dated files to Azure Blob Storage or Data Lake Storage.Paging, watermarking so nothing is missed or duplicated, and a reconciliation count per run.
Azure Synapse Link for DataverseContinuous export of Dataverse tables to a data lake, which Microsoft documents as supporting audit data.Whether audit data export is supported in your configuration and how old values are represented.
Immutability on the destinationTime-based retention or legal hold policies on the storage container, so exported files cannot be modified or deleted until the period ends.Who can change the policy, and that the retention period matches what your compliance team has set.
Microsoft Purview auditActivity logging for Dataverse and Dynamics 365 flows into the Purview audit log, which has its own retention options.Which activities are captured, the licensing required and the retention your plan provides. It complements change history rather than replacing it.

Why is deleting audit logs to free capacity so dangerous?

Because it destroys the evidence and cannot be undone. The admin center lets an administrator delete audit logs to free capacity, for example by date or by table, and a single record's change history can also be deleted through the API. These are legitimate tools, used for personal data erasure among other things, but used casually they remove exactly the history an auditor will ask for.

Put three controls around them. Export first: no audit deletion runs until the export for that period is confirmed and reconciled. Restrict the privilege: few people, named in your access review. Record every deletion: date, scope, reason and approver, kept outside Dataverse. Deletion is also logged within auditing itself, but a log kept in the system being cleaned is not enough on its own. Where audit history holds personal data that must be erased, follow the process in our sibling guide on GDPR retention, erasure and DSARs in Dynamics 365 so erasure and evidence are handled deliberately rather than by a capacity cleanup.

What can you reconstruct for a period when auditing was off?

Some facts, never the full field-level history. Be honest about the difference before an auditor finds it. Useful sources, in rough order of reliability, are below.

SourceWhat it can showWhat it cannot show
Created on, modified on, created by, modified byWhen a row was created and last changed, and by whom.Intermediate changes, or old values. Only the last modification survives.
Integration and middleware logs, message queues, data warehouse snapshotsValues sent or received at points in time, and sometimes versions of a record.Changes made by users in the application that no integration saw.
Emails, activities, notes and timeline entriesDecisions and communications around a change, with their own dates.That a specific field changed from one value to another.
Backups restored to a sandboxPoint-in-time comparison: a record as it stood on a backup date against today. Backup availability windows are limited, so check current Microsoft documentation.Anything between the backup points, or anything older than the available backups.
Source systems and their own logsWhere a value originated, such as a finance system or signed form.Who changed it inside Dynamics 365.
Audit settings history, solution history and admin logsWhen auditing was switched off, and often who did it.The changes made while it was off.

How do you document an audit gap for an auditor?

Write a dated statement rather than hoping the question does not come up. Auditors can usually work with a known, explained, controlled gap; a hidden one found during fieldwork is far worse. Your compliance lead owns the statement, and the technical team supplies the facts.

  • The period: the exact dates auditing was off or scoped down, for which tables and columns, evidenced from audit settings history, admin logs or change records.
  • The cause: capacity pressure, a configuration error, a migration, stated plainly.
  • What was reconstructed and from which sources, with the limits of each, and what cannot be reconstructed.
  • Compensating evidence for the period, such as approvals held outside the system or source system logs.
  • The controls since: auditing scope agreed and documented, scheduled export to immutable storage, restricted deletion privilege, and a periodic check that auditing is still on.
  • The date the controls were verified as operating, and by whom by role.

How do you keep auditing from being switched off again?

Make the audit configuration a controlled setting rather than a toggle anyone with admin rights can change quietly. Keep audited tables and columns in solutions reviewed through your release process, check the environment and table settings on a schedule and alert when they differ from the documented baseline, and monitor the export job so a failed run is noticed within days. Where rules also need to be enforced at the point of data entry, such as mandatory reasons for a change, our sibling guide on closing a forms compliance gap in eight weeks covers that side, and building a CRM against a fixed audit date covers what an auditor usually samples.

If the underlying question is whether Dynamics 365 is the right place for a regulated record at all, answer it on requirements, not habit. We recommend the right solution - whether that's Microsoft Dynamics 365, Power Platform, or a custom-built CRM. Some businesses need the Microsoft ecosystem. Others need full control without licensing. We deliver both. A custom-built CRM on React, Node.js, PostgreSQL or .NET can use an append-only change log designed around your retention rules from day one, where that fits better.

How does Solzet help with Dynamics 365 audit trails?

We start by establishing the facts: what is audited today, what was audited in the period in question, where the gaps are and what the sources can reconstruct. Then we scope auditing to the evidence your compliance team needs, build and reconcile the export to immutable storage, put controls around audit deletion and capacity, and write up the gap so your compliance lead can present it. Where a wider review of security, configuration and ALM is warranted, that is our Dynamics 365 health check and technical audit.

Solzet delivers remotely from Yerevan, Armenia, with senior consultants and full-stack developers and 8+ years of Dynamics 365 Customer Engagement and Power Platform work, directly or white-label for Microsoft partners.

What do people ask us?

Does Dynamics 365 record who viewed a record?

Not through standard Dataverse auditing, which records creates, updates, deletes, relationship and security changes on audited tables. A separate user access setting logs that someone accessed the environment, not what they opened. Read activity can be captured through Microsoft Purview activity logging where your licensing and configuration support it, so check current Microsoft documentation before telling an auditor that reads are covered.

How long does Dynamics 365 keep audit logs?

The environment has an audit retention period setting in the Power Platform admin center, and records are also lost if an administrator deletes audit logs to free capacity. Microsoft has changed the available periods and defaults over time, so check current documentation. For a multi year regulatory requirement, export audit history on a schedule to immutable storage rather than relying on the environment setting alone.

How do I see who changed a field in Dynamics 365?

If auditing was enabled for the environment, table and column at the time, open the record's audit history, or call the RetrieveRecordChangeHistory function or query the audits entity set through the Web API. Each change shows the old value, new value, user and time. The free Solzet Easy Audit PCF control makes the per record view sortable and filterable. If auditing was off, only the last modified by and modified on values survive.

Do Dataverse audit logs use storage capacity?

Yes. Audit records count against log capacity together with plug-in trace logs. That is why auditing is so often scoped down or deleted during capacity cleanups. Scope auditing to the columns that carry evidence, fix integrations that rewrite unchanged values, and export history to external storage so you can manage in-environment retention without losing what a regulator may ask for.

Can Dynamics 365 audit records be changed or deleted?

They cannot be edited through the application or the API, which is what makes them credible evidence. They can be deleted: administrators can delete audit logs to free capacity, for example by date or table, and a single record's change history can be deleted through the API. Restrict those privileges, export before any deletion, and record every deletion with its scope, reason and approver outside Dataverse.

What can we give an auditor if auditing was switched off?

A dated statement of the gap: the period and scope, the cause, what was reconstructed from created and modified fields, integration logs, activities, backups restored to a sandbox and source systems, what cannot be reconstructed, compensating evidence and the controls in place since. A known, explained and controlled gap is far easier for an auditor to work with than one discovered during fieldwork. This is technical guidance, not regulatory advice.

Is Easy Audit a solution for audit log retention?

No. Solzet Easy Audit is a free PCF control that makes the audit history of one record readable on the form, with table and progress views, filters and CSV export. It reads the Dataverse audit data that already exists and retains nothing itself. Retention needs auditing scoped correctly plus a scheduled export to immutable storage.

Which solution is right for your business?

Tell us what you need. A senior consultant replies within one business day with a recommendation - Dynamics 365, Power Platform, or a custom-built CRM - not a sales script.