Files
unibus/migrations/002_users.sql
T
egutierrez c5387028e0 feat(membership): add 002_users.sql migration and user CRUD store
Bus-level user allowlist (issue 0001a): the authoritative directory of
Ed25519 signing identities permitted to use the bus, independent of room
membership. Migration is additive and mirrored byte-for-byte between the
module-root migrations/ and the embedded pkg/membership/migrations/.

Store adds AddUser/GetUser/ListUsers/RevokeUser/IsAuthorized/HasAdmin.
IsAuthorized is the single fail-closed predicate both the control plane and
the NATS data plane will consult, so revocation is a status flip that denies
access on both without a restart.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 12:23:11 +02:00

23 lines
1.1 KiB
SQL

-- 002_users.sql — bus-level user directory (issue 0001a).
--
-- The authoritative allowlist of identities permitted to use the bus, independent
-- of room membership. A user is identified by its Ed25519 signing public key (the
-- same key that derives the endpoint via frame.EndpointID); roles gate admin-only
-- control-plane operations; status enables revocation without deleting history.
--
-- Additive and idempotent: safe to apply repeatedly. Never modify this file;
-- further schema changes go in new numbered migrations (see
-- .claude/rules/db_migrations.md). The embedded copy under
-- pkg/membership/migrations/002_users.sql mirrors this file byte-for-byte.
CREATE TABLE IF NOT EXISTS users (
sign_pub TEXT PRIMARY KEY, -- Ed25519 public key in lowercase hex (peer identity)
handle TEXT NOT NULL, -- human-readable name (unique recommended, not enforced as PK)
role TEXT NOT NULL DEFAULT 'member', -- 'admin' | 'member'
status TEXT NOT NULL DEFAULT 'active', -- 'active' | 'revoked'
created_at TEXT NOT NULL,
revoked_at TEXT
);
CREATE INDEX IF NOT EXISTS idx_users_status ON users(status);