Logistics
Replaced three shared service accounts with 26 per-agent identities
A logistics operator thought it ran nineteen agents on three shared credentials. It ran twenty-six. Permissions on the widest credential 47 → 6, writes traceable to a specific agent 0% → 100%, single-agent isolation under two minutes and rehearsed.
The brief: A freight and contract-logistics operator had put what it believed were nineteen agents into production across its transport management system, customer portal, and finance stack. Its cyber insurer asked a question at renewal that nobody could answer: if one of those agents were manipulated, which systems could it reach, and how would you know it was that one? They asked us to make the fleet accountable before it doubled.
What the inventory found
- There were not nineteen agents. There were twenty-six. Seven had been built by teams outside engineering — two in finance, three in customer operations, two by a systems integrator during a warehouse rollout — and none appeared on any register.
- All twenty-six authenticated as one of three shared service accounts. The widest held 47 distinct permissions, accumulated one grant at a time, including write access to the TMS, read access to the customer database, and the ability to send email as the company.
- Attribution was impossible. We took a set of rate changes written to the TMS the previous week and tried to trace them to a specific agent from logs alone. We could not. The log knew a service account had done it.
- Because revocation meant killing a shared credential, the practical response to a misbehaving agent was to stop the entire fleet. Nobody had ever done it, which meant the control had never been tested.
What we built
- A registry as the control point. Every agent has a record: purpose, owner, systems touched, data classification, and its identity. The registry is not documentation — an agent with no record cannot obtain a credential, which is what stops the seven-shadow-agents problem returning.
- One identity per agent. Each agent authenticates as itself, with permissions attached individually. Broad, harmless grants — logging, metrics, model access — stayed common. Everything touching customer data, money movement, or outbound communication was scoped to the single agent that needed it.
- Credentials bound, not bearer. Short-lived certificates bound to the workload replaced long-lived static secrets, so a captured credential cannot be replayed from somewhere else. The two agents acting on behalf of a logged-in user were rebuilt so the token is exchanged at the gateway and the agent never holds it.
- Attribution wired into the write path. Every write carries the agent identity, the invoking user or schedule, and the task identifier, into the same log the SOC already watches. No new console for anyone to ignore.
- A per-agent kill switch, and a rehearsal. Any single agent can be disabled without touching the others. We ran the drill twice with their team before handover, because an untested control is a claim, not a capability.
What changed
- Agents with a distinct identity: 0 of 26 → 26 of 26, over nine weeks and with no production interruption.
- Permissions on the widest credential: 47 → 6. No single identity in the estate can now both read customer data and send external email.
- Writes traceable to a specific agent and instruction: 0% → 100%.
- Time to isolate one misbehaving agent: previously unachievable without stopping the fleet, now under two minutes and rehearsed.
- Insurer’s control questionnaire: answered from the registry rather than from memory, and the renewal completed without the exclusion the broker had warned was coming.
What we left behind
A provisioning pipeline where identity is the default rather than the hardening step. A new agent gets its record, its identity, and its scoped permissions as part of being deployed, and cannot reach production without them. The registry is owned by the platform team and reviewed quarterly with security, so permission creep is visible as a diff rather than discovered during an incident.
We were explicit with their security team about what this does not do. Per-agent identity is an authorisation control: it contains the damage and tells you who did it. It does not stop an agent being talked into misusing permissions it legitimately holds, and a document-processing agent reading untrusted customer paperwork remains their largest exposure. What changed is the shape of the bad day — a single scoped agent doing something wrong, caught, attributed and isolated in minutes, rather than an unattributable action taken by a credential shared across the entire operation.