mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
Gate the relay admin moderation API (/api/admin/v1) behind explicit authentication configuration selected by BUZZ_ADMIN_AUTH: token (default), disabled, or nip98. In nip98 mode every request carries a signed kind-27235 NIP-98 event; the authenticated pubkey resolves to an OPERATOR or MODERATOR principal from RELAY_OPERATOR_PUBKEYS, the RELAY_OWNER_PUBKEY fallback, or the relay_operators table. Replaces the BUZZ_ADMIN_INSECURE_NO_AUTH bypass with a role model that is revocable without rotating a shared secret and fails closed at every boundary. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
52 lines
2.5 KiB
SQL
52 lines
2.5 KiB
SQL
-- Deployment-global relay operator roster (Phase 2 admin auth: role-based).
|
|
--
|
|
-- This table tracks deployment-level principals (operators and moderators)
|
|
-- staffed via the admin API. Config-backed operators (RELAY_OPERATOR_PUBKEYS,
|
|
-- RELAY_OWNER_PUBKEY owner-fallback) are never seeded here — they are
|
|
-- authoritative in config and outrank any DB row.
|
|
--
|
|
-- Global (no community_id): operators span all tenants, so tenant-scoping
|
|
-- would be a misnomer. Registered in _operator_global_tables and in the
|
|
-- hardcoded parser list in crates/buzz-db/src/migration.rs.
|
|
|
|
CREATE TABLE relay_operators (
|
|
pubkey BYTEA NOT NULL PRIMARY KEY CHECK (length(pubkey) = 32),
|
|
role TEXT NOT NULL CHECK (role IN ('operator', 'moderator')),
|
|
added_by BYTEA NOT NULL CHECK (length(added_by) = 32),
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
INSERT INTO _operator_global_tables (table_name, reason) VALUES
|
|
('relay_operators',
|
|
'deployment-global operator/moderator roster; no community_id intentionally');
|
|
|
|
-- ── Schema amendments to existing tables ──────────────────────────────────────
|
|
|
|
-- moderation_actions: add actor_authority column to record whether the acting
|
|
-- principal was a community member or a deployment operator/moderator.
|
|
-- Default 'community' for all existing rows.
|
|
ALTER TABLE moderation_actions
|
|
ADD COLUMN actor_authority TEXT
|
|
NOT NULL DEFAULT 'community'
|
|
CHECK (actor_authority IN ('community', 'relay_operator', 'relay_moderator'));
|
|
|
|
-- moderation_reports: add processing status for HTTP enforcement claim.
|
|
-- The CAS on status='open' AND active_action_id IS NULL ensures only one
|
|
-- HTTP enforcement can claim a report at a time; legacy 9044 resolvers CAS
|
|
-- on status='open' which fails safely against a processing report.
|
|
ALTER TABLE moderation_reports
|
|
DROP CONSTRAINT moderation_reports_status_check,
|
|
ADD CONSTRAINT moderation_reports_status_check
|
|
CHECK (status IN ('open', 'processing', 'resolved', 'dismissed', 'escalated'));
|
|
|
|
-- active_action_id is non-null when the report is in 'processing' state.
|
|
-- Only relay_admin_actions rows (Phase 2) may set this field; the column
|
|
-- is the lease claim for exactly-once enforcement.
|
|
ALTER TABLE moderation_reports
|
|
ADD COLUMN active_action_id UUID;
|
|
|
|
-- product_feedback: add operator-managed status column.
|
|
ALTER TABLE product_feedback
|
|
ADD COLUMN status TEXT NOT NULL DEFAULT 'new'
|
|
CHECK (status IN ('new', 'reviewed', 'archived'));
|