Lua/Honeycomb

Security & Data Isolation

How Honeycomb keeps your organization's memory isolated, scoped, and under your control: workspace isolation, Spaces and grants, sensitivity ranking, API keys, and the data lifecycle.

Organizational memory is only useful if you can trust it with your organization's most sensitive context. This page explains the guarantees Honeycomb is built on: how your workspace is isolated, how every read is scoped to what the caller may see, how sensitive content is kept from over-sharing, and how you delete or export your data when you need to.

At a glance

  • Your workspace is a fully isolated tenant. Every record is bound to your organization, and that boundary is enforced in the database layer itself — not just in application code. There is no query path that returns another organization's data.
  • Every read is scoped by Spaces and grants. Within your workspace, content belongs to Spaces that mirror real-world access: private threads stay private, public channels are org-visible, and sharing is always explicit.
  • Ingest is private by default. When Honeycomb can't prove who should see something, it fails closed to private — never to org-wide.
  • Sensitivity ranking blocks over-sharing. Content is classified public / internal / confidential / restricted, and confidential-or-above content can never be promoted to org-wide visibility.
  • API keys are workspace-scoped, hashed at rest, and revocable — from the console, in one click.
  • Your data stays yours. Supersession preserves history, tombstoning deletes records and everything derived from them, purge forgets whole sources, and export gives you a portable copy with integrity receipts.

How every request is scoped

Each API request passes through the same chain before it touches any data. Every step fails closed: an unknown key, an unknown workspace, or an unverifiable acting user narrows access — it never widens it.

Workspace isolation

Your workspace is a single-tenant boundary around everything Honeycomb stores for you: entries, memories, facts, entities, graph relationships, insights. The workspace a request operates on is derived server-side from the API key — it is never taken from anything the client sends. Isolation is then enforced again in the database layer on every row, so even a hypothetical application bug cannot cross the boundary.

Space-level access

Within your workspace, every readable record belongs to one or more Spaces — access containers that mirror where the content came from:

ContentDefault access
A private email or DM threadOnly its participants
A private channelOnly the channel's members
A public channelEveryone in your organization
One person's notes or agent chatsOnly that person
Content with ambiguous provenanceQuarantined as private until provenance is known

A record is visible to a user only if one of its Spaces is org-visible or that user holds a grant on it. Sharing adds a grant; revoking removes it — and a revocation sticks, even when the source system redelivers the same content later. The full model, including sharing and the owner role, is covered in Spaces and permissions.

For security reviewers: the model in ReBAC terms. If you evaluate systems against Google's Zanzibar model, Honeycomb's Space layer will look familiar: a Space is an object, a grant is a relation tuple, records inherit access from the containers they are stamped into, and every read evaluates the check inside the database itself (Postgres row-level security), with the vector index filtered to the same Space set and its hits re-validated against the database before anything is returned. Two properties differ in your favor: permissions live in the same transactional store as the content, so a revocation takes effect on the next query with no consistency-token machinery; and group membership (the workspace roster) is flattened into explicit, auditable grants rather than resolved through nested group expansion at read time. Access is deny-by-default throughout — an unresolvable caller gets org-visible content only, and enforcement errors fail closed.

Note: Space scoping applies to every read path — Ask, search and recall, entity timelines, and the MCP tools. There is no side door that returns unscoped results.

Acting on behalf of a user

When your agent or app makes a request for a specific person, pass their identity in the x-acting-user header. Honeycomb resolves them to a known person in your workspace and scopes the read to exactly the Spaces they can access:

curl -X POST "$HONEYCOMB_URL/api/v1/search" \
  -H "Authorization: Bearer hck_live_4f8a2c91d0b7" \
  -H "x-acting-user: [email protected]" \
  -H "Content-Type: application/json" \
  -d '{"query": "renewal terms for the Q3 contract", "limit": 5}'

Three properties make this safe to build on:

  1. The header only works on keys with the act-as-user capability. A key without it ignores the header entirely, so a leaked ordinary key cannot impersonate anyone.
  2. Unresolvable means org-visible only. If the acting user can't be verified against a known person, the read falls back to org-visible content — never to full-workspace visibility, and never to someone else's private Spaces.
  3. Cryptographic assertions are supported. Platforms integrated with Lua can pass short-lived signed identity assertions instead of a plain header; these are verified cryptographically and always take precedence. A workspace can require them, ignoring the plain header entirely — see Identities & approvals.

The email a request acts as is what unlocks that person's private Spaces, so which email belongs to which person is itself an access decision. Identities & approvals covers how Honeycomb resolves handles to people — and why attaching a new email to someone needs their explicit confirmation.

Private by default

Ingest routing is deliberately conservative. When content arrives — through the ingest API, a connector, or file upload — Honeycomb resolves exactly one Space for it based on its provenance, and every ambiguity resolves toward less visibility:

  • An email thread is granted only to its participants.
  • A channel is org-visible only when the source platform says it's public. An unknown channel is treated as private.
  • Content whose owner can't be strongly identified is quarantined privately rather than guessed at.
  • Org-wide visibility is always an explicit opt-in on the write, never a default.

Everything derived from a record — distilled memories, extracted facts, graph links — inherits its access. When a derived item draws on multiple sources, it takes the most restrictive intersection of their access, so a private message's substance never leaks through a summary.

Sensitivity ranking

Independently of who can access it, every piece of content is classified on a four-tier sensitivity scale at ingest:

RankTierExamplesCan become org-visible?
0publicPublished docs, public announcementsYes
1internalOrdinary work content (the default)Yes
2confidentialPersonal identifiers, content marked confidential, external-party correspondenceNever
3restrictedCredentials, API tokens, private keys, government IDs, card numbers, and personal-subject correspondence (family-law / personal-status / health matters) from an external/personal senderNever

Detection combines deterministic pattern matching (credential formats, checksum-validated identifiers), explicit markers like "confidential" or "do not share", and sender-domain trust.

Each Space carries a sensitivity ceiling — the highest rank of anything inside it. A Space whose ceiling reaches confidential or above can never be promoted to org-wide visibility. This guard is enforced in the database layer as well as the application, so a single sensitive document landing in a Space permanently blocks that Space from going org-public.

Warning: Sensitivity ranking limits widening of access; it doesn't retract grants that already exist. If credentials are pasted into a channel, everyone already in that channel can still see them — rotate the credential and tombstone the record.

API keys

Every API request authenticates with a Bearer key that starts with hck_:

curl "$HONEYCOMB_URL/api/v1/memories" \
  -H "Authorization: Bearer hck_live_4f8a2c91d0b7"
PropertyWhat it means for you
Workspace-scopedA key is bound to exactly one workspace at creation. It cannot read, write, or even name another workspace.
Hashed at restHoneycomb stores only a one-way hash. The full key is shown once, at creation — after that it is unrecoverable, so store it in your secrets manager immediately.
RevocableRevoking a key takes effect immediately. Revocation is scoped to your workspace, so no one outside it can revoke (or enumerate) your keys.
ScopedEvery key carries a scope chosen at creation: Read-only (search and recall) or Read & write (adds saving and updating memory). A scope is fixed for the key's lifetime — changing it means revoking and creating a new key. A third tier that can permanently delete memory exists only on operator-provisioned credentials; it can't be created from the console.
Capability-flaggedThe act-as-user capability is opt-in per key. Mint separate keys for services that need it and services that don't.
Rejected fail-closedAn unknown or revoked key gets a 401. There is no fallback workspace. A request beyond the key's scope gets a 403 with code INSUFFICIENT_SCOPE.

Manage keys in the console under Admin → API keys:

  1. Open Admin and select the API keys tab for your memory store.
  2. Click Create key, name it for the service that will hold it, and pick its scope — Read & write for agents that save what they learn, Read-only for anything that should never change memory.
  3. Copy the full key now — only a short display prefix is shown afterward. Each key's scope is shown as a badge in the list.
  4. To rotate (or change a key's scope), create the replacement key first, deploy it, then revoke the old one.

Note: Treat each integration as its own key. Per-service keys make rotation painless and let you revoke one integration without touching the rest.

Agents and MCP

Agents connect through the same security model — MCP is a protocol on top of the API, not a bypass. The six tools (Agents and MCP) split cleanly:

  • Read toolshoneycomb_search, honeycomb_recall, honeycomb_context — run scoped to the acting user's Spaces, exactly like the REST read endpoints.
  • Write and management toolshoneycomb_ingest, honeycomb_upload, honeycomb_manage — operate at the service level of the connecting key.

So an agent answering on behalf of a user can only surface what that user could see themselves.

Emergency lockdown

If you ever suspect your memory store is exposing something it shouldn't, you can freeze all reads instantly — without deleting anything or tearing the store down. Locking a store is a single admin toggle:

curl -X PATCH "$HONEYCOMB_URL/api/v1/tenants/:id" \
  -H "Authorization: Bearer hck_live_4f8a2c91d0b7" \
  -H "Content-Type: application/json" \
  -d '{"lockdown": true}'

While a store is locked:

  • Every read path returns 423 — Ask, search and recall, the graph and entity timelines, suggestions, insights, and the read tools over MCP. There is no read surface that stays open.
  • Ingest and administration keep running. New content still flows in and is stored normally, so you lose no data during the freeze — you're pausing access, not the pipeline. When you flip lockdown back to false, reads resume against a fully up-to-date store.
  • Export is frozen too, so a locked store can't be drained through the bulk endpoint.
  • It fails closed. If the lock state can't be read for any reason, reads are refused rather than allowed.

Lockdown is the fast, reversible response for a suspected leak. For a compromised credential specifically, revoking the key (below) is even faster — authentication runs before any read, so a revoked key can't reach data at all.

Note: Lockdown is a per-store switch you control. It doesn't delete anything — pair it with tombstone or purge if specific records need to be removed for good, and with key rotation if a credential leaked.

Data lifecycle

You control what Honeycomb remembers, for how long, and where a copy of it goes.

Supersession

When a source record changes — a ticket is updated, a doc is revised — the new version supersedes the old rather than silently overwriting it. Current-state queries return only the latest version; the history remains available for point-in-time questions ("what did we believe in March?"). See Search and recall for as-of queries.

Deleting a record (tombstone)

POST /api/v1/entries/tombstone hard-deletes one source record's entire version chain — the current version, its superseded history, and everything derived from it (memories, facts, graph edges, syntheses):

curl -X POST "$HONEYCOMB_URL/api/v1/entries/tombstone" \
  -H "Authorization: Bearer hck_live_4f8a2c91d0b7" \
  -H "Content-Type: application/json" \
  -d '{"externalRef": "zendesk:ticket-48211"}'
{
  "entriesDeleted": 2,
  "memoriesDeleted": 7,
  "factsDeleted": 3,
  "edgesDeleted": 4,
  "edgesDetached": 1,
  "synthesisDeleted": 0
}

Forgetting a source (purge)

POST /api/v1/admin/purge deletes an entire corpus by selector — typically everything from a disconnected source. It requires you to echo the selector in confirm (a typo can't delete the wrong corpus), and supports a dry run:

curl -X POST "$HONEYCOMB_URL/api/v1/admin/purge" \
  -H "Authorization: Bearer hck_live_4f8a2c91d0b7" \
  -H "Content-Type: application/json" \
  -d '{
    "externalRefPrefix": "zendesk:acct-9917:",
    "confirm": "zendesk:acct-9917:",
    "dryRun": true
  }'

Purge works in batches: call it repeatedly until the response reports "done": true. Always dry-run first and review the matched count.

Note: If the tombstone or purge endpoints return 404, lifecycle management isn't enabled for your workspace yet — ask your Lua contact to turn it on.

Exporting everything

GET /api/v1/export returns a portable export of your workspace. The default response is a manifest; add ?full=true to stream the complete bundle. Every item in the bundle carries a SHA-256 integrity receipt, so you can verify the export independently:

curl "$HONEYCOMB_URL/api/v1/export?full=true" \
  -H "Authorization: Bearer hck_live_4f8a2c91d0b7" -o export.json

Encryption and platform protections

  • Encryption in transit. All API, MCP, and console traffic runs over HTTPS (TLS). Authentication is header-based — no cookies on the API surface, so there is no cross-site credential to steal.
  • Rate limiting. Requests are rate-limited per agent with generous, firehose-friendly limits. Responses carry X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset; exceeding the limit returns 429 with a Retry-After header.
  • Webhook verification. Inbound connector webhooks (Slack, GitHub) are verified against the platform's own signatures — a forged payload is rejected before it can write anything.

What Lua operates for you

Honeycomb is a managed service. Your team works entirely through the API, MCP, and the console; Lua runs everything underneath:

Lua operatesYou never have to
Hosting, storage, and the isolation enforcement itselfRun databases or verify isolation configuration
Upgrades and security patchesSchedule maintenance windows or migrate data
Monitoring, health checks, and incident responsePage yourself when a component degrades
Workspace provisioning and connector infrastructureManage tenant plumbing or webhook endpoints

Administrative operations — provisioning workspaces, operating the service — use a separate, dedicated credential surface that is never derived from customer API keys.

FAQ

QuestionAnswer
Can another organization ever see my data?No. Every record is bound to your workspace, and the boundary is enforced in the database layer on every query. An unknown key or workspace is rejected — there is no fallback that crosses tenants.
What happens if an API key leaks?Revoke it in Admin → API keys; revocation is immediate. Only a hash is stored server-side, and the key was scoped to your workspace — it never granted anything beyond it.
Can an agent read a user's private content?Only when the key carries the act-as-user capability and the acting user actually has access to that content. A spoofed x-acting-user header on an ordinary key is ignored.
What does a read return with no verified acting user?Under per-user enforcement, org-visible content only — never full-workspace visibility, and never another user's private Spaces.
Can confidential content become org-visible?No. The sensitivity ceiling blocks promotion of any Space containing confidential or restricted content, enforced at the database layer as well as the application.
Is deleted data really gone?Tombstoning deletes the record's full version chain plus all derived memories, facts, and graph edges. Purge does the same for a whole source.
Can I get all of my data out?Yes — GET /api/v1/export?full=true streams a portable bundle with SHA-256 integrity receipts for every item.
Is my data encrypted in transit?Yes. All traffic to the API, MCP endpoint, and console runs over HTTPS.

Where to go next

  • Identities and approvals — how handles resolve to people, and the approval that gates access-bearing email links.
  • Spaces and permissions — the full access model: grants, sharing, revocation, and promotion.
  • API reference — request and response shapes for every endpoint on this page.
  • Agents and MCP — wiring agents into permission-aware memory.
  • Console — the Admin screen, key management, and access views.