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>
81 lines
3.8 KiB
SQL
81 lines
3.8 KiB
SQL
-- HTTP report-resolution enforcement state machine (Phase 2 admin auth).
|
|
--
|
|
-- relay_admin_actions: one row per HTTP-initiated enforcement action.
|
|
-- relay_admin_outbox: durable delivery queue for tombstones, system messages,
|
|
-- and reporter notice DMs.
|
|
--
|
|
-- Both tables are deployment-global (no community_id direct column; the report
|
|
-- FK carries community provenance). Registered in _operator_global_tables and
|
|
-- in the hardcoded parser list in crates/buzz-db/src/migration.rs.
|
|
|
|
CREATE TABLE relay_admin_actions (
|
|
id UUID NOT NULL PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
report_id UUID NOT NULL,
|
|
report_community_id UUID NOT NULL,
|
|
-- Client-generated idempotency key (signed in NIP-98 request body).
|
|
request_id UUID NOT NULL,
|
|
-- Principal who claimed the report.
|
|
actor_pubkey BYTEA NOT NULL CHECK (length(actor_pubkey) = 32),
|
|
actor_role TEXT NOT NULL CHECK (actor_role IN ('operator', 'moderator')),
|
|
-- The enforcement action requested.
|
|
action TEXT NOT NULL,
|
|
reason TEXT,
|
|
-- Timeout expiration for timeout actions; NULL otherwise.
|
|
timeout_until TIMESTAMPTZ,
|
|
-- Durable state machine: pending → enforcing → succeeded|failed|cancelled.
|
|
state TEXT NOT NULL DEFAULT 'pending'
|
|
CHECK (state IN ('pending', 'enforcing', 'succeeded', 'failed', 'cancelled')),
|
|
-- Step marker: the last durably committed mutation step (NULL = none yet).
|
|
step_marker TEXT CHECK (step_marker IN ('mutation_committed', 'artifacts_done')),
|
|
-- Error from the last failure, if any.
|
|
error_message TEXT,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
-- Report-scoped idempotency: one action per (report, request_id).
|
|
UNIQUE (report_community_id, report_id, request_id),
|
|
FOREIGN KEY (report_community_id, report_id)
|
|
REFERENCES moderation_reports (community_id, id)
|
|
);
|
|
|
|
CREATE INDEX idx_relay_admin_actions_report
|
|
ON relay_admin_actions (report_community_id, report_id);
|
|
CREATE INDEX idx_relay_admin_actions_state
|
|
ON relay_admin_actions (state)
|
|
WHERE state IN ('pending', 'enforcing');
|
|
|
|
INSERT INTO _operator_global_tables (table_name, reason) VALUES
|
|
('relay_admin_actions',
|
|
'deployment-global enforcement state machine; community provenance via report FK');
|
|
|
|
-- ── Relay admin outbox ────────────────────────────────────────────────────────
|
|
|
|
CREATE TABLE relay_admin_outbox (
|
|
id UUID NOT NULL PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
action_id UUID NOT NULL REFERENCES relay_admin_actions(id),
|
|
-- Delivery task type: 'tombstone' | 'system_message' | 'reporter_notice'.
|
|
task_type TEXT NOT NULL,
|
|
-- Task payload (JSON).
|
|
payload JSONB NOT NULL DEFAULT '{}'::jsonb,
|
|
-- Lease-based delivery: held_by identifies the worker pod.
|
|
held_by TEXT,
|
|
lease_expires_at TIMESTAMPTZ,
|
|
-- Delivery state: pending → delivered | failed.
|
|
state TEXT NOT NULL DEFAULT 'pending'
|
|
CHECK (state IN ('pending', 'delivered', 'failed')),
|
|
-- Deduplication key: prevents re-creating an artifact after delivery.
|
|
dedup_key TEXT UNIQUE,
|
|
error_message TEXT,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE INDEX idx_relay_admin_outbox_action
|
|
ON relay_admin_outbox (action_id);
|
|
CREATE INDEX idx_relay_admin_outbox_pending
|
|
ON relay_admin_outbox (lease_expires_at)
|
|
WHERE state = 'pending';
|
|
|
|
INSERT INTO _operator_global_tables (table_name, reason) VALUES
|
|
('relay_admin_outbox',
|
|
'deployment-global enforcement artifact delivery queue');
|