fix: address external audit — criticals 1-5 + mediums
Critical 1 (approval forgery): audit_log is now hash-chained (prev_hash/entry_hash, verify_audit_chain); executor approve REQUIRES a BIP-340 signature over sha256(cayce-ops:approve:<id>) when CAYCE_OPS_OPERATOR_PUBKEY is set; deploy/roles.sql ships least-privilege per-daemon DB roles. Critical 2 (threading dead): sends create real OUTBOUND rows (own Message-ID, In-Reply-To -> inbound); inbound message_id never overwritten; maild compose adds the first-contact path; _match_proposal falls back to inbound chains. Critical 3 (duplicate sends): per-message transactions in send path — SMTP failure on message N no longer resurrects 1..N-1; failures audited (send_failed) and the row stays queued. Critical 4 (classifier): negated approvals (cannot accept / not approved / not accepting) classify REJECTION at 0.95 before the bare-keyword rule; LLM prompt braces escaped (.format no longer KeyError into silent fallback). Critical 5 (systemd): every daemon has a run subcommand (maild run = poll+send, publisher run = publish-due, monitor run = build); deploy README documents the separate daily publisher plan timer. Mediums: approved_hash binds drafts/captions to the approved text (edited text refuses to send/publish until re-approved); risk_score renamed match_score (migration 0002) and auto-approve orders HIGHEST relevance first; compose binds postgres to 127.0.0.1; IMAP marks \\Seen only after commit (fetch returns (num, raw), mark post-commit); disabled channels are terminal (ContentStatus.SKIPPED) and publish failures burn a bounded attempt budget before abandonment; make hooks installs the pre-push gate. tests: 12 new — 56 total, all green; ruff 0 findings; gitleaks clean.
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
-- Per-daemon least-privilege roles (audit critical finding 1, deployment half).
|
||||
-- The app-level chain + signatures are in code; this locks the DB layer.
|
||||
-- Apply on the production Postgres; adjust the connection limits.
|
||||
CREATE ROLE cayce_scanner LOGIN PASSWORD 'set-from-env';
|
||||
CREATE ROLE cayce_executor LOGIN PASSWORD 'set-from-env';
|
||||
CREATE ROLE cayce_maild LOGIN PASSWORD 'set-from-env';
|
||||
CREATE ROLE cayce_publisher LOGIN PASSWORD 'set-from-env';
|
||||
CREATE ROLE cayce_monitor LOGIN PASSWORD 'set-from-env';
|
||||
|
||||
GRANT SELECT ON proposals, audit_log, mail_messages, content_items, daemon_runs TO cayce_monitor;
|
||||
GRANT SELECT, INSERT, UPDATE ON proposals TO cayce_scanner; -- no DELETE
|
||||
GRANT INSERT ON audit_log TO cayce_scanner; -- append-only
|
||||
GRANT SELECT, UPDATE ON proposals TO cayce_executor; -- status transitions
|
||||
GRANT INSERT ON audit_log TO cayce_executor; -- append-only
|
||||
GRANT SELECT, INSERT, UPDATE ON mail_messages, proposals TO cayce_maild;
|
||||
GRANT INSERT ON audit_log TO cayce_maild;
|
||||
GRANT SELECT, UPDATE ON content_items TO cayce_publisher;
|
||||
GRANT INSERT ON audit_log TO cayce_publisher;
|
||||
GRANT SELECT ON daemon_runs TO cayce_scanner, cayce_executor, cayce_maild, cayce_publisher;
|
||||
|
||||
-- sequences
|
||||
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO cayce_scanner, cayce_executor, cayce_maild, cayce_publisher, cayce_monitor;
|
||||
@@ -9,9 +9,14 @@ sudo -u cayce uv sync --frozen
|
||||
sudo -u cayce cayceops db upgrade # alembic to head
|
||||
sudo cp deploy/systemd/cayce-ops@.service deploy/systemd/cayce-ops@.timer /etc/systemd/system/
|
||||
|
||||
# Every daemon has a `run` subcommand now:
|
||||
# scanner run · executor run · maild run (poll + send-approved)
|
||||
# publisher run (publish-due) · monitor run (build)
|
||||
# cadence per daemon (edit OnCalendar in each timer copy):
|
||||
# scanner hourly executor */10 min maild */5 min
|
||||
# publisher */5 min monitor */1 min
|
||||
# NOTE: `publisher plan` (fills the calendar) is a SEPARATE timer:
|
||||
# OnCalendar=daily -> ExecStart=/srv/cayce-ops/.venv/bin/cayceops publisher plan
|
||||
for d in scanner executor maild publisher monitor; do
|
||||
sudo cp deploy/systemd/cayce-ops@.timer /etc/systemd/system/cayce-ops@$d.timer
|
||||
done
|
||||
|
||||
Reference in New Issue
Block a user