Premiere commit - Omika
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
-- ============================================================
|
||||
-- Omika Diagnostic Center -- 003_diagnostics_roles.sql (Phase 5B2B.3)
|
||||
-- PostgreSQL hardening : least privilege (Worker / Web / Owner).
|
||||
-- ============================================================
|
||||
-- TO RUN ON SRV-OMIKA as PostgreSQL superuser (e.g. psql -U postgres),
|
||||
-- BEFORE Phase 5C. DO NOT run from the development PC.
|
||||
--
|
||||
-- Guarantees :
|
||||
-- - PostgreSQL 18 compatible.
|
||||
-- - Idempotent : re-running is a no-op.
|
||||
-- - Non destructive : NO DROP, no role/object/data removal.
|
||||
-- - NO password, NO secret (LOGIN role passwords are set manually via
|
||||
-- \password, never in this file).
|
||||
--
|
||||
-- Role model :
|
||||
-- omika_diagnostics_owner NOLOGIN : owner of DB/schema/tables/sequences/indexes.
|
||||
-- omika_diagnostics_worker LOGIN : Worker runtime (JSONL import).
|
||||
-- omika_diagnostics_web LOGIN : Web runtime (read only).
|
||||
-- omika_diagnostics_app (existing) : KEPT (controlled transition),
|
||||
-- NOT disabled here.
|
||||
--
|
||||
-- Server apply order : 001 (schema) -> 002 (actor_key) -> 003 (roles).
|
||||
-- ============================================================
|
||||
|
||||
-- ------------------------------------------------------------
|
||||
-- 1. Create roles if absent (NO password here).
|
||||
-- ------------------------------------------------------------
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'omika_diagnostics_owner') THEN
|
||||
CREATE ROLE omika_diagnostics_owner;
|
||||
END IF;
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'omika_diagnostics_worker') THEN
|
||||
CREATE ROLE omika_diagnostics_worker;
|
||||
END IF;
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'omika_diagnostics_web') THEN
|
||||
CREATE ROLE omika_diagnostics_web;
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
|
||||
-- ------------------------------------------------------------
|
||||
-- 2. Secure attributes (idempotent).
|
||||
-- All: NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION NOBYPASSRLS.
|
||||
-- ------------------------------------------------------------
|
||||
ALTER ROLE omika_diagnostics_owner NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION NOBYPASSRLS NOLOGIN;
|
||||
ALTER ROLE omika_diagnostics_worker NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION NOBYPASSRLS LOGIN;
|
||||
ALTER ROLE omika_diagnostics_web NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION NOBYPASSRLS LOGIN;
|
||||
|
||||
-- ------------------------------------------------------------
|
||||
-- 3. Ownership transfer (explicit -- no global REASSIGN OWNED).
|
||||
-- Only Omika Diagnostics objects are targeted.
|
||||
-- ------------------------------------------------------------
|
||||
ALTER DATABASE omika_diagnostics OWNER TO omika_diagnostics_owner;
|
||||
ALTER SCHEMA public OWNER TO omika_diagnostics_owner;
|
||||
|
||||
ALTER TABLE diagnostic_event OWNER TO omika_diagnostics_owner;
|
||||
ALTER TABLE telemetry_metric_hourly OWNER TO omika_diagnostics_owner;
|
||||
|
||||
ALTER SEQUENCE diagnostic_event_id_seq OWNER TO omika_diagnostics_owner;
|
||||
ALTER SEQUENCE telemetry_metric_hourly_id_seq OWNER TO omika_diagnostics_owner;
|
||||
|
||||
-- PostgreSQL 18:
|
||||
-- Index ownership follows table ownership.
|
||||
-- No ALTER INDEX OWNER is required.
|
||||
-- (Sequences are NOT auto-transferred by ALTER TABLE: the ALTER SEQUENCE
|
||||
-- OWNER commands above are therefore kept and required.)
|
||||
|
||||
-- ------------------------------------------------------------
|
||||
-- 4. Schema "public" hardening.
|
||||
-- Decision : YES, REVOKE CREATE -- the database is dedicated to the
|
||||
-- Diagnostic Center; only the owner/admin should create objects.
|
||||
-- (PostgreSQL 15+ already revokes it for new databases; this is an
|
||||
-- idempotent belt-and-suspenders.)
|
||||
-- ------------------------------------------------------------
|
||||
REVOKE CREATE ON SCHEMA public FROM PUBLIC;
|
||||
|
||||
-- ------------------------------------------------------------
|
||||
-- 5. MINIMUM runtime privileges (from real code audit).
|
||||
--
|
||||
-- WORKER (omika_diagnostics_worker):
|
||||
-- * diagnostic_event : INSERT only
|
||||
-- (INSERT ... ON CONFLICT (event_id) DO NOTHING -- dedup).
|
||||
-- * sequence diagnostic_event_id_seq : USAGE (id BIGSERIAL).
|
||||
-- * NO SELECT/UPDATE/DELETE (60-day retention is NOT implemented;
|
||||
-- telemetry_metric_hourly upsert is registered but has NO caller).
|
||||
--
|
||||
-- WEB (omika_diagnostics_web): SELECT ONLY on diagnostic_event
|
||||
-- (QueryAsync count+page, GetByTraceId, GetByOperationId, IsAvailableAsync).
|
||||
--
|
||||
-- NO privilege granted on telemetry_metric_hourly while no code uses it
|
||||
-- (least privilege).
|
||||
-- ------------------------------------------------------------
|
||||
|
||||
-- Explicit connection intent (PUBLIC keeps default CONNECT; documented only,
|
||||
-- not hardened beyond requested scope).
|
||||
GRANT CONNECT ON DATABASE omika_diagnostics TO omika_diagnostics_worker, omika_diagnostics_web;
|
||||
|
||||
GRANT USAGE ON SCHEMA public TO omika_diagnostics_worker, omika_diagnostics_web;
|
||||
|
||||
-- Worker : JSONL import -> diagnostic_event.
|
||||
GRANT INSERT ON TABLE diagnostic_event TO omika_diagnostics_worker;
|
||||
GRANT USAGE ON SEQUENCE diagnostic_event_id_seq TO omika_diagnostics_worker;
|
||||
|
||||
-- Web : read only.
|
||||
GRANT SELECT ON TABLE diagnostic_event TO omika_diagnostics_web;
|
||||
|
||||
-- ------------------------------------------------------------
|
||||
-- 6. Legacy role omika_diagnostics_app : KEPT (no DROP, no NOLOGIN here).
|
||||
-- After transfer it owns no Diagnostics object and has no object privilege;
|
||||
-- disabling it (ALTER ROLE ... NOLOGIN) is an EXPLICIT administrator action
|
||||
-- AFTER validating the new roles.
|
||||
-- ------------------------------------------------------------
|
||||
|
||||
-- ============================================================
|
||||
-- END 003. Manual next steps (outside this script):
|
||||
-- 1. Set passwords: psql -> \password omika_diagnostics_worker
|
||||
-- then \password omika_diagnostics_web (never in script/log/history).
|
||||
-- 2. Point Worker: Username=omika_diagnostics_worker ; Web:
|
||||
-- Username=omika_diagnostics_web (ConnectionStrings__DiagnosticsDatabase).
|
||||
-- 3. Validate Worker (INSERT) and Web (SELECT), then only after,
|
||||
-- disable omika_diagnostics_app (ALTER ROLE ... NOLOGIN) if desired.
|
||||
-- ============================================================
|
||||
Reference in New Issue
Block a user