Failed Requests Now Appear in the Audit Log
Denied reveals, wrong vault keys, throttled requests and forbidden writes are recorded alongside the successful ones, each with the reason it failed.
#What's Changed
- [Security] Failed requests are now written to the audit log. Every key endpoint on the web, CLI and MCP surfaces logged only on its success path, so a wrong vault key, a throttled reveal, a viewer's rejected write or a lookup of a key that does not exist left no trace at all — exactly the events an audit trail exists to capture. The logs page and its Error filter had always been able to display them; nothing was ever writing them.
- [Improvement] Failed entries carry the reason: the error code and message from the response are stored on the entry, so a 403 reads as INVALID_VAULT_KEY or a read-only role rather than an unexplained refusal.
- [Improvement] A failed attempt is filed under the action that was attempted — a denied reveal is a KEY_REVEALED entry with a 4xx status, and a rotation that fails on the vault key is recorded as an attempted rotation rather than a metadata edit — so filtering by event type shows both the successes and the attempts.
- [Improvement] Logging now derives from the response each endpoint actually returns instead of being written by hand on the success path, so a new failure branch cannot silently go unlogged. This also corrects the bulk import, which recorded status 201 while returning 200.
- [Fix] A request that fails before its project is known — an unauthenticated caller, or one whose project cannot be resolved — is still not logged, because audit entries are stored per project. Those responses are unchanged.