Audit Log
Every state-changing action in Vygl produces an audit-log entry. Triage decisions, member invites, integration setup, custom rule edits, scan submissions, API key creation — all logged with the actor, timestamp, target resource, HTTP context, and a structured event payload. Useful for compliance reviews, post-incident reconstruction, and detecting abuse.
What’s recorded
Section titled “What’s recorded”Each entry includes:
| Field | Example |
|---|---|
action | finding.triage, org.member.invite, integration.create |
actor (user or API key) | The user ID or key prefix |
auth_type | jwt or api_key |
resource_type / resource_id | The thing being mutated (finding, member, rule, …) |
org_id | Always present — every entry is org-scoped |
ip_address | The request IP |
user_agent | The client that made the request |
http_method / http_path / status_code | Full request context |
details | Structured JSON specific to the action (old value, new value, reason, …) |
created_at | UTC timestamp |
The action vocabulary spans roughly 60 distinct types covering auth, organizations, members, projects, scans, findings, rules, integrations, memory, registries, SCM, CVE Watch, and admin actions. MCP-originated calls show as auth_type=api_key (or jwt for OAuth flows) — there’s no separate mcp auth type because MCP forwards the underlying credential.
Querying
Section titled “Querying”Today the audit log is superadmin-only — there’s no in-app audit-log surface for org admins. If you need a compliance review, request an export from Vygl support. An org-admin-facing audit-log view is on the roadmap.
Filters available to superadmins:
- Action category —
auth.*,finding.*,scan.*,project.*,org.*,rule.*,integration.*,memory.*,admin.*. - Actor — by user ID or API key prefix.
- Date range.
- Path / method — useful for tracking specific endpoints.
- Status code — 4xx / 5xx for failure analysis.
Append-only by design
Section titled “Append-only by design”Audit entries are append-only — there’s no API to edit or delete them. This is intentional: the audit log’s value as a compliance artifact comes from immutability. To remove an entry, ops would need direct database access plus a paper trail.
Common queries
Section titled “Common queries”Who marked these findings false-positive?
Filter action = finding.triage, details.status = false_positive, group by actor. False-positive abuse — a user mass-marking findings FP to silence them — is detectable from this query (cross-check with finding.bulk_triage for batch operations).
Did a fix-claim get verified or disproven?
Filter action ∈ {finding.status_change.claim_verified, finding.status_change.claim_disproven}. Each entry carries the scan ID that produced the verdict.
Who set up the Slack integration?
Filter action = integration.create, then look at details for the provider field.
Did this API key do anything unexpected?
Filter by the key’s prefix in actor. The full request history of a key is reconstructable from the log.
Retention
Section titled “Retention”Audit entries are retained indefinitely — there’s no automated pruning. Retention is implemented as “the row is never deleted”, not as a scheduled archive policy.