railiance-apps/build/forgejo/README.md
tegwick ab3cf5cdc5
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Correct composed validation scope and retain the initial fixture skip
Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a14bfc-9643-7872-aa12-98326dcf25e7
2026-10-18 12:21:03 +02:00

172 lines
11 KiB
Markdown

# Forgejo release preparation (build only)
The Apps Makefile targets package the digest-bound 49-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.
## Current-token callback source continuation
The 49-path candidate additionally vendors the unchanged, producer-generated
KeyCape current-token adapter from `08c083ba`; no consumer token registry or
handwritten copy is introduced. `current_token` (explicit HTTPS issuer, resource
audience, owning client, CA/JWKS/private-client-file references and maximum token
age) and `application_tenant` are mandatory in the independently admitted
`FORGEJO_ACCESS_ENGINE_ADMISSION_FILE` for this guarded callback profile. A signed
caller cannot select the application's tenant. No operational configuration or
credential is supplied by the build.
The callback requires the online KeyCape human ID token's exact RS256 `at_hash`
access-grant binding before private caller use. Access-only `jti`/`scope` cannot
substitute for an ID token. It joins independently verified subject/tenant/type,
issuance, assurance/authentication time and tenant provenance to a fresh issuer
observation before the PDP, then checks current status again after the decision.
Source tests refuse mixed, revoked, suspended, stale, malformed and unavailable
inputs; actual HTTPS issuer PKCE/discovery/UserInfo/status/revocation and real
Forgejo provider/callback run in five isolated consumer processes. MFA session
seeds and PDP admissions are synthetic. Complete release build/asset/OCI evidence
for the preceding patch remains historical; this revision requires its own build
and independent owner/package/type/custody admission before operational use.
The user selected current KeyCape checks on every ongoing API/Git/SSH operation
for NetKingdom-linked accounts, while retaining the separate local break-glass
path. That is an implementation requirement under RAPPS16-T09/NK48-T43, not a
claim that the callback implements those routes or a native deployment grant.
Ongoing resource/action/current-group decisions, protected operation/inverse and
all release writers/journal custody remain acceptance work.
Final composed source validation passes 116 test/subtest results without skips.
The initial 114-pass run skipped its private file-replacement check because a
reused fixture was exhausted; the runner now creates fresh private/read-only
aliases. That initial skip is retained and is not PostgreSQL acceptance.