Zumik
Core concepts

Handles and fingerprints

Opaque public IDs that callers hold, versus internal tenant-scoped HMAC fingerprints that never leave the isolation boundary - and why raw content hashes are never exposed.

Zumik uses two completely different kinds of identifier, and keeping them separate is a security boundary, not a style choice.

  • Public handles are what you hold. They are opaque, random, and safe to log.
  • Internal fingerprints are keyed HMACs the platform computes for deduplication and trace analysis. They never leave the tenant's isolation boundary and are never returned to a caller.

Public handles

Every public object has an opaque, prefixed, random ID:

art_01jy7n3q8v...   bnd_01jy...   ses_01jy...
br_01jy...          snp_01jy...   rsp_01jy...

The suffix is 26 random Crockford-base32 characters - roughly 130 bits of entropy - so handles are unguessable and never collide. The prefix only tells you the object kind. It tells you nothing about the content, and two artifacts with identical bytes get entirely unrelated IDs.

Why raw hashes are never handles

It is tempting to use a content hash as a reusable handle: ctx_sha256:91af.... Zumik refuses to, because a content hash leaks equality.

A raw content hash creates real risks:

  • Callers treat it as a durable, reusable capability that the platform never promised.
  • Identical hashes across tenants make accidental cross-tenant correlation easy.
  • Deletion gets confusing: re-uploading the same bytes silently revives the old hash and any cache relationship attached to it.
  • A leaked hash reveals that two systems hold identical content.

Opaque random handles have none of these properties. Re-uploading identical content after a delete produces a new handle and restores nothing.

Internal fingerprints

Inside the boundary, the platform still needs to recognize "this is the same content we saw before" to deduplicate storage and analyze prefix families. It does this with a tenant-scoped keyed HMAC:

logical_fingerprint =
  HMAC-SHA256(
    tenant_fingerprint_key,
    canonicalization_version || artifact_type || normalized_content
  )

Three properties make this safe:

Key rotation breaks linkage on purpose

The fingerprint key is rotatable, and rotating it is a feature. After rotation, previously equal content no longer fingerprints equal, which intentionally severs old equality relationships. This is one of the mechanisms a purge relies on: once linkage is broken, stale dedup relationships cannot quietly reconnect deleted content.

Fingerprints exist only for internal deduplication and diagnostics. They are never part of any request or response, never appear in logs you can read, and never serve as a handle. If you can see an identifier, it is an opaque public handle.

On this page