Daily Use

Dashboards

Dashboards turn bounded NFQL results into reusable SOC views. Use them for a live operations wall, a handover screen, recurring threat hunting, capacity monitoring, or any question that is easier to understand as a trend than as a table.

There are two entry points:

  • Investigation → Visualize explores the result currently in memory. Choose a table, metric, line, bar chart, histogram, donut, scatter plot or heatmap, then map result columns to axes and values. The preview does not rerun the query.
  • Analysis → Dashboards creates an empty durable canvas. Add panels when the dashboard has a clear purpose; each panel stores inline NFQL or a saved query reference, plus its visualization and position on a responsive 12-column grid.

The dashboard catalogue separates opening from definition-level actions. Select the main body of a card to open its canvas. Edit opens the same focused title, portable-name and description modal used at creation. Clone creates a complete independent copy, including panels, queries, visualizations, layout, tags and defaults, with a collision-free portable name. Delete always asks for confirmation. Edit and delete acquire only that dashboard’s lease and release it when their short operation finishes.

Reference dashboards

obserae ships four reference dashboards and installs them on the first start. They are the fastest way to see what the product can answer, and a worked example of how the queries behind each panel are written:

DashboardQuestion it answers
Health & coverageIs obserae seeing your network correctly? Export volume per sampler, session consolidation coherence, direction inference, NAT confidence, assets missing from the cartography.
Network overviewWhere does your traffic go? Egress and ingress volume over time, their totals, and the top internet and internal talkers in both directions.
HuntingThreat-hunting starting points: beaconing, exfiltration candidates, port scanning, DNS and clear-text protocol usage, tunnelling, ICMP volumetry, destinations outside known cloud ranges.
SOC triageThe morning triage: closed sessions, internal hosts, threat-intelligence hits, exposed services, scans and dead services, lateral movement, sessions no rule matched.

They carry a Reference badge in the catalogue and are read-only: they cannot be edited, renamed or deleted, and the std. name prefix is reserved for them, so one of your dashboards can never collide with a future one. obserae keeps them up to date on upgrade — an improved query reaches you without any action, which is also why a published link on a reference dashboard may change shape after an upgrade.

Everything that does not change the definition stays available: change the time range and the refresh interval, open a panel in the large view, and publish a public read-only link.

Three ways to work from one:

  • Clone to edit makes a complete, ordinary, editable copy — panels, visualizations, layout and defaults included. The copy drops the std. prefix and is yours: change anything, and it is exported with your configuration like any other dashboard.
  • 🔍 on a panel opens the panel studio in read-only. The NFQL, the field mapping and the rendering options are all visible and selectable, so you can read and copy the query without being able to save over it.
  • ⇄ on a panel copies that single panel into one of your own dashboards, where you can then edit it freely. The reference dashboard is left untouched.

Reference dashboards never appear in the exported configuration YAML — the definition inside the binary is their source of truth — and importing a configuration never removes them.

Build a panel

The dashboard is read-only when it opens. Edit is dedicated to the canvas: select it, then Add panel to open the panel studio. Edit mode is also required to edit, clone or delete an existing panel, change the layout, save the current time and refresh controls as dashboard defaults, or delete the dashboard itself. The panel studio uses the same highlighted, schema-aware NFQL editor as Investigation, including distinct highlighting for the four time variables. Start from scratch or search the saved-query catalog by name, tag or keyword. The two query-source modes are exclusive:

  • Write NFQL stores an editable query directly in the panel.
  • Saved query stores a read-only reference. Every preview and dashboard refresh resolves the current saved-query revision automatically.

The visualization picker is available immediately, before choosing or writing the query. The saved query must be edited from Investigation and cannot be deleted while a dashboard panel references it. As the source changes, the studio compiles it in the background without scanning data and proposes compatible field roles. Superseded analysis requests are cancelled. Run one bounded data preview with Run preview or Ctrl/Cmd + Enter as the final verification before saving; errors stay next to the editor. A preview updates only result rows and never replaces axis, series or value choices.

API clients can inspect the output shape without reading any flow or session rows by posting the same inline or saved query source and time context to /api/dashboards/analyze. The response identifies grouping dimensions, aggregate measures and semantic field kinds such as time, IP, port or bytes; it never returns query result rows and rejects shapes wider than 64 fields.

Editing a live panel immediately reuses its latest bounded result: the saved visualization type, explicit field mapping and preview are available as soon as the studio opens. Run preview again after changing inline NFQL or selecting another saved query. Pressing Escape while NFQL completion is open closes only the completion menu; it does not discard the panel studio. Panels added from Investigation behave like ordinary panels and leave the optional description empty for the operator.

Use the Clone panel action to start from any existing panel. The clone opens in the same studio with its inline NFQL or saved-query reference, visualization mapping, description, size and latest preview already available. Obserae generates a distinct portable key and appends “copy” to the title; both remain editable before save. The original panel is unchanged.

Field choices are typed and never free-form, and they are available from query analysis before a data preview. For example, this result:

FROM sessions_consolidated
  | BETWEEN $from AND $to
  | STATS total = COUNT(max_client_to_server_bytes) BY client_ip
  | SORT total DESC
  | LIMIT 10

suggests client_ip as the labels and numeric total as the value for a donut. A panel cannot be saved from a stale or failed preview, or when a field is incompatible with the visualization.

For a hierarchical breakdown, keep every grouping field in STATS BY:

FROM sessions
  | BETWEEN $from AND $to
  | STATS traffic = SUM(client_to_server_bytes) BY server_ip, server_port
  | SORT traffic DESC
  | LIMIT 50

Visualization Studio recognises server_ip → server_port in query order and uses numeric traffic as the value. A donut with one group is rendered as a readable ring with collision-free labels and, by default, a total in its centre. Show total in center can hide that number when the aggregate is not meaningful for the panel. Two to four groups produce a drillable sunburst. Line, bar and scatter charts expose an independent X axis, one or more Y values, and optional ordered Split into series fields.

Numeric grouping keys, such as server_port, remain groups and keep their position in the hierarchy. A field cannot also be selected as the value. If a final KEEP or DROP removes every numeric aggregate, the studio leaves the value empty and asks for a numeric measure instead of treating the port or another numeric key as an amount.

For the common SOC question “which client sent how many bytes in each time slice?”, write or select a query such as:

FROM sessions
  | BETWEEN $from AND $to
  | STATS sent_bytes = SUM(client_to_server_bytes) BY BUCKET(opened_at, $interval), client_ip

Choose Heatmap, then map bucket to X axis, client_ip to Y axis and sent_bytes to Cell value. Swap axes transposes those selections. Timestamp fields use a real time axis with bounded zoom whether they are on X or Y. Missing cells remain empty unless the panel explicitly selects Replace with zero.

Time is an axis type, not a chart type. Selecting a timestamp for X axis therefore works with Line, Bar and Scatter. The studio derives time, numeric or categorical axis behaviour from the selected field type.

Choose Histogram to inspect the distribution of one numeric result column, for example flow bytes or session duration. It does not require a dimension: the renderer ignores null/non-numeric cells, chooses up to 50 bins from the bounded result and displays the number of observations in each interval.

Control operational rendering

The panel studio and Investigation Visualization Studio expose the same safe, persisted options:

  • Unit formats values as bytes, throughput, packets, counts, percentages or durations in axes, tooltips, heatmap scales and metrics.
  • Legend can be hidden or placed above, to the right or below the chart.
  • Show total in center controls the aggregate displayed inside a donut and is enabled by default for existing panels.
  • Missing values preserve gaps, connect line segments across gaps, or explicitly replace missing numeric cells with zero. NFQL NULL is retained until this rendering choice is applied.
  • Stack series combines comparable bar or line breakdowns.
  • Thresholds add up to eight info, success, warning or critical reference levels. Metrics take the colour of the highest crossed threshold; Cartesian charts draw labelled threshold lines.

These options are a closed data contract: dashboards cannot store arbitrary formatters, colours or JavaScript. The server validates units, severities and finite threshold values and sorts thresholds before persistence. Public dashboards render the same contract.

Inspect a panel in a large view

Every panel header includes Open large view, including while the dashboard is read-only and on published dashboards. The modal reuses the panel’s current bounded result and rendering configuration, so opening it does not execute a second query. Live refreshes update both the dashboard tile and its large view.

The large view supports charts, metrics and tables. Close it with its close button, the backdrop or Escape; keyboard focus returns to the panel button that opened it.

Create a useful time-based panel

Aggregate before charting. A chart with one point per flow is both noisy and expensive; a chart with one point per time bucket carries the signal.

FROM sessions
  | BETWEEN $from AND $to
  | EVAL bucket = BUCKET(opened_at, $interval)
  | STATS sessions = COUNT(*) BY bucket

Run an equivalent query in Investigation, select Visualize, choose Line or Bar, map the bucket column to X axis and sessions to Y values, then add it to an existing dashboard. When Use dashboard time controls is enabled, the studio replaces a LAST or BETWEEN stage with the typed dashboard bounds.

The renderer never executes custom JavaScript from a dashboard definition. Visualization documents contain only validated data fields.

Time-filter variables

Investigation queries and saved panel NFQL may use four special typed values:

VariableTypeMeaning
$fromtimestampStart of the selected time-filter window. Valid in EVAL and as a BETWEEN bound.
$totimestampEnd of the selected time-filter window. Valid in EVAL and as a BETWEEN bound.
$intervalinteger secondsA stable 1/2/5 bucket width chosen for roughly 500 points.
$range_sinteger secondsLength of the selected window.

Variables are lexer and AST nodes resolved by the compiler. They are not text substitutions and cannot inject NFQL. Investigation supplies them from its time filter; dashboards supply them from their authenticated or public time filter. An API or CLI execution without that context fails with a clear “dashboard time context is required” error.

Timestamp arithmetic uses whole seconds. For example, EVAL from_far = $from - 600 | BETWEEN from_far AND $from extends a panel query ten minutes before the selected start while keeping the bound stable for every row.

The maximum selectable window is 366 days. The dashboard runner returns at most 2,000 rows per panel, allows at most 24 panels and bounds the complete request to 30 seconds. One panel failure is shown on that panel; successful siblings remain readable.

Layout and refresh

Panels live on a 12-column grid. Select Edit, drag a panel by its header and resize it from the lower-right handle. Arrow keys resize the focused handle for keyboard use. Changes snap to the grid and persist when the gesture ends; the chart follows every size change without reloading data. On a narrow screen every panel expands to the full width. Select Done to finish and release the editing lease.

Only one browser session may edit a given dashboard at a time. Everyone else keeps a live read-only view naming the current editor. Leaving the page releases the lease immediately; if the browser crashes or loses connectivity it expires after 90 seconds. Locks are scoped to their resource, so other operators may edit a different dashboard or the cartography at the same time with independent session tokens.

When a panel at the right edge cannot grow because another panel occupies the start of its row, select Start new row on that panel. It moves below the preceding panels without changing their widths. Drag the resize handle once it has room, or select Full width to make it span all 12 columns immediately. Select Join previous row to let the grid pack it alongside earlier panels again. Row breaks and widths persist in dashboard YAML.

Delete is grouped with the dashboard actions in the top toolbar. Obserae shows a confirmation dialog before permanently removing the dashboard, its panels and all active read-only links.

The time filter follows the familiar observability workflow:

  • Quick select offers common windows from the last 15 minutes to the last 90 days.
  • Relative accepts a number of seconds, minutes, hours, days or weeks and keeps that window rolling against now.
  • Absolute fixes explicit local start and end timestamps for incident reconstruction.

Auto-refresh has common presets plus a custom value and unit. It may be turned off on an authenticated dashboard; enabled intervals are bounded from 10 seconds to one hour. Public viewers receive the same time filter when the publication permits it, while the publication’s minimum refresh remains enforced. Save defaults persists the current duration and refresh cadence for the next viewer; an absolute window is saved as its duration because dashboard defaults are rolling by design.

Each panel reports its NFQL query time in milliseconds at the lower-right. The number is the server-measured compilation plus execution time; hover it to see the split. During a manual or automatic refresh, a rotating indicator replaces the number on every panel while the previous visualization remains visible. The same feedback is present on public read-only dashboards.

Publish a read-only view

A user holding dashboards:share can publish one or more stable URLs for a dashboard. Anyone can open a publication without a login or secret. Use it for a wall display or a read-only operational handover.

  • The complete URL remains visible in the Publish dialog and can be copied again at any time.
  • A publication can expire, can be unpublished immediately, and can forbid viewers from changing the time range.
  • Public refresh cannot be faster than 30 seconds. The creator may require a slower minimum.
  • Public responses contain titles, layouts, visualization documents and result rows, but never the stored NFQL source.

Unpublishing the URL or deleting its dashboard stops the next refresh.

External domain, IP address and port

Open Settings → Public access and set Public base URL to the origin viewers actually use, for example https://soc.example:8443 or http://192.0.2.20:8080. This is especially important behind a reverse proxy. The value contains only the scheme, host and optional port; it does not change the daemon listen address. Leaving it empty uses the browser’s current origin.

The consolidated YAML configuration carries this setting:

public_access:
  base_url: https://soc.example:8443

Publication records remain instance-local and are excluded from the portable YAML configuration. Dashboard definitions and the public origin are included; publish the required dashboards after restoring another instance.

Permissions

Dashboard permissions are independent:

PermissionCapability
dashboards:readList/open dashboards and execute their stored panels.
dashboards:writeCreate, edit, reorder and delete dashboards and NFQL panels.
dashboards:sharePublish, inspect and unpublish public read-only URLs.

The built-in analyst group has read/write but cannot publish. The built-in auditor group is read-only. Admin has all three. Creating a public link is intentionally not implied by dashboard write access.

YAML configuration

Dashboard definitions are part of the consolidated configuration bundle. The dashboards section is a sequence keyed by each dashboard’s portable name. Reference dashboards are the exception: they are never exported, an import never removes them, and a name starting with std. is rejected because that prefix is reserved for them.

dashboards:
  - name: soc-overview
    title: SOC overview
    description: Live traffic and detection posture
    tags: [soc, wall]
    default_time_range_secs: 21600
    refresh_interval_secs: 30
    panels:
      - key: sessions-over-time
        title: Sessions over time
        nfql: >-
          FROM sessions | BETWEEN $from AND $to |
          EVAL bucket = BUCKET(opened_at, $interval) |
          STATS sessions = COUNT(*) BY bucket
        visualization:
          type: line
          mapping:
            x_axis: bucket
            values: [sessions]
          legend: bottom
        layout: {x: 0, y: 0, width: 8, height: 5, new_row: false}

An empty dashboard is valid and is represented by panels: [].

Importing a present dashboards section replaces the dashboard domain after the complete bundle has validated. Omitting the section leaves existing dashboards untouched. Runtime UUIDs, revisions and authorship do not travel; portable dashboard names and panel keys are stable identities.

A panel uses exactly one query source. Inline panels carry nfql; linked panels carry the saved query’s portable name:

panels:
  - key: current-investigations
    title: Current investigations
    saved_query: active-internal-scans
    visualization: {type: table}
    layout: {x: 0, y: 0, width: 12, height: 5}

The consolidated bundle imports its alerting.queries before dashboards, then resolves saved_query to the instance-local UUID. The UUID never appears in YAML.

Upgrading an existing installation is automatic. Inline panels keep their query text, visualization and layout unchanged; their saved-query reference is initially empty until an operator explicitly selects one. No dashboard export or manual database operation is required.

Operational limits

  • 200 dashboards per instance;
  • 24 panels per dashboard;
  • 64 selected value columns and 8 thresholds per visualization;
  • 4 ordered donut groups, or 3 series fields plus one X axis, per visualization;
  • 2,000 result rows per panel;
  • 512 KiB per dashboard document;
  • 10 public links per dashboard;
  • 366-day maximum query window.

These are rejection limits, not silent truncation of configuration. Result-row truncation is explicit in each panel response.