Skip to main content

Data lake

Huntbase can query telemetry that lives in a data lake as well as data it reaches through a connection. There are two ways in, and you can use both at once:

  • Bring your own lake — point Huntbase at an Apache Iceberg store you already own. Your raw events stay in your bucket and Huntbase queries them in place. Your lake is read-only to Huntbase: it never sends events to it.
  • Ship logs to Huntbase — send events from a log shipper (Fluent Bit, Vector, rsyslog, syslog-ng) straight into the Huntbase data lake. This needs no store of your own, and is the shortest way to get data in.

Either way you query the result with KQL (Huntbase Lake) or Search (Huntbase Lake) in the Explorer. One query can read the Huntbase data lake and your own lakes together, but reading your lake costs you scans of your bucket, so Huntbase reads it only when you ask. See Querying the lake.

Beta

The data lake is currently rolling out and may not be enabled for your organization.

Bring your own lake​

A lake store is set up like any other connection — see Create a connection — with one difference that matters, covered below.

Huntbase mounts your catalog read-only and queries the tables where they are — this is called federation. Nothing is copied into Huntbase, and nothing is written back to your lake: ingest keys can't send to it, and detections found in your data are stored in Huntbase, not in your bucket.

Choose how your tables are catalogued​

The first question on the Connect step is How your tables are catalogued, and it decides what else you are asked for. There are three answers:

Catalog typeUse it whenWhat Huntbase then asks for
Give us a bucket — Huntbase runs the catalogYou have object storage and nothing else. This is the default and the shortest path.Bucket / warehouse location
AWS Glue Data CatalogYou are on AWS and already use Glue. Nothing to stand up.Bucket / warehouse location, and a Glue Catalog ID only if the catalog is in a different AWS account from your key
I already run an Iceberg REST catalogYou operate an Iceberg REST catalog service of your own.The catalog's URI

The form only shows the fields your answer needs, so switching the catalog type changes which settings appear.

What to have ready​

You'll needNotes
Object store endpointPick your AWS regional endpoint from the list, or type your own for MinIO, Ceph, Cloudflare R2 or any other S3-compatible store.
RegionPick from the AWS regions, or type the region string your store expects. us-east-1 is the usual answer for MinIO.
Access key and secret keyS3-compatible credentials. Read access to the warehouse prefix is enough for queries; write is used only for Iceberg table metadata.
Catalog settingsWhichever the table above says your catalog type needs.
Apache Iceberg only

Bring your own lake reads Apache Iceberg tables over Parquet in an S3-compatible store. Delta Lake tables are not read directly.

The rest catalog type currently connects to an Iceberg REST catalog that does not require authentication. Managed catalogs that speak the same protocol but authenticate — Databricks Unity Catalog, Snowflake Open Catalog, Apache Polaris, AWS S3 Tables — are not connectable yet. Support for them is planned; talk to us if you need one.

Creating and provisioning the store​

Search for the lake product on the Product step, fill in the settings and keys on Connect, then click Create & check.

Creating the connection is only half of it. Unlike every other product, a lake store has to be provisioned before it will answer anything, and that starts automatically when the connection is created. The Verify step shows the progress:

StepWhat is happening
Reach the lakeConnecting to the Iceberg catalog and object store.
Register catalogCreating the store's query catalog.
Attach tablesBinding the telemetry tables Huntbase reads.
Join federationIncluding the store in federated lake queries.

Provisioning continues if you close the page. You can follow it, and re-run it, from the Lake store card on the connection's own page.

warning

Until provisioning completes the store answers nothing, and lake queries skip it. A store that is merely healthy is not necessarily queryable — check the federation badge below.

In federation, or excluded​

The Lake store card carries a badge that answers the only question that matters for results:

BadgeMeaning
In federationThe store is active and provisioned, so lake queries read it.
ExcludedLake queries skip it. Hover the badge for the reason — never provisioned, provisioning failed, provisioning still running, or the connection is inactive.

This matters because an excluded store makes your results narrower without making them look wrong. When a query skips a store, the results panel says so — see Which stores answered.

Telemetry › Destinations shows every lake of yours side by side under Your lakes — Huntbase reads these: whether it's in federation, and its readiness trail. Where the Telemetry page is available, a lake's connection page links to Browse with your lakes included.

When provisioning fails​

The trail names the step that failed and gives you a short remediation. The technical diagnostic is deliberately terse (something like probe: ConnectionRefusedError) because Huntbase does not echo back what your catalog endpoint returned. Treat it as a hint, and check in this order:

  1. Are the object store endpoint — and the catalog URI, if you supplied one — reachable from outside your network?
  2. Do the access keys still work, and does their policy cover the warehouse prefix?
  3. Are the region and warehouse location right?

Then use Retry provisioning.

Ship logs to Huntbase​

If you would rather send events than expose a store, mint a telemetry ingest key and point a log shipper at Huntbase. Every key sends to the Huntbase data lake. Keys are never bound to a lake of your own, which Huntbase only reads.

Mint a key​

Click New ingest key on the Telemetry page. Onboarding's Telemetry step mints keys too. Where the Telemetry page isn't available, use the Send telemetry to Huntbase card on the Connections page, or Telemetry ingest keys under it, and click New key.

If you see Request access instead of your sources, ingest is not enabled for the organization you are working in. Use the button to ask — it fills in the details support needs to turn it on.

Give it a Source label that names the sender — something like edge-fluentbit-eu. One key per shipper or source means a single noisy or compromised sender can be revoked on its own.

warning

The token is shown once, when you create it. It is stored only as a hash, so it cannot be recovered or shown again. Copy it before you close the dialog — the dialog will ask you to confirm if you try to dismiss it without doing so.

Afterwards the key is identified only by its prefix (for example hbik_3f9a2c1).

Where to send it​

Ingest endpoint under the table on Telemetry › Sources (or the Send telemetry to Huntbase card) shows the endpoint for your deployment, so what you read there is what you paste. It is the same host this app talks to:

Method and pathPOST /api/v1/telemetry/ingest
HostYour Huntbase host, shown on the card.
Port443
AuthAuthorization: Bearer <your ingest key>

Shippers that want host, port and path separately (Fluent Bit, for example) will find them listed individually there.

Before wiring anything up, you can prove the network path from the machine that will do the shipping:

curl -fsS https://<your-huntbase-host>/api/v1/telemetry/ingest/health

That probe is unauthenticated by design, so it works before any key exists — and it distinguishes "the firewall blocks this" from "the key is wrong", which is otherwise a long afternoon.

Configure your shipper​

The mint dialog generates ready-to-paste configuration for Fluent Bit, Vector, rsyslog and syslog-ng, plus a command that checks Huntbase is reachable before you involve any secret. Its curl tab sends one test event with the new key, so you can see it arrive before you configure a shipper; the endpoint answers {"accepted":1,"rejected":0}. You can bring the configuration back up later with ⋯ › Shipper config on Telemetry › Sources (or the key's Config action where the Telemetry page isn't available) — with a placeholder in place of the token, since we cannot show it again.

What the endpoint accepts:

  • A single JSON object, a JSON array, or newline-delimited JSON.
  • Optionally gzipped.
  • Up to 10 MB per request, before and after decompression.

It answers with a count of accepted and rejected records. A malformed record is counted, not retried, and never fails the rest of the batch — so a shipper should treat the response as success and not resend.

What Huntbase adds to each event​

Nothing changes in what you send, and the event is stored exactly as it arrived. Alongside it, Huntbase records a few things it works out when it accepts the event:

AddedHow
Event timeThe event's own timestamp, from the first of time, timestamp, @timestamp, ts or eventTime that can be read as a time (ISO 8601, or epoch seconds, milliseconds, microseconds or nanoseconds), in UTC.
HostThe first of host (a string, or an object with name or hostname), hostname, host.name or computer.
Source labelThe label of the ingest key the event arrived on.
ShipperFluent Bit, Vector, rsyslog, syslog-ng or other, recognized from the shipper's User-Agent.

These values give every event the time, host and source fields that Search telemetry filters and charts on. They also give the Telemetry Overview its ingest lag. To get the most from them, send a timestamp and a host name in one of those fields. You don't have to rename anything you already send.

Revoking a key​

On Telemetry › Sources, ⋯ › Revoke, then confirm. Shippers using the key start failing immediately. The row stays listed, marked Revoked, so the history of what existed is preserved.

Status and Last event are the quickest way to tell a key that is wired up and working from one that was minted and never configured. Status is based on the last accepted event, so a key that is used but only sends records that are refused doesn't show as receiving. See Source statuses.

Querying the lake​

Pick KQL (Huntbase Lake) in the query bar's language picker. Unlike the other languages it needs no connection, because a lake query can search Huntbase's own store and every one of your stores that is in federation together. If you have no lakes of your own, the bar shows Data lake instead of a connection picker.

When you do have lakes in federation, a Stores pill takes its place. It shows what Run reads: by default the Huntbase data lake and every one of your lakes in federation (Lake + N). Pick Huntbase Lake only to leave your lakes out. The line under a new tab's input names the stores a run will read, and the compact bar's summary names them after a run.

When your lake is read​

Reading your lake scans your bucket, which you pay for, so nothing reads it on a guess:

WhereReads your lake?
KQL (Huntbase Lake) run from QueryYes, every store in federation, unless you pick Huntbase Lake only in the Stores pill.
A KQL (Huntbase Lake) query that Auto runs when you press EnterNo — the Huntbase data lake only.
Search (Huntbase Lake)Only when you ask: press ⌘/Ctrl+Enter instead of Enter, or include your lakes in the stores pill. See Search telemetry.
ScoutYes, within your scope and permissions.
Check against history on a watcherYes, every store in federation.
Live tailNo — the Huntbase data lake only.
A watcher's readiness chipNo — it checks the Huntbase data lake only.
The entity timelineOnly when you click Include it in its note.

Daily scan budget​

Before Huntbase reads your lake it estimates how much of your bucket the read will scan, and charges the estimate against your organization's Daily scan budget for your own lake (50 GB a day unless an admin changes it — see Capabilities). The budget is shared by every reader, and the Huntbase data lake never counts against it.

When a query would go over what's left of today's budget, your lakes drop out of that run and the Huntbase data lake part still runs. The results say so: your stores are listed as excluded because the scan budget is used up. A search that would go over asks you to narrow the view instead.

Which stores answered​

Because one query can read several stores, the results panel tells you what it actually searched:

NoticeWhat it means
Searched N storesExpand it to see which. Each store can be used to narrow the results to just its rows.
N stores were excludedA warning, not a footnote: the store was unavailable, isn't answering, or today's scan budget is used up, so your results may be incomplete. The notice links to the connection.
Your lake wasn't searchedThe run didn't ask for your lake — for example a query that Auto ran. Click Include it to run it again with your lake.
Showing the first N rowsA row cap was applied. Add `
A column is empty for some eventsNo mapping exists for that field in those events, so those rows are empty rather than guessed.

A lake that stops answering doesn't fail the whole query. Huntbase checks it, leaves it out of the run, and the notice says it isn't answering, so results cover your other lakes. It's left out of other reads for a few minutes, then tried again.

Events in your lake written as plain OCSF 1.x fill the same hb_ surface columns as the formats Huntbase maps itself, so one surface query covers both. In Search, each OCSF event's summary line shows the fields that matter for its class: for a sign-in, for example, the outcome, user and source address, with the field your search matched highlighted.

Every result row carries a store column showing which store it came from, and you can narrow to one store from there.

To look at shipped events without writing a query, use Search telemetry. Search filters by clicking and shows the same KQL (Huntbase Lake) query it runs.

Next steps​

  • Query languages — writing lake KQL, and what the dialect supports
  • Connections — creating and managing connections
  • Telemetry — the health of each telemetry source and its ingest key
  • Search telemetry — filter shipped events by clicking
  • Watchers — standing rules over the data you have connected