IAM is the sole user store. Base creates ephemeral (unsaved) auth records
from JWT claims for rule evaluation. No writes to _superusers or users
collections. IAM admins (isAdmin=true) get _superusers collection context
for full access. Regular users get users collection context.
Zero local user records. Zero _superusers records. IAM is truth.
When an IAM JWT has isAdmin=true, the user is mapped to a _superusers
collection record in Base. This gives IAM admins full superuser access
to all collections — no separate _superusers auth needed.
Removed the local token fallback for _superusers. IAM is the sole
auth source in external-only mode. No hacks, no PB legacy.
- loadAuthToken now falls back to local validation for _superusers tokens
when JWKS validation fails in external-only mode. Non-superuser local
tokens are still rejected. Fixes seeding with IAM enabled.
- Scrub PocketBase references from docs, SDK, and UI config
Implements OIDC authorization code flow with PKCE for the superuser
login page (/_/). When BASE_OIDC_ISSUER is set, the email/password
form is hidden and replaced with a single "Sign in" button that
redirects through the OIDC flow. The callback stores the auth token
in localStorage and redirects to the admin UI.
Routes:
GET /_/auth/oidc/redirect - start OIDC flow (state+PKCE cookies)
GET /_/auth/oidc/callback - exchange code, find/create superuser
GET /_/api/oidc/config - reports whether OIDC is enabled
Env vars: BASE_OIDC_ISSUER, BASE_OIDC_CLIENT_ID,
BASE_OIDC_CLIENT_SECRET, BASE_OIDC_AUTO_CREATE_SUPERUSER
ID field changed to max=36, pattern=^[a-z0-9\-]+$ to support UUIDs.
Tests in apis/collection_test.go and plugins/migratecmd expected
the old max=15, pattern=^[a-z0-9]+$.
In IAM-only mode, the local Save() may fail due to collection rules
(createRule: null). Instead of returning nil (which makes the user
a guest), return the record with all JWT claims populated.
IAM is the user store — Base doesn't need to persist the record.
The record serves as auth context for the request only.
StoreKeyIAMOnly: when set, JWKS is tried first and built-in password/OTP
auth is disabled for non-superuser collections. Platform plugin sets this
automatically when IAM endpoint is configured.
- Pad short IAM subs to 15 chars for Base record ID requirements
- Include ui/dist/ in git (un-ignored via !ui/dist/) so Go module
consumers get embedded admin assets
- Add X-Authorization as auth header alias
- Add Makefile ui target, update release workflow
- C1: add orgId field to _tasks/_workflows, filter all queries by org
- C2: validate spaceID/orgID with regex before Temporal visibility queries
- H1: add sync.RWMutex to orgClients map (prevent concurrent map panic)
- H2: atomic FailTask with CASE expression (eliminate TOCTOU race)
- H4: extractCreator uses authenticated user ID, not raw headers
- Add orgId to collection schemas, store methods, and API filters
- Test fixture DB: rename all _pbf_* field IDs to _hzf_*
- collection_test.go: update hardcoded field IDs to match
- record_crud.go: __pb_create__ → __hzf_create__
- base_backup.go: old_pb_data_ → old_hz_data_
- Remove stale _hz_users_auth_ mapping from tokenreplace
- router: remove self-import cycle in rereadable_read_closer_test.go
- rate limit: bump sleep waits (800→1100ms, 1000→1200ms) to reliably
cross 1-second window boundaries on slow CI
- verification: replace hardcoded expired JWT tokens with dynamically
generated tokens via BeforeTestFunc + bytes.Buffer pattern
- password reset: same dynamic token generation fix
- collection update: fix system field IDs (_hzf_ → _pbf_) to match
test database, so reserved name validation is reached
Embeds a complete task queue and workflow scheduler into base using
the collection/record system backed by embedded SQLite.
Plugin creates _tasks and _workflows system collections on bootstrap
and runs a background scheduler that checks timeouts, advances
workflow state, and optionally auto-executes tasks via OnExecute callback.
API endpoints: create/get/list/update/claim/start/complete/fail/cancel/
progress/next (work-stealing) for tasks, plus create/get/list for
workflows with auto-chained pipeline and parallel (fan-out) support.
10 tests covering full lifecycle: CRUD, atomic claims, retry with
re-queue, dependency blocking, priority ordering, workflow advancement.
New /api/tasks endpoints for durable workflow execution:
- POST /api/tasks — submit task
- GET /api/tasks — list tasks (filterable by state/queue)
- GET /api/tasks/{id} — get task details
- POST /api/tasks/{id}/cancel — cancel running task
- POST /api/tasks/{id}/signal — signal running task
- GET /api/tasks/{id}/query/{queryType} — query task state
- POST /api/tasks/workflows — submit workflow (pipeline/fan-out)
- GET /api/tasks/workflows — list workflows
- GET /api/tasks/workflows/{id} — get workflow details
Superuser auth required. Hanzo Tasks (Temporal) backend injected via OnServe hook.
No hard dependency on Temporal SDK — handlers return placeholder until backend connected.
Remove all _hz_ prefixes from collection IDs, internal markers, and test
fixtures. The default users collection is now _users_auth_ instead of
_hz_users_auth_. Internal SQL parser tokens renamed from __hz_join__/__hz_discard__
to __join__/__discard__. Backup prefix changed from @auto_hz_backup_ to
@auto_backup_. Test database updated with correct collection IDs and indexes.
JWT tokens in test files regenerated with new collection IDs.
Add LogoURL field to MetaConfig so the admin UI logo is configurable via
app settings instead of hardcoded. FullPage.svelte and App.svelte sidebar
now read logo and app name from the settings store, falling back to
defaults when not configured.
Replace github.com/pocketbase/pocketbase with github.com/hanzoai/base
in 106 Go source files. Keep pocketbase/dbx and pocketbase/tygoja as-is
(upstream dependencies). Add compiled binary to .gitignore. Include
realtime DX design document inspired by Convex patterns.