Repository navigation
v0.2.0
Adds the audit trail, the one thing the README listed as missing.
Every list, get and search is recorded before its result is returned.
Identifiers and field names, never field values. A trail that stored the
rows would become a second copy of every record an agent ever read, in a table
nobody wrote a policy for, and the log would be a softer target than the data
it was meant to protect. To see values, read those ids from the source, where
the policy still applies.
A denied read and a missing one are recorded apart, while staying identical
to the agent. get still returns null for both so ids cannot be enumerated;
the operator gets the distinction they need, in a record the agent never sees.
Refused calls are recorded too. One filter on an unexposed field is a
mistake. A run of them is probing.
Strict by default. A sink that refuses takes the read down with it, because
a trail with silent gaps cannot answer the question it exists for, and the
moment a gap opens is exactly when an attacker would choose to be reading.
Set agent-kit.audit.strict to false if availability matters more to you.
The default sink writes to a log channel, so it works on a fresh install with
no migration. Bind Audit\AuditSink for anything else. ArraySink ships so
your own tests can assert that a tool call produced the record you expected.
34 tests across PHP 8.2, 8.3 and 8.4, including that no field value ever
reaches the audit record and that the log line format does not drift.
Still not built, and still not pretended otherwise: relation traversal, and a
generator that emits laravel/mcp tool classes from a resource.