railiance-apps/build/forgejo/README.md
tegwick 308e83fcfb
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Verify Forgejo PostgreSQL operations and preserve tracing hook context
Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a14bfc-9643-7872-aa12-98326dcf25e7
2026-10-18 03:21:56 +02:00

136 lines
8.9 KiB
Markdown

# Forgejo release preparation (build only)
The Apps Makefile targets package the digest-bound 40-path Forgejo 11.0.3
source candidate in `forgejo-security-extension.patch`. It combines the original
three-group any-of gate, private secret-file input, private source-operation DB
primitives and the producer-owned Access Engine client in the OIDC callback.
Coordinator source tests and complete release checks are recorded separately;
independent owner review and operational admission of this revision remain open. They never deploy, push, change default values or choose
an operational image. Third-party application source is expanded only into a new
`/tmp` workspace; this repository retains a release input lock and exact reviewed
patch, not a second source-code tree. Upstream source ownership and publication
remain separate owner work.
Supply explicit public input archives/cache paths to `make forgejo-release-prepare`:
`FORGEJO_SOURCE_ARCHIVE`, `FORGEJO_GO_ARCHIVE`, `FORGEJO_NODE_ARCHIVE`,
`FORGEJO_BUILD_GOMODCACHE`, optionally `FORGEJO_BUILD_GOCACHE_SEED` and
`FORGEJO_BUILD_NPM_CACHE_SEED`. Every archive, patch, source output, dependency
lock and selected host compiler tool is digest-bound by `inputs.lock.json`.
Go's official checksums and Node's official SHASUMS must be independently checked
when acquiring those public archives. The source archive is official Forgejo
v11.0.3; archive PAX commit b81aa4d0807cc1e2d6a2fbafd0b75c46cc0ae237.
The workspace must not exist. Existing trials are preserved, never restarted
because an observer timed out. The recipe's `process.json` records the exact
active child PID, phase and command, then completion; logs and receipts stay in
the workspace. Do not run two phases against the same workspace concurrently.
`make forgejo-release-acquire-npm` explicitly acquires only public registry
packages, with fresh HOME/config paths, integrity-bound lockfile and lifecycle
scripts disabled. With the cache ready, `make forgejo-release-build` reruns
`npm ci --offline --ignore-scripts`, Go module verification, upstream frontend
compilation and upstream generation/static backend targets inside a network
namespace without connectivity. It uses the exact Go/Node distributions, local
compiler inputs, `bindata timetzdata sqlite sqlite_unlock_notify` plus upstream
static target's `netgo osusergo`, explicit Make GOFLAGS for trimpath/buildvcs and
fixed file/directory timestamps. Build tags retain the upstream rootless build
profile. `make forgejo-release-verify` compares every embedded public/options/
template file to actual generated source bytes, checks the extension CLI and
checks the ELF has no dynamic interpreter. These are local artifact checks,
not application login, DB, native rollout or architecture acceptance.
For a **local container build** only, first acquire the locked public amd64
base with an empty Docker client config and the explicit local socket. Then
`make forgejo-release-container` uses that exact digest as a build input and a
minimal context containing only the verified executable and generated Dockerfile.
It directly exports a local OCI archive with `rewrite-timestamp=true`, no-cache,
no image load or push. SOURCE_DATE_EPOCH alone does not fix COPY parent-directory
timestamps. The image epoch is max(source epoch,ceil immutable base created
instant), so the original base layers remain exact while new metadata is stable.
The recipe verifies every OCI blob, original base layer prefix, rootless runtime
configuration, provenance labels and exact final executable. Two no-cache exports
must reproduce the frozen output image and archive digests before claiming
reproducibility. The actual local proof receipts are in the accompanying source
proposal packet, not an admission of the resulting artifact.
There is no deployment tag, registry publication, RUN directive, privileged
container or Docker host/secret mount. Public base acquisition and a standard
local Docker/buildx daemon supporting OCI export/layer timestamp rewriting are
explicit prerequisites. An unavailable feature is a retained blocker; do not
switch to a privileged builder or claim a successful image from a backend-only
binary. Existing contexts/output archives refuse overwrite. Reconcile an actual
failed export explicitly, retaining original metadata/logs/artifacts; observation
timeouts never justify another build. Older prototype load/save behavior and
its config-versus-manifest-ID issue are retained in the source trial history,
not shipped as a production continuation.
The static host toolchain is pinned for this Linux amd64 review estate. Broader
cross-host reproducibility or a different architecture/compiler/libc is a new
input revision, not an implicit fallback. The glibc static-linker's optional
SQLite `dlopen` diagnostic is retained; no SQLite-extension runtime compatibility
or production platform admission is inferred from ELF inspection or asset checks.
An accepted owner image/source/backend, authenticated access-engine decision,
private secret-input boundary, type/case/descriptor re-freeze, current operation/
inverse sessions, durable journal and application/Helm writer exclusion are
separate gates. Helm omission/rollback does not remove persisted OAuth source.
The existing case gate is compatibility code, not a single-PDP exception.
## KeyCape identity and callback admission
The callback independently verifies the ID token against owner-admitted public
keys, algorithms, issuer, audience and token type. Public trust is loaded from
`FORGEJO_ACCESS_ENGINE_ADMISSION_FILE`; only an absolute private file reference
is used for the PDP caller token. No admission file or operational keys are
supplied by this build. New fields `tenant_source_claim` and
`max_authentication_age` are mandatory. The KeyCape v0.3 profile uses
`assurance_claim: assurance` and `tenant_source_claim: tenant_source`. Maximum
identity age and maximum authentication age are separate positive durations
chosen by the owner, not implicit defaults.
The signed assurance object preserves `level`, `methods`, boolean `mfa`,
`source: key-cape` and integer `at`. Its authentication time must not follow
issuance or the current time, and must satisfy the admitted authentication-age
bound. Identity validity ends at the earliest token expiration, issued-at age
bound or authentication-age bound. Directory, registration and default tenant
provenance remain distinct in the request. Mutable UserInfo cannot replace
these authenticated facts. Current UserInfo subject and the Goth subject must
match the independently verified token; the three required group alternatives
remain policy input.
The parser also represents valid lower-assurance facts. Application policy
continues to decide authorization. The Check client and unchanged canonical
signature bytes are a generated source slice of Access Engine ca0cb757; Forgejo
adds no policy evaluator. Exact caller/policy/registry/signer/request/lifetime
pins, an authenticated HTTPS connection and a current ALLOW are required.
Synthetic callback fixtures test ALLOW, DENY and adverse cases, including an ID
token serialized by the actual pinned KeyCape handler. Those fixtures do not
prove an actual browser, factor, custody or native rollout.
The current integration covers this guarded OIDC callback. Ongoing application
HTTP/API/Git/SSH paths, current operation/inverse sessions, durable private
evidence and retention, deployed PostgreSQL/custody acceptance and exclusion of all release
writers remain open in RAPPS-WP-0016-T08/T09 and NK-WP-0048-T43. An old image
approval or source test result cannot admit this candidate.
## PostgreSQL operation-source verification
The source primitive has now run on a disposable PostgreSQL 16.14 instance using
the actual Forgejo engine, model schemas and OAuth configuration types. Tests
cover default, explicit-public and named schemas, exact source restoration, drift
and linked-account refusals, trigger rollback, uncooperative SQL writer exclusion
and concurrent preparation. Independent client processes and an actual server
restart verify prepared/applied/inverse journal recovery. The test-only
`source_operation_postgres` tag selects the integration tests; no runtime route,
credential, session or authority callback is added. The companion Custodian
`forgejo-postgres-source-r1` packet holds the isolated fixture, commands, source
pins, counterexamples and original failed attempts.
Actual PostgreSQL diagnostics exposed a tracing-hook composition crash. Tracing
now publishes its task context to the shared XORM hook context so later hooks
retain it. Ordinary and private SQLite traces and actual PostgreSQL failure
queries exercise this path. Controlled copies without the table lock or private
query marker fail their respective regressions. These are source/database
mechanics checks; owner admission, current authenticated operation/inverse
sessions, runtime/backup custody, retention, every release writer and native
deployed-database acceptance remain separate obligations. The previous frozen
release is historical and does not contain this context correction.