Prepare persistent personal app release and guarded OIDC repair
Some checks failed
Use-case regression gate / usecase-regressions (push) Has been cancelled

Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a10e2d-a5ef-7e92-b03d-b1694e915680
This commit is contained in:
tegwick 2026-10-06 15:14:38 +02:00
parent a1989f19db
commit ac7bac1852
7 changed files with 164 additions and 36 deletions

17
.dockerignore Normal file
View file

@ -0,0 +1,17 @@
.git
.venv
.env
.env.*
.auth
var
staticfiles
db.sqlite3
**/__pycache__
**/*.pyc
.pytest_cache
.ruff_cache
scripts/node_modules
tests
docs
history
workplans

View file

@ -38,7 +38,8 @@ COPY manage.py pyproject.toml ./
COPY coulomb_social ./coulomb_social
COPY scripts/docker-entrypoint.sh /app/docker-entrypoint.sh
RUN chmod +x /app/docker-entrypoint.sh \
RUN python manage.py collectstatic --noinput \
&& chmod +x /app/docker-entrypoint.sh \
&& chown -R appuser:appuser /app
USER appuser

View file

@ -29,19 +29,13 @@ X-Verified-Oidc-Claims: {"iss","sub","tenant","principal_type","aud",...}
plus `coulomb-social`. Trust is the proxy secret; claims were verified by
KeyCape OIDC at the app edge.
### Operator: enable HTTP mode locally
### Governed credential configuration
```bash
# secret never printed to shell history if you use process substitution carefully
export USER_ENGINE_BASE_URL=https://users.92-205-62-239.nip.io
export USER_ENGINE_PROXY_SECRET="$(kubectl -n user-engine get secret user-engine-runtime \
-o jsonpath='{.data.proxy-secret}' | base64 -d)"
export USER_ENGINE_EXPECTED_AUDIENCE=user-engine-portal
# then OIDC or dev-login
```
OpenBao lane for the proxy secret (future): document under railiance-platform
workload KV; until then kubectl-sourced secret is operator-only on the workstation.
Live HTTP mode already uses mounted runtime credential references. Do not
extract the proxy secret with kubectl/jsonpath or print it into shell/chat.
For a new credential need, run `warden route find "user-engine trusted proxy credential" --json`
and follow the owning OpenBao/platform lane. Interactive personal login belongs
to KeyCape/NetKingdom; it does not require retrieving this server credential.
## Profile attributes (shell only)

View file

@ -0,0 +1,47 @@
#!/usr/bin/env python3
"""Restore the historical public client through NetKingdom's guarded lane.
Inspection is read-only. Apply requires exact founder approval and a fresh
UID/resource-version receipt. Secret values stay inside the owner helper.
"""
import importlib.util
import os
from pathlib import Path
from types import SimpleNamespace
def load(name, path):
spec = importlib.util.spec_from_file_location(name, path)
result = importlib.util.module_from_spec(spec)
spec.loader.exec_module(result)
return result
def configure(owner_root):
rollout = load("keycape_guarded_rollout", owner_root / "portal-client-rollout.py")
historical = load("coulomb_registration", owner_root / "register-coulomb-social.py")
original = rollout.replacement
rollout.portal = SimpleNamespace(CLIENT_ID=historical.CLIENT_ID, CLIENT=historical.CLIENT)
def replacement(secret):
_, config, _ = rollout.pin.issuer_document(secret)
for client in config.get("clients", []):
if client.get("clientId") == historical.CLIENT_ID:
rollout.require(client == historical.CLIENT, "existing_registration_differs")
return original(secret)
rollout.replacement = replacement
return rollout
if __name__ == "__main__":
try:
owner_root = Path(os.environ.get(
"NET_KINGDOM_KEYCAPE_DIR",
str(Path.home() / "net-kingdom/sso-mfa/k8s/keycape"),
))
helper = configure(owner_root)
except Exception:
print('{"status":"failed","reason":"owner_helper_unavailable"}')
raise SystemExit(1)
raise SystemExit(helper.main())

View file

@ -1,26 +1,8 @@
#!/usr/bin/env bash
# Register this app's OIDC client on live KeyCape (kc.coulomb.social).
# Delegates to net-kingdom/sso-mfa/k8s/keycape/register-coulomb-social.sh
# Inspect by default; explicit dry-run/apply use guarded owner receipts.
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
NK_SCRIPT="${NET_KINGDOM_KEYCAPE_DIR:-$HOME/net-kingdom/sso-mfa/k8s/keycape}/register-coulomb-social.sh"
if [[ ! -x "$NK_SCRIPT" && ! -f "$NK_SCRIPT" ]]; then
echo "ERROR: KeyCape register script not found: $NK_SCRIPT" >&2
echo "Clone net-kingdom or set NET_KINGDOM_KEYCAPE_DIR." >&2
exit 1
if [[ $# -eq 0 ]]; then
set -- inspect
fi
chmod +x "$NK_SCRIPT" 2>/dev/null || true
bash "$NK_SCRIPT"
echo ""
echo "Next: export OIDC settings and restart the app:"
echo " export OIDC_ENABLED=true"
echo " export OIDC_ISSUER=https://kc.coulomb.social"
echo " export OIDC_CLIENT_ID=coulomb-social"
echo " export OIDC_REDIRECT_URI=http://127.0.0.1:8008/auth/callback/"
echo " # no client secret — public + PKCE"
echo " make run"
echo "Docs: $ROOT/docs/identity/oidc-client.md"
exec python3 "$ROOT/scripts/keycape-client-repair.py" "$@"

View file

@ -0,0 +1,49 @@
"""Synthetic owner-lane checks; run with python3 scripts/test_keycape_client_repair.py."""
import base64
import json
from pathlib import Path
import unittest
import yaml
from importlib.machinery import SourceFileLoader
adapter = SourceFileLoader("csoc_repair", str(Path(__file__).with_name("keycape-client-repair.py"))).load_module()
class RepairTests(unittest.TestCase):
def setUp(self):
self.rollout = adapter.configure(Path.home() / "net-kingdom/sso-mfa/k8s/keycape")
def fixture(self, clients):
raw = ("# keep comment\nauthelia:\n issuer: https://auth.example.invalid\n"
" clientSecret: synthetic-marker\nclients:\n" +
yaml.safe_dump(json.loads(json.dumps(clients)), sort_keys=False) + "tokenLifetime: 15m\n")
return {"data": {"config.yaml": base64.b64encode(raw.encode()).decode(),
"key.pem": "synthetic-key"}}, raw
def test_insert_preserves_bytes_and_is_idempotent(self):
secret, raw = self.fixture([{"clientId": "existing", "clientType": "public"}])
encoded, changed = self.rollout.replacement(secret)
updated = base64.b64decode(encoded).decode()
self.assertTrue(changed)
self.assertTrue(updated.startswith(raw[:raw.index("tokenLifetime:")]))
self.assertTrue(updated.endswith("tokenLifetime: 15m\n"))
expected = yaml.safe_load(raw)
expected["clients"].append(self.rollout.portal.CLIENT)
self.assertEqual(yaml.safe_load(updated), expected)
self.assertEqual(secret["data"]["key.pem"], "synthetic-key")
secret["data"]["config.yaml"] = encoded
self.assertEqual(self.rollout.replacement(secret), (encoded, False))
def test_refuses_different_or_duplicate_registration(self):
client = self.rollout.portal.CLIENT
for clients in [[dict(client, redirectUris=["https://other.invalid/callback"])],
[dict(client, allowedScopes=["openid", "admin"])],
[client, client]]:
with self.subTest(clients=clients), self.assertRaises(self.rollout.Refused):
self.rollout.replacement(self.fixture(clients)[0])
if __name__ == "__main__":
unittest.main()

View file

@ -66,7 +66,7 @@ an instruction to bulk-move every space before the first user review.
```task
id: CSOC-WP-0008-T01
status: wait
status: progress
priority: high
state_hub_task_id: "6adce69f-9011-5ada-a920-b2228aa15218"
```
@ -266,3 +266,41 @@ clipboard and blocked/manual fallback pass Chromium checks with synthetic data.
Full application suite: 87 passed; new test Ruff clean. Real latest protocol
reconciliation and actual mail-client/user review remain T03/T09, not completed
by these tests. No live deploy, private-data import or mail sending performed.
## Live orientation and personal account — 2026-10-06
Fresh checks confirm a healthy 1/1 coulomb-social Helm workload on railiance01
(92.205.62.239), image 7fcd0cf, revision 9. app.coulomb.social landing and health
return 200; KeyCape discovery is live. No content PVC/CONTENT_ROOT exists in
that old release. One live Member links the user-selected tegwick identity to
KeyCape and tenant:coulomb; one demo space exists. No new password/account is
needed. The user tried sign-in and received invalid_profile_usage / unknown
client_id. Guarded issuer inspection confirms the coulomb-social client is absent;
the stored Member and healthy discovery did not prove interactive login worked.
T01 now progresses by preparing the latest tested app image with collected
static assets and an owning-chart persistent CONTENT_ROOT upgrade. Single-writer
Recreate avoids concurrent filesystem writers and rolling CPU surge. Exact live
change approval follows the prepared diff/dry-run and immutable image receipt.
Node CPU requests observed 3455m/4000m; disk has 123G available.
No deployment or credential change was made by these read-only checks.
## T11 — Restore personal OIDC sign-in
```task
id: CSOC-WP-0008-T11
status: progress
priority: high
```
Restore the historical NetKingdom public coulomb-social authorization-code/PKCE
client through the owning guarded helper; refuse differing existing registrations,
preserve unrelated configuration bytes and Secret data, pin cluster identity and
Secret UID/resourceVersion. Inspection and server dry-run passed on 2026-10-06;
no live change made. Existing historical ordinary AAL1 behavior (mfaRequired:
false) is explicit in the review packet; shared issuer restart requires exact
founder approval. User tegwick must then confirm interactive login. Do not mark
this task done on an HTTP redirect or discovery-only check.
Knowledge receipt: emergent-security 0.2.6 identity, verified-files,
orientation-only; digest 8d1d6a9d4d07fec7b619618de7dfe2be2254c1790f85f4198c7fe19db9751c02.