containment: hardcap admin API publish gate + outbox self-sufficient pool
ci / lint-test-leaks (pull_request) Canceled after 0s
ci / lint-test-leaks (pull_request) Canceled after 0s
- hardcap PATCH /admin/articles/:id → PUBLISHED now stages into
outbound_drafts (channel hardcap) instead of publishing, when
HARDCAP_PUBLISH_MODE=draft (default). Fail-closed. Verified E2E:
PATCH on a QUEUED article returned {staged:true, draft_id:7} and the
article stayed QUEUED.
- bitcoinhotels.org: audited — frontend only (Next.js), no publishing
path; nothing to contain.
- outbox.mjs: self-sufficient pool (createRequire from
/srv/cayce-core/node_modules/pg — hosts may lack pg; found by the
promo simulation which now works end-to-end).
- runtime/hardcap/admin.ts: versioned copy of the patched route
(hardcap-backend itself is not a git repo).
- deploy.sh: hardcap env wiring (HARDCAP_PUBLISH_MODE, IDENTITY_PATH,
CAYCE_PGURL appended server-side).
🔴 UNRELATED CRITICAL FINDING (needs operator decision, not patched
without approval): hardcap admin API has NO authentication and binds
*:3001 — reachable from the public internet (HTTP 200 from outside,
including DELETE /admin/articles/all). Recommend: auth middleware +
bind 127.0.0.1 + firewall, plus rotation of credentials that appeared
in journald (hardcap DB role DSN leaked via a psql error line during
testing — fixed in the same patch, but journald retains it).
This commit is contained in:
+4
-1
@@ -13,6 +13,9 @@
|
||||
|
||||
import { readFileSync } from 'node:fs'
|
||||
import { createHash } from 'node:crypto'
|
||||
import { createRequire } from 'node:module'
|
||||
|
||||
const require_ = createRequire(import.meta.url)
|
||||
|
||||
const IDENTITY_PATH = process.env.IDENTITY_PATH || '/home/ubuntu/cayce-ops/prompts/cayce-identity.md'
|
||||
|
||||
@@ -67,7 +70,7 @@ let ownPool = null
|
||||
async function poolFor(poolPg) {
|
||||
if (poolPg) return poolPg
|
||||
if (!ownPool) {
|
||||
const pg = (await import('pg')).default
|
||||
const pg = require_('/srv/cayce-core/node_modules/pg')
|
||||
const env = Object.fromEntries(
|
||||
readFileSync('/srv/cayce-core/.env', 'utf8').split('\n').filter(l => l.includes('=')).map(l => [l.slice(0, l.indexOf('=')), l.slice(l.indexOf('=') + 1)])
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user