Move portal workloads to registry digests
This commit is contained in:
parent
52b57c99f7
commit
f854969a01
6 changed files with 42 additions and 17 deletions
|
|
@ -1,24 +1,26 @@
|
|||
{
|
||||
"captured_at": "2026-07-29T21:56:00Z",
|
||||
"captured_at": "2026-07-29T22:16:00Z",
|
||||
"checks": {
|
||||
"backup_archive_catalog_valid": true,
|
||||
"backup_checksum_valid": true,
|
||||
"backup_schedule_present": true,
|
||||
"database_ready": true,
|
||||
"identity_provisioner_registry_public_read": true,
|
||||
"metrics_authorized": true,
|
||||
"metrics_unauthorized_denied": true,
|
||||
"restore_drill_complete": true,
|
||||
"restore_migration_rows": 1,
|
||||
"restore_public_tables": 4,
|
||||
"rollback_exercised": true,
|
||||
"rollforward_restored": true
|
||||
"rollforward_restored": true,
|
||||
"user_engine_offsite_age_upload": true,
|
||||
"user_engine_registry_public_read": true
|
||||
},
|
||||
"declared_image": "user-engine:portal-2bcda7f",
|
||||
"residual_risks": [
|
||||
"Backup PVC uses the reef's single local node and is not an independent disaster-recovery copy.",
|
||||
"The directly imported image still needs publication through the approved registry lane."
|
||||
],
|
||||
"rollback_image": "user-engine:portal-746bf21",
|
||||
"declared_image": "forgejo.coulomb.social/coulomb/user-engine@sha256:60f4fa1c144c8f7b9e2e74c264e4594e63ac6a0c0f75e5cf536880b8fd99fa28",
|
||||
"identity_provisioner_image": "forgejo.coulomb.social/coulomb/identity-provisioner@sha256:ecd9ba44bb83a4809fb47e0ef016e3f71f38a87f1adbdbf0a102ac24c12f6df8",
|
||||
"offsite_artifact": "user-engine-pg-user_engine-20260729T220653Z.dump.age",
|
||||
"residual_risks": [],
|
||||
"rollback_image": "forgejo.coulomb.social/coulomb/user-engine@sha256:d25037e61c0c71dd9fbf89f653797932061b0be1fc5b4b23223821e5c2e3d6d0",
|
||||
"schema_version": "user-engine-operability-evidence/v1",
|
||||
"secret_values_observed": false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ spec:
|
|||
seccompProfile: {type: RuntimeDefault}
|
||||
containers:
|
||||
- name: provisioner
|
||||
image: identity-provisioner:12cdef5
|
||||
imagePullPolicy: Never
|
||||
image: forgejo.coulomb.social/coulomb/identity-provisioner@sha256:ecd9ba44bb83a4809fb47e0ef016e3f71f38a87f1adbdbf0a102ac24c12f6df8
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports: [{name: http, containerPort: 8080}]
|
||||
env:
|
||||
- {name: LLDAP_URL, value: "http://lldap.sso.svc.cluster.local:17170"}
|
||||
|
|
|
|||
|
|
@ -6,9 +6,11 @@ no public Ingress until the KeyCape authorization-code/PKCE edge and
|
|||
must remain impossible because the application accepts identity only from a
|
||||
trusted edge marker plus verified claims.
|
||||
|
||||
For the current pre-production bootstrap the image is imported directly into
|
||||
k3s and uses `imagePullPolicy: Never`. Replace it with the immutable Forgejo
|
||||
OCI digest after the OpenBao package-publisher lane is available.
|
||||
The portal image is published through the activity-core workload-scoped
|
||||
Forgejo package credential and deployed from
|
||||
`forgejo.coulomb.social/coulomb/user-engine` by immutable digest. The public
|
||||
package read was verified without an image pull Secret; publishing still uses
|
||||
the ExternalSecret-backed credential and temporary client state.
|
||||
|
||||
The CloudNativePG operator creates `user-engine-pg-app`, including its `uri`
|
||||
field. `user-engine-runtime` contains only the generated edge marker and must
|
||||
|
|
|
|||
|
|
@ -45,8 +45,8 @@ spec:
|
|||
seccompProfile: {type: RuntimeDefault}
|
||||
containers:
|
||||
- name: portal
|
||||
image: user-engine:portal-2bcda7f
|
||||
imagePullPolicy: Never
|
||||
image: forgejo.coulomb.social/coulomb/user-engine@sha256:60f4fa1c144c8f7b9e2e74c264e4594e63ac6a0c0f75e5cf536880b8fd99fa28
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports: [{name: http, containerPort: 8080}]
|
||||
env:
|
||||
- name: USER_ENGINE_DATABASE_URL
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ set -euo pipefail
|
|||
namespace=user-engine
|
||||
deployment=user-engine
|
||||
manifest="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/runtime.yaml"
|
||||
rollback_target="${USER_ENGINE_ROLLBACK_IMAGE:-forgejo.coulomb.social/coulomb/user-engine@sha256:d25037e61c0c71dd9fbf89f653797932061b0be1fc5b4b23223821e5c2e3d6d0}"
|
||||
exercise_rollback=false
|
||||
if [[ "${1:-}" == "--exercise-rollback" ]]; then
|
||||
exercise_rollback=true
|
||||
|
|
@ -47,12 +48,13 @@ print("%s %s %s" % (denied, response.status, int("user_engine_ready 1" in body))
|
|||
rollback_image=""
|
||||
rollback_restored=true
|
||||
if $exercise_rollback; then
|
||||
kubectl -n "$namespace" rollout undo deployment/"$deployment" >/dev/null
|
||||
kubectl -n "$namespace" set image deployment/"$deployment" \
|
||||
"portal=${rollback_target}" >/dev/null
|
||||
kubectl -n "$namespace" rollout status deployment/"$deployment" \
|
||||
--timeout=180s >/dev/null
|
||||
rollback_image="$(kubectl -n "$namespace" get deployment "$deployment" \
|
||||
-o jsonpath='{.spec.template.spec.containers[0].image}')"
|
||||
[[ "$rollback_image" != "$current_image" ]]
|
||||
[[ "$rollback_image" == "$rollback_target" ]]
|
||||
kubectl apply -f "$manifest" >/dev/null
|
||||
kubectl -n "$namespace" rollout status deployment/"$deployment" \
|
||||
--timeout=180s >/dev/null
|
||||
|
|
|
|||
|
|
@ -194,6 +194,25 @@ The remaining production gaps are registry publication and an independently
|
|||
custodied/off-node backup copy; the current PVC shares reef-railiance's single
|
||||
failure domain, so T05 remains in progress.
|
||||
|
||||
2026-07-30 follow-up: both former gaps are implemented. The activity-core
|
||||
ExternalSecret boundary published the portal and provisioner images to
|
||||
`forgejo.coulomb.social` without exposing the package credential. Anonymous
|
||||
digest inspection passed, and both live Deployments now pull immutable public
|
||||
digests. The prior verified portal image is also published by digest;
|
||||
rollback/roll-forward passed without node-local image reliance.
|
||||
|
||||
The established Option A activity-core lane produced and uploaded
|
||||
`user-engine-pg-user_engine-20260729T220653Z.dump.age` to independent
|
||||
Nextcloud custody. The plaintext dump was removed immediately and only
|
||||
non-secret sizes and the artifact name were recorded. The local isolated
|
||||
restore drill already proves the same logical dump/restore path.
|
||||
|
||||
The final T05 custody residual is narrower: `user-engine-runtime/proxy-secret`
|
||||
and `identity-provisioner-client/token` remain bootstrap Kubernetes Secrets.
|
||||
They must move to an OpenBao-owned path plus ExternalSecret and a rotation
|
||||
procedure. Creating that new write/custody lane requires the ops-mason
|
||||
executive approval gate; registry and backup work do not remain open.
|
||||
|
||||
## T06 - Prove role-scoped administration and failure safety
|
||||
|
||||
```task
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue