145 lines
8.2 KiB
Markdown
145 lines
8.2 KiB
Markdown
# Forgejo template inheritance
|
|
|
|
FORGE-WP-0006-T02, coordinated by CUST-WP-0080 G07. Proposal
|
|
`forge-template-proposal.json` records the exact source, executor, target,
|
|
verification and recovery for trial `FORGE6-TEMPLATE-LIFECYCLE-001`.
|
|
Standing build-mode blue-lane authorization applies; this is not an autopilot
|
|
grant or a claim of independent owner approval.
|
|
|
|
The October 13 execution reached Deployment generation 12 Ready, preserving the
|
|
image and all 22 previously installed profiles. The live Forgejo global Git
|
|
configuration selects `/opt/forge-secret-template`. Native Git initialization
|
|
using that configuration inherited the exact regular, executable scanner hook;
|
|
malformed input was refused and the owned temporary repository was removed.
|
|
The execution receipt is
|
|
`docs/evidence/2026-10-13-netkingdom-security/forge-template-activation.json`.
|
|
|
|
## Durable source
|
|
|
|
railiance-apps commit `390a30a` owns the immutable non-secret ConfigMap manifest,
|
|
Helm volume/mount/encoded environment setting, and the Make prerequisite that
|
|
installs the ConfigMap before a future Helm deployment. A file `subPath` mount
|
|
is intentional: Git must copy a regular executable, not a ConfigMap projection
|
|
symlink. The hook still invokes the two previously admitted binaries on the
|
|
existing data PVC. Backup/restore must preserve or re-admit those exact binaries;
|
|
the template alone cannot recreate them. Missing scanner artifacts refuse
|
|
pushes, rather than disabling detection.
|
|
|
|
The live change used a conditional JSON Patch because the running Deployment
|
|
contains changes newer than its last Helm revision. Reapplying that old Helm
|
|
release was outside scope. The patch added one volume, four file mounts and one
|
|
configuration environment variable; resourceVersion/UID tests guard the write.
|
|
Images, replica/strategy/resource settings, identities, existing environment
|
|
entries and Secret objects were unchanged. Initial-only admin bootstrap and
|
|
the existing admin row were verified before the restart. Configuration conversion
|
|
uses the existing chart's environment-to-ini process.
|
|
|
|
## Recovery
|
|
|
|
Do not replay the apply operation after activation. It refuses the changed
|
|
Deployment template. To recover this exact change, after checking the current
|
|
target and the source record:
|
|
|
|
```sh
|
|
python3 docs/changes/CUST-WP-0080/activate_forge_template.py \
|
|
--proposal docs/changes/CUST-WP-0080/forge-template-proposal.json \
|
|
--receipt /tmp/forge-template-rollback.json --rollback
|
|
```
|
|
|
|
Rollback removes only the exact added mounts/volume and sets the added environment
|
|
variable to `/usr/share/git-core/templates`. Merely removing the environment
|
|
variable would leave the saved application/global-Git setting behind. The
|
|
ConfigMap remains inert; original and already inherited repository hooks remain.
|
|
Readiness, health, exact original 22 profiles, binary custody and default template
|
|
selection must pass again. Reconcile the owner Helm source to that explicit default
|
|
before another deployment; the original source otherwise intentionally re-enables
|
|
the desired control. Unknown concurrent changes cause refusal and require the
|
|
railiance-forge abort owner to review the current target, not overwrite it.
|
|
|
|
Automatic recovery after an incomplete apply is limited to a Deployment whose
|
|
template matches the exact attempted result. An uncertain submission checks
|
|
current state before deciding whether recovery is needed. The readiness budget
|
|
is 240 seconds per rollout/recovery; failure remains unverified in the receipt.
|
|
|
|
The original October 12 receive-hook activation retains its old pod binding.
|
|
Do not edit that old proposal to pretend it targets the replacement pod.
|
|
|
|
## Remaining acceptance
|
|
|
|
This closes configuration persistence and native Git inheritance for future
|
|
creation paths that use Forgejo's configured Git initialization. It does not prove
|
|
an authenticated production API/browser creation, SSO journey or imported/mirrored
|
|
content check. Imports and mirrors use clone/fetch; a receive hook is insufficient
|
|
for those paths. The refreshed inventory has 166 repositories: 22 installed
|
|
profiles and 144 builtin-only inventories. Existing repository expansion, CI
|
|
authority, private finding-to-response, historical/LFS/log/artifact coverage and
|
|
the applicable DSM requirements remain open in the existing owner plans.
|
|
|
|
Validation: 30 isolated exact-image lifecycle/configuration/rollback checks, six
|
|
conditional-patch/recovery tests, non-secret Helm rendering and matching server
|
|
dry-run. Local test containers were removed. The isolated environment used SQLite;
|
|
the deployed proof is scoped to configuration, restart, Git inheritance and the
|
|
preserved existing profiles.
|
|
|
|
## October 13 custody regression and recovery
|
|
|
|
The original generation-12 receipt proves only its listed checks. Ordinary source
|
|
push acceptance subsequently failed: Kubernetes volume processing left the
|
|
scanner binaries group-writable (0775), which the scanner correctly refuses.
|
|
The trial remains failed; later corrections are recovery revisions of the same
|
|
proposal, not new unchanged successes. Do not use the original malformed-input
|
|
check as evidence that the scanner can open and scan its admitted executable.
|
|
|
|
- Revision 2: `forge-custody-repair-proposal.json` and
|
|
`repair_forge_custody.py` restore only the two hash-pinned files to 0755.
|
|
- Revision 3: `forge-custody-rollout-proposal.json` and
|
|
`deploy_forge_custody.py` add the unprivileged first init container. The exact
|
|
Helm source is railiance-apps `50b66c4`; only the existing security subtree is
|
|
mounted. Kubernetes defaults are declared explicitly. The first startup and
|
|
real installed-scanner receive probe passed.
|
|
- Revision 4: `forge-custody-restart-proposal.json` and
|
|
`restart_forge_custody.py` repeat acceptance on another pod. Use its receipt to
|
|
determine completion. The revision-3 `--restart-proof` preparation is withdrawn:
|
|
its local JSON Pointer helper did not decode the annotation's slash. Its dry-run
|
|
refused before mutation. Original executed files and hashes remain preserved.
|
|
|
|
The guard checks all artifact hashes and owners before changing either mode. It
|
|
refuses unexpected permissions, symlinks and mismatched binaries. Missing or
|
|
changed artifacts stop startup for investigation; never disable scanning to make
|
|
that check pass. The six isolated custody checks simulate fsGroup mode changes.
|
|
Native probes use temporary repositories and the real inherited installed hook;
|
|
production builtin authorization is excluded there. A normal source sync push is
|
|
required separately for authenticated SSH acceptance.
|
|
|
|
For rollback after revision 4, first conditionally remove only the owned
|
|
`custodian.coulomb.social/custody-proof` annotation whose value is the revision-4
|
|
marker. Review the resulting template against revision 3's patched digest; wait
|
|
for that replacement to finish. Then revision 3 `--rollback` removes only the
|
|
exact guard, waits for readiness, and repairs the exact binaries to 0755 after
|
|
remount. The next unguarded restart may widen modes again, so rollback is temporary
|
|
recovery and does not establish durable acceptance. Reconcile the owner Helm
|
|
source before its next deployment. Any unexpected deployment or artifact change
|
|
stops this procedure for the named abort owner. Original template rollback is a
|
|
separate operation and must not silently remove the custody repair.
|
|
|
|
### Exact original proposal storage
|
|
|
|
`forge-template-proposal.json` and `forge-template-source-render.json` are now
|
|
lossless archival envelopes. A public ConfigMap source checksum under a filename
|
|
containing `secret` triggered the generic API-key detector. The archive keeps
|
|
paths and SHA-256 values in separate fields and retains all original metadata.
|
|
No detector ignore, exception or rule change was added. The executed original
|
|
proposal digest remains unchanged; it is the digest of the restored bytes, not
|
|
of the envelope. `forge-custody-metadata-triage.json` records this classification.
|
|
|
|
Restore the historical proposal to a new private file before using its original
|
|
executor (which remains byte-for-byte unchanged):
|
|
|
|
```sh
|
|
python3 docs/changes/CUST-WP-0080/restore_forge_proposal.py \
|
|
docs/changes/CUST-WP-0080/forge-template-proposal.json \
|
|
/tmp/forge-template-original.json
|
|
```
|
|
|
|
The helper refuses an existing destination or any reconstruction whose digest
|
|
differs. Restoration does not authorize replaying a stale live proposal.
|