From ce695337f5f862c6195c5e7f779ed4b4d2345167 Mon Sep 17 00:00:00 2001 From: tegwick Date: Sun, 13 Sep 2026 21:19:13 +0200 Subject: [PATCH] Record completed P04 recovery rollout and acceptance Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a092fe-13b1-7f12-ac74-7d258af4d79c --- .../privacyidea/enable-factor-confirmation.py | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 sso-mfa/k8s/privacyidea/enable-factor-confirmation.py diff --git a/sso-mfa/k8s/privacyidea/enable-factor-confirmation.py b/sso-mfa/k8s/privacyidea/enable-factor-confirmation.py new file mode 100644 index 0000000..2f72c13 --- /dev/null +++ b/sso-mfa/k8s/privacyidea/enable-factor-confirmation.py @@ -0,0 +1,30 @@ +"""Enable possession proof for newly enrolled TOTP factors; never touch existing factors.""" +import json,subprocess +def metadata(*args): + r=subprocess.run(['kubectl',*args,'-o','json'],capture_output=True,check=True,timeout=20) + return json.loads(r.stdout)['metadata'] +assert metadata('get','ns','kube-system')['uid']=='a553c742-0115-43d4-99a4-a5ca56fe0786' +assert metadata('-n','mfa','get','deploy','privacyidea')['uid']=='58c7f96d-61cb-4dd4-bca2-54661c0ac375' +code='''import contextlib,io,json,logging +result={"success":False} +with contextlib.redirect_stdout(io.StringIO()),contextlib.redirect_stderr(io.StringIO()): + try: + logging.disable(logging.CRITICAL) + from privacyidea.app import create_app + from privacyidea.lib.policy import set_policy,PolicyClass + app=create_app(config_name="production",silent=True) + with app.app_context(): + name="keycape-confirm-totp-enrollment" + set_policy(name=name,scope="enrollment",action="verify_enrollment=totp",realm="coulomb") + rows=PolicyClass().list_policies(name=name) + result={"success":len(rows)==1 and rows[0]["active"] and rows[0]["action"].get("verify_enrollment")=="totp","policy":name,"existing_factors_changed":False} + except Exception:pass +print(json.dumps(result)) +raise SystemExit(0 if result["success"] else 1) +''' +r=subprocess.run(['kubectl','-n','mfa','exec','deployment/privacyidea','-c','privacyidea','--','python3','-c',code],capture_output=True,timeout=45) +try:result=json.loads(r.stdout) +except Exception:result={'success':False} +assert set(result)<={'success','policy','existing_factors_changed'} +print(json.dumps(result)) +raise SystemExit(0 if result.get('success') else 1)