Skip to content

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.

Each entry includes:

FieldExample
actionfinding.triage, org.member.invite, integration.create
actor (user or API key)The user ID or key prefix
auth_typejwt or api_key
resource_type / resource_idThe thing being mutated (finding, member, rule, …)
org_idAlways present — every entry is org-scoped
ip_addressThe request IP
user_agentThe client that made the request
http_method / http_path / status_codeFull request context
detailsStructured JSON specific to the action (old value, new value, reason, …)
created_atUTC 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.

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 categoryauth.*, 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.

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.

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.

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.