fix(case2-unit): factory Console takes the paired --sso --send; .53 launches through the proxy (Vikunja #415, #416)
The factory profile of scripts/case2-unit.sh now takes the bare pair --sso --send, ported from the lane's serve_flags rule (b00019548). Either flag alone refuses, and the proxy preview set and the proof pair still refuse. Before any unit write, a bounded query run as the stack user, through the existing config-query supervisor, checks that the stack user's system config has console.sso; the Console refuses --sso without it at start (packages/webui/src/cli.mjs:95). The server needs no change. The library profile is unchanged: still read-only, still refusing --send and --sso. Taking library --send with forward-auth and proof would need the #385 refusal reverted in cli.mjs:63, serve.mjs:681 and the service, release and upgrade scripts, so it is not done here. docs/guides/case1-business.mosaic-stack.json now launches claude-opus-5-5 with provider proxy, route anthropic, under account factory with credential proxy.
This commit is contained in:
1 parent
1ff45c4ad6
commit
bd79daffdd
4 files changed
+119
-14
No files matched your search
+24
-9
@@ -20,7 +20,7 @@
|
||||
# never imports copy code. This adds sudo and GNU timeout to the installer
|
||||
# dependencies. The inner query supervisor runs after the uid drop: 5 s inside,
|
||||
# 7 s on root's wait. Fixed system Bash, setsid, sleep, timeout and head are
|
||||
# resolved and root-validated. Only the config query uses this supervisor.
|
||||
# resolved and root-validated. Only the config queries use this supervisor.
|
||||
# It renders the default instance only.
|
||||
#
|
||||
# The library profile takes exactly these serve flags, each once:
|
||||
@@ -29,10 +29,13 @@
|
||||
# --auth-header HEADER --allow-user ID
|
||||
# --proof-header NAME --proof-file PATH
|
||||
# It is proxy-preview read-only until Case 2 supports --sso (#412); --send
|
||||
# is explicitly refused. The proof still protects proxy preview reads.
|
||||
# and --sso are explicitly refused. The proof still protects proxy preview reads.
|
||||
# The factory profile takes --port N (1..1023) and --business ID, and an
|
||||
# optional bare --tester-socket marker. Retired tester TCP refuses. Only factory takes
|
||||
# --pm and --claude.
|
||||
# optional bare --tester-socket marker. It also takes the paired bare
|
||||
# --sso --send (#415): the Console signs its owner in from console.sso, which
|
||||
# the stack user's config must have; either one alone refuses, and the
|
||||
# preview and proof flags still refuse. Retired tester TCP refuses. Only
|
||||
# factory takes --pm and --claude.
|
||||
#
|
||||
# On a re-install the installed units must equal the render in everything
|
||||
# but the copy id, and all selected units must name one copy, so a re-pin or rollback
|
||||
@@ -298,6 +301,7 @@ tester_capture() (
|
||||
cat -- "$file"
|
||||
)
|
||||
|
||||
SSO_QUERY='import {pathToFileURL} from "node:url";const m=await import(pathToFileURL(process.argv[1]).href);const s=m.loadSystem();console.log(JSON.stringify({sso:Boolean(s.console&&s.console.sso)}));'
|
||||
TESTER_QUERY='import {readFileSync} from "node:fs";import {pathToFileURL} from "node:url";const m=await import(pathToFileURL(process.argv[1]).href);const s=m.loadSystem();console.log(JSON.stringify({dataRoot:s.dataRoot,socket:readFileSync(process.argv[2],"utf8").includes("MOSAIC_TESTER_SOCKET_V1")}));'
|
||||
tester_facts() {
|
||||
local LC_ALL=C pattern='^\{"dataRoot":"([A-Za-z0-9/._@+-]+)","socket":(true|false)\}$'
|
||||
@@ -342,7 +346,7 @@ tester_location() {
|
||||
serve_flags() {
|
||||
local -A seen=()
|
||||
local flags='' name value
|
||||
local port='' public_host='' auth_header='' allow_user='' proof_header='' proof_file='' tester_socket=0
|
||||
local port='' public_host='' auth_header='' allow_user='' proof_header='' proof_file='' tester_socket=0 sso=0
|
||||
local i=0 n=${#SERVE[@]}
|
||||
while [ "$i" -lt "$n" ]; do
|
||||
name="${SERVE[$i]}"
|
||||
@@ -351,10 +355,8 @@ serve_flags() {
|
||||
--tester-socket) [ "$PROFILE" = factory ] || die "the library profile refuses --tester-socket" ;;
|
||||
--checkout) die "refusing --checkout: Case 2 has no queue panel" ;;
|
||||
--board) die "refusing --board: Case 2 runs no control board" ;;
|
||||
--sso) die "refusing --sso: the Console signs people in through the proxy, with the preview set and the proof pair (Q175 phase 2 is a follow-up)" ;;
|
||||
--send)
|
||||
[ "$PROFILE" = library ] || die "the factory profile refuses --send: its host has no proxy"
|
||||
die "the library profile is read-only; refusing --send until Case 2 supports --sso (#412)" ;;
|
||||
--sso) [ "$PROFILE" = factory ] || die "refusing --sso: the Console signs people in through the proxy, with the preview set and the proof pair (Q175 phase 2 is a follow-up)" ;;
|
||||
--send) [ "$PROFILE" = factory ] || die "the library profile is read-only; refusing --send until Case 2 supports --sso (#412)" ;;
|
||||
--port|--business) ;;
|
||||
--public-host|--auth-header|--allow-user|--proof-header|--proof-file)
|
||||
[ "$PROFILE" = library ] || die "the factory profile refuses $name: its host has no proxy" ;;
|
||||
@@ -363,6 +365,8 @@ serve_flags() {
|
||||
[ -z "${seen[$name]:-}" ] || die "serve flag $name given twice"
|
||||
seen[$name]=1
|
||||
if [ "$name" = --tester-socket ]; then tester_socket=1; flags="$flags --tester-socket"; i=$((i + 1)); continue; fi
|
||||
if [ "$name" = --sso ]; then sso=1; flags="$flags --sso"; i=$((i + 1)); continue; fi
|
||||
if [ "$name" = --send ]; then flags="$flags --send"; i=$((i + 1)); continue; fi
|
||||
[ $((i + 1)) -lt "$n" ] || die "serve flag $name needs a value"
|
||||
value="${SERVE[$((i + 1))]}"
|
||||
case "$name" in
|
||||
@@ -391,6 +395,17 @@ serve_flags() {
|
||||
[ -n "${seen[$name]:-}" ] || die "serve flag $name is required"
|
||||
done
|
||||
if [ "$PROFILE" = factory ]; then
|
||||
# #415: only the paired owner sign-in and writes. No preview header or
|
||||
# proof file is inferred. The Console refuses --sso without console.sso
|
||||
# at start; this asks the stack user's config first, before any write.
|
||||
[ "$sso" = 0 ] || [ -n "${seen[--send]:-}" ] || die "refusing --sso without --send in the factory profile"
|
||||
[ -z "${seen[--send]:-}" ] || [ "$sso" = 1 ] || die "the factory profile refuses --send without --sso"
|
||||
if [ "$sso" = 1 ]; then
|
||||
local answer
|
||||
answer="$(tester_capture 5 7 4096 "$USER_NAME" "$HOME_DIR" "$UNIT_PATH" "$NODE" --input-type=module -e "$SSO_QUERY" "$COPY/packages/cli/src/config.mjs")" || die "sso config query $(tester_capture_reason "$?")"
|
||||
[ "$answer" != '{"sso":false}' ] || die "--sso needs console.sso in $USER_NAME's system config"
|
||||
[ "$answer" = '{"sso":true}' ] || die "sso config query has invalid facts"
|
||||
fi
|
||||
if [ "$tester_socket" = 1 ]; then
|
||||
local query
|
||||
query="$(tester_capture 5 7 4096 "$USER_NAME" "$HOME_DIR" "$UNIT_PATH" "$NODE" --input-type=module -e "$TESTER_QUERY" "$COPY/packages/cli/src/config.mjs" "$COPY/packages/webui/src/cli.mjs")" || die "tester config query $(tester_capture_reason "$?")"
|
||||
|
||||
Reference in new issue
Block a user