Security review
llms.txtlists every page for an agent
What each job can reach, who can approve an apply, and the record every change leaves.
Works
- A reader and a writer per environment: only the apply wave holds the writer, and a write probe fails a pull request job that can write
- Each approval bound to a digest of the plan; when the plan moves, the approval no longer holds
- Approval modes, including approvals sealed with a signer listed in the repository
- An audit log derived from the history and the gate ledger
Differs
By database
- A project owns ClickHouse databases (
yodel create <dir> --clickhouse --database <name>). - A rebuild keeps the old table until
yodel cleanupdrops it, and lint flags mutations and rebuilds (ch-mutation,ch-rebuild).
- A project owns Postgres schemas (
yodel create <dir> --postgres --schema <name>). - Roles stay the environment's: the schema declares the policies and grants that name them.
By forge
- The writer's secrets are secrets of a GitHub environment limited to
main. - The plan comment and the drift issue use the job's own token.
- The writer's variables are protected and scoped to the environment; the readers' are not protected.
- The plan comment and the drift issue need
GITLAB_TOKEN, and each drift watch runs from a pipeline schedule you create.
- Secrets belong to the repository, with no environments, so limit who can push branches.
- Jobs need a runner with the
dockerlabel, and a job gets no OIDC token for cloud roles.
First step
npx yodel config check <env> --write-probeProof
Each claim runs what this room relies on against a real server, once plain (it passes) and once with the behaviour broken (the claim catches it). Claims status lists every claim.
| Claim | What it says | Plain, broken |
|---|---|---|
approval | a pending migration applies only after chant approve of its plan digest, and the history records that digest; a failing pre-migration check refuses it, and so does a policy rule, read at the base commit, unless an override is recorded for that digest, for a yodel revert as for an apply; the audit log derived from the history and the ledger accounts for every approval and apply, and names one removed; a reader and a writer that are one user are refused, and the reader, its password a minted token, cannot write; an approval is refused once the migration changed after it, and nothing is applied | ClickHouse: pass, caughtPostgres: pass, caught |
waves | the apply pipeline runs one wave per environment, in order, each behind its gate policy read from the base commit, applies only what the wave before applied, and applies a tenant set's migrations to every tenant behind one gate; a sealed wave counts only an approval sealed by a signer the base commit lists | ClickHouse: pass, caughtPostgres: pass, caught |
