0.16

Every published okengine release, newest first.

all series · 0.17 · 0.15

v0.16.0

✨ Added

Console — Auth & shell

  • Access (/access) manages API keys: create, edit, refresh expiry (same secret), revoke, rotate, reveal-once secret, usage from Runs, and a Bearer call example. Sidebar, command palette, and ⌘6. Session ?next= may restore /access.

Runtime

  • fx.auth.createApiKey / listApiKeys / revokeApiKey / rotateApiKey / updateApiKey — session-only, issuer derived from the live principal. Effects auth:api-keys.
  • gate.auth always creates a shared API key store (HMAC-SHA-256 with gate.auth.secret). Host and Console share it via attachHostToConsole.
  • fx.store(db).select().from(table) infers the declared row from store.schema.table() / Drizzle $inferSelect. select({ … }) projections stay SqlRow[]. Export InferSelectRow.

💥 Breaking Changes

Runtime

  • API key Bearer is the issuer: fx.auth.userId / fx.operator.id and WideEvent principal are creatorId. The credential is fx.auth.apiKeyId and dimensions.api_key.
  • Key secrets hash with HMAC-SHA-256 (gate.auth.secret). Stolen table rows are not portable across apps.
  • Per-key ipAllowlist and rateLimit are enforced on the HTTP Bearer path (401, no api_key dimension).

Console — Auth & shell

  • User-plane Access create requires creatorUserId. The ceiling is that user's grants — console:* no longer adds application scopes.
  • Production no longer seeds a demo API key.

♻️ Changed

Console — Chrome

  • Access sidebar and command-palette mark is BiometricAccessIcon so it no longer shares Vault's key glyph.

Console — Auth & shell

  • Access create sheet uses plane / issuer / scope chips and expiry presets (never · 30d · 90d · custom 7d / 12h). Issuer and scopes have in-header search. Scopes group by Module:Action prefix. User / Operator bands and the create-sheet Plane choices use UserIcon and CrownIcon. Rotate requires typed ROTATE. The inspector matches Vault: identity strip, usage tokens, ExplorerEmpty.
  • Access key inspector groups scopes by Module:Action, lists allow entries as IP/Host rows, frames the Bearer call like a Trace request, and labels past expiry as expired. Revoked / unused / expired keys get a posture strip. Refresh resets the deadline from now (snaps 30d / 90d) without rotating the secret.
  • Access create and edit share expiry, an add-one allow list (IPv4, IPv6, localhost, or FQDN — junk is dropped), and a split rate (max / every / s·m·h·d·ms). Allow rows show IP vs Host. Edit can still change them after mint.
  • Console default roles grant member only. Demo User scopes follow the live Manifest (no leftover Skyport booking:create / reports:export on every app).
  • Invoke-as seeds ten identities from owner to guest. Demo User (user_demo) and Member (user_member) keep their ids. Guest has no scopes. A Keel Manifest always seeds every Keel Gate scope (member, task:write, comment:write, files:write, project:admin, member:admin, webhook:admin) onto owner and the Access role ladder.

Runtime

  • API key ipAllowlist entries may be hostnames. Verify resolves them and matches the client IP (lookup failure is closed).

Dev, Keel & create-oke

  • Keel flow helpers (nextIdentifier, writeActivity, pushInbox, upsertTask) take the exported Fx type — no hand-rolled fx shape and no as never at the call site.
  • Keel seed featured members are a ten-rung owner → guest ladder and include demo@example.com and member@example.com.

Docs

  • Flow and fx pages call out typing extracted helpers as Fx. Store documents inferred select().from(table) rows.
  • Gate documents API keys (issuer identity, fx.auth methods, Access). fx lists the methods and apiKeyId. Vault points keys to /access.

🐛 Fixed

Console — Auth & shell

  • Access create uses the issuer's identity plus role grants, and only offers scopes that exist in the app catalog.
  • Access edit shows the frozen issuer and lists that principal's grantable scopes — not only the actor's user-plane ceiling. The sheet stays editable while the key list refreshes.

Runtime

  • FxAuth identity (userId / scopes / apiKeyId) is distinct from key-management methods, so createFx and wholesale Fx mocks typecheck. Store cache invalidation ignores auth:api-keys. SQL select overloads keep inferred rows without implicit-any.
  • Edge createFx and Store-only oke() load fx.auth key methods only via computed import.meta.require, so graphs that never manage keys stay under the existing bundle budgets.
  • API keys persist in public oke_api_keys on the app store.sql() connection (DATABASE_URL). A standalone restart hydrates a fresh gate.auth.apiKeyStore and Bearer still verifies — no Console. Access attaches that host instance, not oke_console.oke_api_keys.