A human logs in once and you can reconstruct what they did. A service account, a CI runner, and an agent log in thousands of times a day, often as the same shared key, and your audit trail records a machine doing things no person ever reviewed. That is the tension. A non-human identity acts like a user but reports like a process.
The result is an audit trail full of activity and short on accountability. You can see that svc-deploy ran a migration at 03:14. You cannot see who or what decided it should, or whether anyone was supposed to approve it.
Why non-human identity strains the audit trail
Most logging was built around the human session. One person, one login, one trail. Non-human identities violate every part of that shape:
- They are shared. Ten pipelines and three engineers use the same database role, so the log attributes everything to the role.
- They are long-lived. A token minted in 2023 is still authenticating in 2025, and nobody remembers what granted it.
- They fan out. One scheduled job triggers five downstream calls, each landing in a different system's log with no link back to the cause.
An audit trail that cannot name the principal behind an action is a list of events, not an account of decisions.
What a usable trail actually needs
For non-human identities, three properties separate a real record from noise:
- A named principal per action. Every command resolves to a specific identity, not a shared role. "The reporting agent" is not enough; the trail names the agent, the run, and the human or policy that authorized it.
- Command-level granularity. "Connected to Postgres" tells you nothing. "Ran
UPDATE accounts SET ...on the prod replica" tells you everything. - A record outside the actor. If the same process that ran the command also writes the log, a compromised or buggy actor can shape its own story. The record has to live somewhere the actor cannot reach.
Put the audit trail on the connection, not in the agent
The fix is architectural. Stop trying to make every service account, runner, and agent honestly narrate itself, and instead record at the point where it touches infrastructure. That point is the connection.
