Audit Events
Every Levee audit event type, grouped by channel, with the fields each one fills and what is never recorded
Levee writes an audit event each time the AI agent asks for something Levee controls, and for what Levee decided: a website, a model call, a database query, a file, a plugin call, an approval. This page lists every event type, so auditors and security teams can search the trail, build reports, and set alerts.
For where the events are stored, who can read them, and how to forward them, see Activity and audit. The same events appear in the app's Activity tab and in levee audit tail.
What does every event contain?
Each event says when it happened, what kind of event it is, what it concerns, what was decided, and who and which machine it belongs to.
Record format
| Field | Content |
|---|---|
Timestamp | UTC time of the event |
EventType | The event category (for example NetworkRequest, AccessDenied) |
EventTypeString | The precise event name, when more specific than the category (for example http.denied, llm.request) |
Resource | What the event is about |
Detail | The decision, reason, or measurement |
UserName | The Windows user the action is attributed to |
MachineName | The workstation |
ContainerId | The sandbox session, when the event belongs to one |
In the SQLite database (levee-audit.db) the event_type column holds the precise name when there is one, otherwise the category. In the JSON-lines file (levee-audit.jsonl) both fields are present. When you search, match on EventTypeString first and fall back to EventType.
What is never recorded?
The audit trail records decisions and metadata, not content.
- Model prompts and responses
- Cookie values, passwords, API keys, tokens, and connection strings
- Office document and email content
- Search results and web response bodies
- Plugin call arguments and results
Some events do record what the agent asked for, such as a web search query or a SQL statement. Those are noted in the tables below.
Event reference
Sandbox lifecycle and administration
| Event | Resource / Detail |
|---|---|
ContainerStarted | A project's sandbox started. |
ContainerStopped | A project's sandbox stopped. |
PolicyReloaded | A new policy took effect on the machine (local file change or cloud sync). |
tool.enable.approved | A user approved and enabled an AI tool for a project, including its network hosts. |
tool.upgraded | A user upgraded a project's tool to a newer published version. |
tool.disabled | A user disabled a tool for a project. |
RuntimeProvisioning | The sandbox image was downloaded, verified, or loaded, or provisioning failed. |
EngineLifecycle | The container engine changed state (started, stopped, became unavailable). |
HostFeatureEnabled | An administrator enabled the Windows Containers feature from the Levee app. |
HostFeatureEnableDenied | A non-administrator tried to enable it. |
CaCertInstalled / CaCertRemoved | The certificate the sandbox trusts for web inspection was installed or removed for a session. |
AgentChat (agent.<kind>) | Easy mode chat activity: the agent's tool calls, auto-approved in-sandbox permissions, and turn completion. Chat text itself is not in the audit trail. |
AgentChat (agent.readProjectFile) | The user previewed a project file in the chat. Resource is the project. Detail is the outcome (Ok, Refused, NotFound, TooLarge) and the file path. |
Tool changes are recorded like every other event: the change does not wait for its record to be stored, so a failure of the audit store can leave a change without a stored record.
Approvals
| Event | Resource / Detail |
|---|---|
AccessRequested | A request was paused for a human decision. Resource is what was requested. |
AccessApproved | Approved. Detail includes scope=once or scope=persist. |
AccessDenied | Denied, dismissed, or timed out. Detail includes the scope, for example scope=timeout. |
AccessEscalated | A request was escalated for review by policy. |
AccessRevoked | A remembered decision was revoked. |
Web access
Web events have the category NetworkRequest and a precise name starting with http..
| Event | Meaning |
|---|---|
http.request | A request was allowed. Resource is host:port/path (or CONNECT host:443 for HTTPS). Detail is the method and outcome, for example GET - allowed. |
http.denied | A request was refused. Detail gives the reason, for example policy deny, method not in whitelist, CONNECT denied for non-443 port, or a user denial. |
http.access_requested / http.access_approved | A request matched an escalate rule and went to the user. |
http.upstream_failed | The destination couldn't be reached. |
http.security.dns_rebind | The host name resolved to a private, loopback, or reserved address and was refused. |
http.security.sni_mismatch | The TLS connection named a different host than the one requested, and was refused. |
http.security.session_overflow | The number of remembered web approvals hit its limit and was cleared. |
http.identity.inject | A connected identity's session was attached to a request (host and cookie count only). |
http.identity.escalation | A request needed a sign-in. |
With web inspection enabled for a host, allowed requests also carry method, content type, and size for each request and response.
Model access
| Event | Resource | Detail |
|---|---|---|
llm.request | provider/model | Requested model, prompt and completion token counts, latency, status code, whether streamed |
llm.denied.model | Requested model | The model isn't permitted by policy |
llm.denied.user | Model | The user denied (or didn't answer) the first-use prompt |
llm.denied.budget | Model | Which budget was hit (session, daily, concurrency), tokens used, and the cap |
llm.denied.protocol | Model | The agent used an API format the model's provider doesn't accept |
llm.denied.auth | Model | No provider credential is configured on the host |
llm.prompt_blocked | Model | A prompt filter term matched. The term itself is never recorded, only a short non-reversible marker. |
llm.upstream_error | provider/model | The provider returned an error, with status and latency |
llm.internal_error / llm.startup_failure | The model channel failed internally |
Prompts and responses are never recorded.
Database access
| Event | Detail |
|---|---|
odbc.connect | The agent opened a connection to a permitted data source alias. |
odbc.connect.denied | The connection was refused (unknown or unauthorized alias). |
odbc.query | A query was permitted and is about to run. Detail is the SQL text. |
odbc.query.denied | A query was refused. Detail is the reason followed by the SQL text. |
odbc.query.timeout | A query exceeded the policy's time limit and was terminated. |
odbc.security.dangerous_pattern | A query contained a blocked pattern such as xp_cmdshell or OPENROWSET. |
odbc.metadata | The agent listed tables or columns. |
odbc.disconnect | The connection closed. |
odbc.policy.partial / odbc.policy.rejected | Part or all of a pushed database policy was invalid (see Database access). |
SQL text is truncated to 500 characters. Connection strings and credentials are never recorded.
Web search
| Event | Resource | Detail |
|---|---|---|
SearchRequested | The query text | A search was requested. |
SearchApproved | The query text | The user approved it. |
SearchExecuted | The query text | Sent to the provider. Detail is provider:resultCount. |
SearchDenied | The query text | Denied by the user, timed out, or couldn't be confirmed in the audit trail. |
SearchProviderError | The query text | The provider failed. |
denied:select | Search is disabled, or the provider isn't allowed (search-disabled, provider-not-allowed, ...). | |
denied:validation | The query broke a rule: empty-query, too-many-domains, invalid-domain, prohibited-term, session-quota-exceeded. | |
denied:credential | The provider's API key isn't configured on the host. |
Search queries are recorded in full. Search results are not.
Connected identities
| Event | Meaning |
|---|---|
WebIdentityEscalated | The agent needed a sign-in and the user was prompted. |
WebIdentityCaptured | The user completed a sign-in. |
WebIdentityDenied | Policy refused the sign-in, or the user declined. |
WebIdentityRevoked | The user revoked an identity. |
WebIdentityStoreCorrupted | Stored sessions couldn't be read and were discarded. |
Cookie values are never recorded.
Package registry credentials
| Event | Meaning |
|---|---|
UpstreamCredentialSet / UpstreamCredentialCleared | An administrator stored or removed a registry credential (manager and scheme only). |
UpstreamCredentialDenied | A non-administrator tried to. |
UpstreamCredentialStoreCorrupted | Stored credentials couldn't be read and were discarded. |
Microsoft 365 (preview)
| Event | Detail |
|---|---|
M365Operation | An Office operation was requested and decided. Detail is a JSON summary: the tool (for example m365.excel.read_range), a hash of its arguments, the scope (sheet, range, cell count, folder, recipient count), the policy rule, the outcome, and latency. |
AccessRequested / AccessApproved / AccessDenied | Office approval prompts, as for other channels. |
Document content, email content, and recipients' addresses are never recorded, only hashes and counts.
Packages (preview)
| Event | Detail |
|---|---|
package.allowed | A package download was permitted. Resource is manager:scope/package@version. The package is only served once this record is stored. |
package.denied | Refused, with a reason such as no-policy-for-manager, method-not-allowed, upstream-unreachable, or invalid-upstream-auth. |
package.stream_interrupted | A download stopped partway (client-aborted, idle-read-timeout, transport-error). |
decision-aborted-by-client usually means someone pressed Ctrl+C during an install; exclude it from deny-rate alerts.
File access
These events cover the files and folders a user shares with a project. Events from the LeveeFS file-system service carry an fs. or file. name, with the category shown in brackets.
| Event | Detail |
|---|---|
FileGranted (grant.added) / FileRevoked (grant.removed) | A folder or file grant was added to or removed from a project. Resource is the host path. Detail is the project and the access (read, readwrite, or deny). |
grant.skipped (AccessDenied) | A grant could not be offered to the sandbox, for example because the path is neither on a local fixed drive nor a \\server\share path. Resource is the path. Detail is the project and the reason. |
fs.read / fs.dir (FileGranted) | The agent was allowed to read a file or list a folder. Resource is the host path. Detail is the operation and the reason. |
fs.write (FileModified) | The agent was allowed to change a file. |
fs.denied (AccessDenied) | An operation was refused. Detail is the operation, the action, and the reason. |
fs.approval_requested (AccessRequested) | An operation needs the user's approval, and the user was asked. |
file.read | The first read of a file in each open. |
file.mutated | A change was applied: create, write, append, rename, delete, truncate. |
file.close | Closing a file failed. Only failures are recorded. |
policy.denied / transport.refused | LeveeFS refused an operation because the policy changed under it, or because its connection to the user's session was gone. |
FileModified | A file changed through Levee file access. |
A denied path looks to the agent exactly like a path that doesn't exist; the real reason is recorded here.
Plugins (preview)
Plugin events come from the MCP plugin runner. They have the category NetworkRequest. Resource is the plugin as <pluginId>@<version>. See Plugins.
| Event | Detail |
|---|---|
mcp.call | The agent called a plugin. Detail is the plugin's short name (slug), the method, the tool, prompt, or resource name, the outcome (ok, tool-error, protocol-error, crash, revoked, cancelled, unavailable), the duration, and request and response sizes. |
server.start / server.ready | A plugin server is starting, and is ready. |
server.stop | A plugin server stopped. Detail gives the reason. |
server.start_failed | A plugin server could not start. Detail gives the reason. |
server.crash | A running plugin server ended unexpectedly. |
server.parked | A plugin server failed repeatedly, and Levee stopped restarting it. |
server.version_change | A plugin server moved to another version of the plugin. Detail gives both versions. |
server.client_request_rejected | A plugin server sent a request the runner does not allow, and it was refused. |
channel.violation | A plugin server broke the communication protocol. The server.crash that follows records its end. |
Plugin call arguments and results are never recorded, only names, outcomes, sizes, and durations.
Security events
These indicate Levee blocked or detected something that deserves attention. Consider alerting on all of them.
| Event | Meaning |
|---|---|
SecurityDnsRebind | A destination resolved to a private or local address and was refused. |
SecuritySniMismatch | A connection tried to reach a different host than it claimed. |
SecurityCertRejected | A certificate failed validation. |
SecuritySignatureInvalid | A Levee component failed its signature check and was not started. |
SecuritySymlinkDetected | A link that pointed outside an allowed folder was refused. |
SecurityPipeDenied | A local connection to a Levee component was refused because its caller couldn't be verified. |
SecurityFsAttachRefused | A file-access connection from a sandbox couldn't be verified and was refused. |
SecurityWfpDegraded | Network enforcement for a sandbox couldn't be confirmed. The sandbox is kept blocked. |
SecurityAuditOverflow | Audit events arrived faster than they could be stored. Affected actions were refused. |
SecurityAuditWriteFailed | The audit store failed to write one or more events. Because the store is what failed, this alert is raised in the service log and, when forwarding is on, in Vediram Cloud rather than in the local audit files. |
Suggested alerts
| Alert | Query idea |
|---|---|
| Any security event | EventType starts with Security or EventTypeString contains .security. |
| Spike in denials | Count of http.denied, llm.denied.*, odbc.query.denied per user per hour |
| Standing exceptions | AccessApproved with detail containing scope=persist |
| Destructive SQL attempts | odbc.query.denied or odbc.security.dangerous_pattern |
| Budget exhaustion | llm.denied.budget |