Documentation · Audit

Audit scenarios & playbook

A mapping of the questions internal and external auditors actually ask to Mergen detections — which built-in rule answers each or which custom-rule recipe to define, plus an honest list of what is out of scope. Every detection carries who (user, IP), what (rule, statement, tables/columns), and when.

A note on intent

Mergen records the what and the pattern; intent is a judgement the auditor makes from that evidence — though several patterns strongly imply it (exfiltration beaconing, privilege-escalation chains, credential-catalog reads). Mergen's job is to make the activity undeniable and searchable.

"Do you log DBA / privileged-user activity?"

Yes. A custom rule that records everything the named administrators do, at Info severity as a trail:

{
  "id": "dba_activity",
  "severity": "info",
  "match": { "user_in": ["dba", "root", "postgres"] },
  "message_template": "DBA activity: {kind} on {tables} by {user}"
}

"Record everything that is NOT the application account." (the headline SoD ask)

List every legitimate service account in user_not_in; everything else — operators, scripts, third parties — is recorded:

{
  "id": "non_app_access",
  "severity": "warning",
  "match": { "user_not_in": ["app_service"] },
  "message_template": "non-app access: {kind} on {tables} by {user}"
}

Verified by unit tests: sod_non_app_user_fires, sod_app_user_silent.

Writes to protected tables by non-app accounts

A read by an analyst is fine; a write to a financial table by a non-app account is Critical:

{
  "id": "non_app_write",
  "severity": "critical",
  "match": {
    "statement_kinds": ["Insert", "Update", "Delete"],
    "tables_regex": "^(ledger|payments|payroll)$",
    "user_not_in": ["app_service"]
  }
}

Verified by unit tests: non_app_write_fires_but_read_silent.

Scenario → rule coverage

Privilege / role changes role_privilege_escalation · dangerous_grant · role_impersonation Built-in
Schema changes (DDL) dangerous_ddl · ddl_by_non_admin Built-in
Backdoors / persistence security_definer_function · trigger_backdoor · dangerous_extension Built-in
Bulk export excessive_data_export Built-in
File / direct exfiltration exfil_direct Built-in
PII / sensitive data (KVKK) pii_content · turkish_pii · ozel_nitelikli_veri_access · sensitive_column_read Built-in
Slow-drain / beaconing exfil_byte_volume · exfil_time_pattern Built-in
Off-hours activity off_hours_query Built-in
Behavioral deviation (UEBA) ueba_anomaly · ueba_peer_anomaly Built-in
Mass delete (no WHERE) bulk_delete Built-in
Audit/log tampering audit_tamper Built-in
Credential-catalog reads system_catalog_recon Built-in
Failed access / brute force failed_login_burst · login_audit Built-in
DBA activity trail custom: user_in Custom rule
Segregation of duties (non-app access) custom: user_not_in Custom rule
High-rate scraping custom: rate Custom rule

Note: time is an optional axis — most rules run 24/7 (unwanted activity happens during business hours too). To bind a rule to time, add a time_window: e.g. "non-app access only after hours" as one Critical rule ({user_not_in} + {time_window start 18:00 end 08:00}). Use negate/days to restrict to business hours instead (UTC).

How to add a custom rule

  1. Rules → Custom rules → New. Pick the engine (pg/mongo) and severity.
  2. Set the match: statement kinds, table/column/command regex, user_in / user_not_in, require-no-WHERE — combine only what you need (AND semantics; an empty match matches everything).
  3. Optionally add a rate (count / window / group-by-user) for burst rules.
  4. Write a message template: {kind}, {tables}, {columns}, {user}.
  5. Save — the rule is pushed to agents on the next heartbeat (no restart) and can be scoped per host/group/global.
  6. Test — the panel previews against recently captured query patterns (approximate; exact matching runs live on the agent).

Out of current scope (honest gaps)

These stateful identity-anomaly scenarios are on the roadmap (advanced tier) and are NOT detected today — they should not be presented as covered:

  • Account sharing (same credential, many hosts at once)
  • Dormant-account reactivation
  • Impossible travel (distant IPs in a short window)
  • First-time-object access across the fleet