nano SIEM
User Guide

Parser Extensions

Customize OOTB parsers per log source with a small VRL overlay, without forking the base parser.

Parser Extensions

A parser extension is a small VRL overlay attached to a single log source. It runs as an extra Vector transform chained between the OOTB parser's parse step and its output step. Use it to add a field, normalize a value, or drop a noisy event for one tenant or one feed, without forking the OOTB parser and losing upgrades.

What an Extension Is

An extension is a VRL transform that runs after the OOTB parser has already produced the canonical UDM shape (.udm.*, .metadata.*, .ext, .message, .source_type) and before the output flatten step that prepares the event for ClickHouse.

Because the extension sits between _parse and _output, it sees the same .udm.* shape the parser produced. You can set, override, or delete UDM fields directly, and the flatten step still runs uniformly afterward.

Common Use Cases

GoalExample
Add a tenant field.udm.team = "soc"
Normalize a value.udm.action = downcase!(.udm.action)
Drop noisy eventsif .udm.action == "heartbeat" { abort }
Enrich from .ext.udm.user = .ext.principal_id ?? .udm.user
Mask sensitive content.message = replace!(.message, r'\d{16}', "[REDACTED]")

What Extensions Are Not For

  • Replacing the OOTB parser. If the base parser is structurally wrong for your logs (different format, different vendor variant), generate a new parser from samples instead.
  • Cross-source logic. Extensions are per-log-source. Logic that spans sources belongs in detection rules or enrichment.
  • Stateful processing. Extensions are stateless transforms: no aggregation, no joins, no lookups against other events.

The Stub Case (No OOTB Parser)

If the log source's parser_vrl is empty and the extension is enabled, the extension is the parser for that source type. The pipeline skips the _parse stage entirely and the extension consumes from the router directly:

The Extension tab makes this explicit: when no OOTB parser exists for the source type, the read-only base pane shows a "your extension will be the parser" hint and you author the full transform there.

Authoring an Extension

Walkthrough

  1. Open the log source at Feeds → select source → log-source detail page
  2. Click the Extension tab (between VRL editor and Deployments)
  3. Write the overlay. The top pane shows the OOTB parser read-only; the bottom pane is your editable VRL. The AI sidebar accepts natural-language edits and is pinned to "only emit the extension, don't touch the base parser"
  4. Test with a sample event. The Test button runs parser_vrl → extension_vrl against your sample and shows the final event shape: exactly what would land in ClickHouse
  5. Enable the toggle, Save the draft, then Publish + Deploy from the page header to push to Vector

Worked Example: Tag CloudTrail with a Team

You manage two AWS accounts (production and analytics) and want every CloudTrail event tagged with the responsible team so dashboards and detections can filter cleanly.

  1. Open the aws_cloudtrail_prod log source → Extension tab

  2. Write:

    if .udm.cloud_account_id == "111111111111" {
        .udm.team = "platform"
    } else if .udm.cloud_account_id == "222222222222" {
        .udm.team = "data"
    }
  3. Paste a sample CloudTrail event into the Test panel and click Test, then confirm team appears in the output

  4. Toggle EnabledSavePublish from the page header

The OOTB CloudTrail parser keeps running unchanged. Your team tag rides on top.

Worked Example: Drop a Noisy Health Check

A firewall feed includes health-check pings that double your event volume but never trigger detections:

if .udm.action == "allow" && .src_ip == "10.0.0.5" && .dest_port == 443 {
    abort
}

abort in VRL halts the transform and drops the event before it reaches the combiner. The OOTB parser still processes everything else.

Validation: Three Gates

Invalid extension VRL never reaches a running Vector. nano enforces three independent layers:

GateWhat it catches
Publish-timeWhen you click Publish, the server runs validate_vrl on both the parser and the extension. Syntax errors, unbalanced braces, and blocked functions (get_env_var, http_request, dns_lookup, etc.) reject the publish. The previous version stays live and the error message names the offending transform.
Combined-chain testThe Test button on the Extension tab runs the full parser_vrl → extension_vrl chain against your sample event before you publish. Field-name mismatches with the upstream parser surface immediately, so you can catch them in the draft loop.
Deploy-timeVector's own vector validate runs against the staged config after publish; on any failure the previous version stays live and the UI shows a deploy-failure status.

The AI sidebar re-validates every suggestion before returning it, so accepted suggestions are almost always already publish-clean. Save persists your draft as-is; the validation gates fire when you publish.

Version History

Extensions piggyback on the same publish/version flow as the base parser:

  • Each Publish snapshots both parser_vrl and extension_vrl into a new version
  • The Versions tab diff shows changes to either
  • Revert restores both fields to the chosen version's snapshot, so you don't have to revert parser and extension separately

Sampling Interaction

Extensions run before the optional sample transform, so an enabled extension applies to every event before sampling decisions. A normalization or enrichment in the extension is visible to the sampling exclude condition, which means you can write rules like:

.udm.criticality = if .src_ip == "10.0.1.5" { "high" } else { "low" }

and then exclude criticality == "high" from sampling on the Configuration tab.

Limitations (v1)

  • One extension per log source. Stacking multiple extensions with explicit ordering will come later. For now, compose your logic in a single transform.
  • VRL only. No declarative shorthand for common cases like "add a constant field." Use VRL with one-line assignments.
  • No conflict lint. If you set .udm.user in your extension and a future OOTB parser update also sets it, the extension wins (it runs second). Watch the Versions diff when pulling parser updates.
  • No cross-source library. Each log source's extension is its own artifact; copy-paste between sources for now.
On this page

On this page