Skip to content

API keys

Organization API keys (eb_sk_…) authenticate servers and SDKs acting as the whole organization. Org-scoped, least-privilege, shown once — and why they're stored as SHA-256, not Argon2id.

Updated

An organization API key authenticates a server or SDK acting as the whole organization — not on behalf of any one signed-in user. It is the server-side counterpart to the user-facing OAuth flow: where OAuth answers “which user is this?”, an API key answers “which organization is this?”.

  • Shape: eb_sk_… — the sk means secret key.
  • Created in: Settings → API keys by an org admin.
  • Scopes: least-privilege org:* permissions.
  • Calls: /api/v1/org/*.

A key is a server secret — never ship it in an app. An eb_sk_… key acts as your entire organization and can be extracted from any downloadable binary (APK, SPA bundle). Client apps use an OAuth client_id (public, PKCE-protected) instead. If a key was ever embedded or shared, revoke it.

What a key carries

Each key is minted with:

  • Least-privilege scopes — pick only the org:* scopes the integration needs (org:passes:read, org:passes:write, org:facilities:read). See Scopes.
  • An optional expiry — after which the key stops working.
  • An optional source-IP allowlist — requests from other IPs are rejected.

The key is shown exactly once, at creation. EntryBit stores only its hash and can never display it again — if it’s lost, revoke it and mint a new one. See Create & manage keys.

Why keys are stored as SHA-256, not Argon2id

User passwords at EntryBit are hashed with Argon2id. API keys are hashed with plain SHA-256 — and that is deliberate, not a shortcut.

An API key is 256 bits of CSPRNG output. There is no dictionary, no pattern, no human-memorable structure — so an offline preimage or brute-force search against any hash is computationally infeasible. Argon2id exists to slow down guessing of low-entropy secrets (passwords people choose); it buys nothing against a full-entropy random key.

Meanwhile, a memory-hard KDF on the hot, per-request verify path would be actively harmful:

  • Latency — every authenticated API call would pay Argon2’s deliberate cost.
  • A DoS lever — an attacker POSTing garbage keys would force expensive Argon2 work per request, turning the verification step into a CPU-exhaustion amplifier.

A fast hash is therefore the correct choice for high-entropy machine credentials — the same doctrine EntryBit applies to OAuth client secrets and refresh tokens. Argon2id for what humans choose; SHA-256 for what a CSPRNG generates.

Keys vs OAuth, at a glance

API keyOAuth access token
Acts asThe organizationA signed-in user
Credentialeb_sk_… (long-lived secret)JWT (~15 min, from a client_id + PKCE)
Endpoints/api/v1/org/*/api/v1/*
Scopesorg:passes:*, org:facilities:readpasses:*, invites:read, …
LivesOn your server, in a vaultIn the app, refreshed as needed

Next steps