Commit Graph
2 Commits
Author SHA1 Message Date
ekklesiaandClaude Opus 5 a2db774b8c docs: correct Gitea Actions guarantees
CI / verify (pull_request) Successful in 29s
CI / infrastructure-smoke (pull_request) Successful in 20s
CI / migration-smoke (pull_request) Failing after 39s
The security document claimed the CI workflow "is least privilege" because it
declares `permissions: contents: read`. That is not true on the server this
repository actually uses.

The inventoried server is Gitea 1.24.2, and its official comparison page lists
`permissions` / `jobs.<job_id>.permissions`, `concurrency`, and
`jobs.<job_id>.timeout-minutes` under unsupported workflow syntax — verified
against https://docs.gitea.com/1.24/usage/actions/comparison rather than assumed.
On this server those keys are inert, so the branch cannot claim the in-job
GITEA_TOKEN is read-only, and cannot claim YAML-enforced timeout or concurrency
behavior. Job-token permission controls, repository/owner defaults, and
server-side maximum-permission clamping arrive in the 1.26 feature line
(https://docs.gitea.com/1.26/usage/actions/token-permissions).

The document now separates what is actually true of this repository — full-SHA
action pins, frozen-lockfile install, no pull_request_target, no referenced
secret, `persist-credentials: false` on every checkout, and the declared
`permissions` block — from what the server enforces. It also states precisely
what `persist-credentials: false` proves: checkout leaves no credential in
`.git/config` for a later step, which is not the same as removing or reducing
the job token. The CI blockers are recorded: upgrade to a reviewed supported
release, configure repository/owner defaults and a maximum permission, prove
against the real server what the token cannot do, move timeout/cancellation/
teardown into the trusted provisioner and reaper, and finish the disposable-guest
proof before opening the real pull request.

The workflow keeps every declaration — they are already correct for a supported
Gitea release and for GitHub Actions — and gains a comment saying plainly that
this server ignores them, so no future reader mistakes them for enforcement.

Nothing about runners, proxies, firewalls, or deployment is asserted here.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-07-28 20:10:20 -05:00
ekklesiaandClaude Opus 5 07a3c61083 docs: define deployment trust boundaries
One canonical security document, linked from the README, platform architecture,
and module-development guide, stating what the boundaries actually protect
against — and, more importantly, what they do not.

Installed modules are trusted compiled backend code. A module runs arbitrary
JavaScript inside the API process and shares its PostgreSQL role and pool, so
`ModuleDatabase.execute` gives it the API's full database authority over every
table, including identity, grants, owner, bootstrap, and audit. Table prefixes,
manifests, permission declarations, route validation, frozen contexts, typed
facades, and the capability registry are correctness and coordination boundaries
that assume a cooperative module; none of them constrains one that is not. There
is no process, container, syscall, filesystem, network, database-role, schema,
tenant, or resource sandbox between a module and Core, and the document says so
in those words, along with what would have to be built before untrusted modules
could be accepted.

It also records the honest deployment state: Ekklesia is not deployed. There is
no production instance, reverse proxy, public listener, or deployment automation
anywhere in this repository, and no `.env` has ever been committed. The loopback
listen default and the production signup refusal are real, but a config default
is not a firewall, so the origin-reachability, proxy-overwrite, header-spoofing,
and trusted-peer properties a public launch needs are written as a
launch-blocking checklist rather than as guarantees. The per-process
authentication limiter is described as exactly that, valid only while signup
stays disabled and exactly one instance serves traffic.

The CI section records the workflow's verified posture and deliberately stops
there: a pull request can edit `runs-on`, so a workflow file cannot be the
boundary, and the runner topology is not described as though it had been
verified.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-07-28 19:49:12 -05:00