Require an absolute owner command after attended OpenBao login.
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s

A relative scripts path can fail to spawn after a successful contained
OIDC session, which Warden then revokes. The wrapper now resolves the
command first; T03 records that this attempt did not write the role.

Assistant: grok
Assistant-Session: 01a0a23b-3bf0-7341-b4e5-9dc05f72573a
This commit is contained in:
codex 2026-09-15 02:16:42 +02:00
parent bb1aa85aea
commit 7496d9fab5
5 changed files with 81 additions and 13 deletions

View file

@ -0,0 +1,15 @@
{
"schema": "railiance-platform.attended-login-attempt.v1",
"observed_at": "2026-09-15T00:11:57Z",
"lane_id": "openbao-platform-admin-login",
"plan_verdict": "founder_required",
"login_helper_reached": true,
"owner_command_started": false,
"warden_message": "attended command could not start; the login session was revoked",
"session_revoked": true,
"role_mutated": false,
"ingress_mutated": false,
"credential_values_emitted": false,
"cause": "relative owner command path failed to spawn after successful contained login",
"retry": "python3 scripts/openbao-attended-exec.py -- /home/worsch/railiance-platform/scripts/openbao-apply-operator-loopback-callback.sh"
}

View file

@ -37,13 +37,17 @@ silent and Warden self-revokes the attended session:
warden plan \ warden plan \
"attended OpenBao platform administration to add the exact operator-tunneled OIDC callback to auth/netkingdom/role/platform-admin" \ "attended OpenBao platform administration to add the exact operator-tunneled OIDC callback to auth/netkingdom/role/platform-admin" \
--json --json
warden access openbao-platform-admin-login --exec -- \ python3 scripts/openbao-attended-exec.py -- \
scripts/openbao-apply-operator-loopback-callback.sh /home/worsch/railiance-platform/scripts/openbao-apply-operator-loopback-callback.sh
``` ```
The plan must return `founder_required` and select The plan must return `founder_required` and select
`openbao-platform-admin-login`. Do not run the owner command directly with a `openbao-platform-admin-login`. The owner command must be an absolute path:
persistent token. Warden's contained child inherits the caller's cwd, so a relative `scripts/...`
path raises OSError, prints `attended command could not start`, and revokes a
successful login without applying the callback. Do not run the owner command
directly with a persistent token. The wrapper also supplies the WSL browser
launcher when native `xdg-open` is absent.
## Guarded sequence ## Guarded sequence

View file

@ -6,14 +6,32 @@ import shutil
import sys import sys
def reviewed_command(args):
if args and args[0] == '--':
args = args[1:]
if not args:
raise SystemExit('A reviewed silent owner command is required')
command = Path(args[0]).expanduser()
if not command.is_absolute():
command = Path.cwd() / command
try:
command = command.resolve(strict=True)
except OSError:
raise SystemExit('Reviewed owner command is missing')
if not os.access(command, os.X_OK):
raise SystemExit('Reviewed owner command is not executable')
return [str(command), *args[1:]]
def main(): def main():
args=sys.argv[1:] args = reviewed_command(sys.argv[1:])
if args and args[0]=='--': args=args[1:] env = os.environ.copy()
if not args: raise SystemExit('A reviewed silent owner command is required') if not any(shutil.which(x) for x in ('xdg-open', 'x-www-browser', 'www-browser')):
env=os.environ.copy()
if not any(shutil.which(x) for x in ('xdg-open','x-www-browser','www-browser')):
if not Path('/mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe').is_file(): if not Path('/mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe').is_file():
raise SystemExit('No supported attended browser launcher is available') raise SystemExit('No supported attended browser launcher is available')
env['PATH']=str(Path(__file__).resolve().parent/'operator-browser')+os.pathsep+env.get('PATH','') env['PATH'] = str(Path(__file__).resolve().parent / 'operator-browser') + os.pathsep + env.get('PATH', '')
os.execvpe('warden',['warden','access','openbao-platform-admin-login','--exec','--',*args],env) os.execvpe('warden', ['warden', 'access', 'openbao-platform-admin-login', '--exec', '--', *args], env)
if __name__=='__main__': main()
if __name__ == '__main__':
main()

View file

@ -50,6 +50,24 @@ def test_unexpected_live_role_refused(monkeypatch, mutation):
m.read_role() m.read_role()
def test_attended_wrapper_requires_absolute_existing_executable(tmp_path, monkeypatch):
import os
spec = importlib.util.spec_from_file_location(
'attended', Path(__file__).resolve().parents[1] / 'scripts/openbao-attended-exec.py')
wrapper = importlib.util.module_from_spec(spec)
spec.loader.exec_module(wrapper)
missing = tmp_path / 'missing.sh'
with pytest.raises(SystemExit, match='missing'):
wrapper.reviewed_command([str(missing)])
command = tmp_path / 'owner.sh'
command.write_text('#!/bin/sh\n')
with pytest.raises(SystemExit, match='not executable'):
wrapper.reviewed_command([str(command)])
command.chmod(0o755)
monkeypatch.chdir(tmp_path)
assert wrapper.reviewed_command(['owner.sh']) == [str(command.resolve())]
def test_silent_entrypoint_on_command_failure(tmp_path): def test_silent_entrypoint_on_command_failure(tmp_path):
import os import os
import subprocess import subprocess

View file

@ -9,7 +9,7 @@ flavor: implementation
owner: codex owner: codex
topic_slug: railiance topic_slug: railiance
created: "2026-08-23" created: "2026-08-23"
updated: "2026-09-06" updated: "2026-09-15"
related: related:
- RMASTER-WP-0020-T09 - RMASTER-WP-0020-T09
- RAPP-OPENBAO-WP-0002 - RAPP-OPENBAO-WP-0002
@ -108,3 +108,16 @@ The role endpoint has no CAS; exclusive attended administration is still needed.
Tests cover settings preservation, idempotence, drift, readback failure and Tests cover settings preservation, idempotence, drift, readback failure and
unexpected roles. No live role update or ingress retraction was performed in unexpected roles. No live role update or ingress retraction was performed in
this follow-up; attended loopback UI login remains the cutover gate. this follow-up; attended loopback UI login remains the cutover gate.
## Attended retry — 2026-09-15
Plan selected `openbao-platform-admin-login` / `founder_required` / `oidc_login`.
Contained login reached a helper-backed session, then
`warden access ... --exec -- scripts/openbao-apply-operator-loopback-callback.sh`
failed with `attended command could not start; the login session was revoked`.
That Warden string is OSError spawning the child after successful login, not an
OIDC or MFA refusal. Relative `scripts/...` is missing unless cwd is this repo;
the session was revoked and private storage cleaned. No role write, Ingress
change, or retained helper. Retry only through
`python3 scripts/openbao-attended-exec.py --` and the absolute owner command.
Do not reuse the failed relative-path attempt as callback evidence.