Files
Linux_post_install/AgentsReport/builder/2026-09-06_stab-security.md
T
Your Name d817c37652
gates / consistency-and-conventions (push) Successful in 26s
fix: stabilization pass — fail-closed auth, ai flag validation, lint/config/security hardening, regression tests
17-point code-level audit executed via Explorer->Architect->Builder->Tester->Reviewer;
Reviewer accepted (APPROVE_WITH_NOTES; 3 block-list items resolved):

- security: telegram sender-owner AND-gate + TELEGRAM_OWNER_ID, matrix
  MATRIX_ROOM_ID fail-closed, gpg --passphrase-fd 3 (no argv secret),
  /dev/tcp positional-arg form (checkport/smb-client/share-lib/NET_PROBE),
  eval deny-by-default + --no-command-execution carried by both chat bridges,
  tty-gated --trust; config/{telegram,matrix}.env reference templates
- ai: all ExecStart flags validated against installed llama.cpp
  (requested->error, default->omit+warn, CONFIG_REQUESTED_FLAGS); single-file
  hf download failure rc=1 + no .hf-meta; LLAMACPP_HOST coherent;
  POS_SUBCMDS + metadata gaps closed
- tooling: lint-conventions Bash-native rewrite (~24-30x faster, rules and
  output byte-identical, :num restored); pos system uninstall covers all 12
  libs + scale-tail + flags dir + systemd user units (|| true) + plugin
  markers; anchored .bash_completion/.bashrc removal replaces sed -i '/pos/d'
- config: canonical load_env_file in lib/config-ui.sh (CRLF strip, env-wins,
  XDG, LOADED_ENV_KEYS); 9 tools migrated; entertainment-lib collapsed to
  wrappers; docker-compose deliberately unmigrated (source semantics)
- tests: first committed regression suite — tests/run-tests.sh zero-dep
  runner + make test; 12 files / 179 checks / 0 skip / ~52s; hard skip
  contract; systemd-analyze verify on generated unit PASS

Verified: make gen idempotent; make check green; make lint 0 FAIL, 0 WARN;
make test green; bash -n clean; git diff --check clean. Audit deliverables +
agent reports + AGENT_TODO Done entry included.
2026-09-06 07:25:44 -04:00

6.4 KiB
Raw Blame History

Builder report — 2026-09-06 stabilization security track (D-A, V3, V5, V7)

TL;DR

Status: IMPLEMENTED — all approved changes done, gates green, 23/23 probes PASS. Scope: architect decision D-A (telegram owner gate, matrix fail-closed) + explorer findings V3 (backup gpg argv leak), V5 (/dev/tcp host injection), V7 (documented notice); plus template-creation and two hygiene fixes listed in the brief. Verified: bash -n on all touched scripts, make gen, make check (check-sync: OK), make lint (0 FAIL, 0 WARN), runtime registry smoke (pos config telegram scope shows TELEGRAM_OWNER_ID), and a 23-assertion probe harness (fail-closed telegram/matrix behavior, gpg fd + cleanup, host-injection attempts) — all PASS. Files changed: 9 code/doc files in scope, 2 new config templates, plus DOC/AGENT_Context_Project.md + completions/pos.bash from the required make gen.

Step 1: D-A telegram listener owner gate — [DONE]

  • bin/pos-communication-telegram-listener: per-message authorization replaced by fail-closed AND-gate: message processed only when chat == TELEGRAM_CHAT_ID AND from_id == TELEGRAM_OWNER_ID; unauthorized → warn-only, skip (no reply) (bin/pos-communication-telegram-listener:805).
  • Owner unset → daemon runs but every command is ignored with warn "TELEGRAM_OWNER_ID unset — ignoring command" (bin/pos-communication-telegram-listener:798); startup logs "commands authorized" or warns fail-closed; run line now logs owner (bin/pos-communication-telegram-listener:518-530 region).
  • bin/pos-communication-telegram-sender registry line gained TELEGRAM_OWNER_ID=digits:Numeric Telegram user id (your account) allowed to run chat commands; usage() config block updated.
  • Probes 1a1d prove: owner-unset → warning + no send; right chat+user → executes; wrong user → ignore; wrong chat → ignore. 8/8 PASS.

Step 2: D-A matrix listener fail-closed — [DONE]

  • bin/pos-communication-matrix-listener: with MATRIX_ROOM_ID unset the daemon runs but shows room none — fail-closed and watches NO room; the room filter is now fail-closed ([ -z "$room_only" ] || [ "$room" != "$room_only" ]), startup warn at bin/pos-communication-matrix-listener:519.
  • Probe 2 (owner message, room unset) proves: warning logged, run line shows fail-closed, nothing answered. 3/3 PASS.

Step 3: Config templates + sender registry — [DONE]

  • config/telegram.env and config/matrix.env created as commented reference templates (config/ai.env style) since no templates existed.
  • Verified postinstall.sh:22-50 copies only explicitly named entertainment.env/system.env/notify.env/ai.env (no glob) — templates are NOT auto-installed; runtime provisioning remains pos config telegram / pos config matrix. Residual gap: postinstall.sh does not copy the new templates (out of scope).

Step 4: V3 backup gpg passphrase fd — [DONE]

  • bin/pos-system-backup: both gpg calls use --passphrase-fd 3 + 3<<<"$PASS" (bin/pos-system-backup:197, :207); failed encrypt removes the plaintext archive + err "encryption failed — plaintext archive removed, nothing left behind"; failed verify removes the corrupt .gpg + err; unset PASS retained.
  • Probes: gpg argv has --passphrase-fd 3, no --passphrase <value>, secret absent from argv/logs; success path leaves only .gpg (chmod 600); fail path leaves neither plaintext nor partial artifact, with honest error. 8/8 PASS.

Step 5: V5 /dev/tcp host injection — [DONE]

  • Positional-arg form everywhere a remote host reaches bash -c 'exec 3<>/dev/tcp/…':
    • bin/pos-network-checkport:135 (check_tcp), :168/:170 (banner probes) — _ "$ip" "$port".
    • bin/pos-share-smb-client:94_ "$host" "$SMB_PORT".
    • lib/share-lib.sh:61 (share_port_probe, shared core) — _ "${1}" "${2}".
    • bin/pos-network-download:28 — default NET_PROBE now timeout 3 bash -c 'exec 3<>/dev/tcp/$1/$2' _ 8.8.8.8 53.
  • POS.md NET_PROBE doc updated at line 188 (also fixed pre-existing missing > in the doc example).
  • Probes: hostile host 8.8.8.8;touch … passed as ONE literal arg, probe source uses $1/$2, no marker file created, hostile connect fails harmlessly; same for share_port_probe and smb-client probe_server. 8/8 PASS.

Step 6: V7 notice + doc/hygiene updates — [DONE]

  • DOC/howto/communication.md: one-time Telegram setup notes TELEGRAM_OWNER_ID (set via pos config telegram) and the inherent token-in-argv caveat of Bot API URLs (revoke if leaked); owner-only bullet for chat commands; matrix self-messaging bullet.
  • POS.md: telegram-listener row (owner id), matrix-listener row (fail-closed), backup row (passphrase on internal fd — never argv), telegram/matrix paragraphs (~372/402).
  • Hygiene: apps/ai/llamacpp.sh chmod 755 (still untracked); DOC/APPS.md line 3 app count 16 → 18.

Step 7: Gates + probes — [DONE]

  • bash -n on all 10 touched scripts: OK.
  • make gen OK (required by POS_CONFIG change; also folded in parallel-track drift), then regeneration re-verified.
  • make check: OK. make lint: 0 FAIL, 0 WARN.
  • Probe harness /tmp/opencode/probe-stab.sh (23 assertions): PASS=23 FAIL=0. Harness uses stub curl/gpg/sudo (secret-free argv assertions), extracted real function bodies verbatim for checkport/smb-client/share-lib, and verifies no marker file is created by hostile hosts.

Residual risks / follow-up

  • config/telegram.env / config/matrix.env are reference templates only — not wired into postinstall.sh (out of scope; installer currently copies only 4 explicit env files).
  • Existing deployments without TELEGRAM_OWNER_ID / MATRIX_ROOM_ID now ignore all chat commands (INTENDED fail-closed; startup warn tells the operator to run pos config telegram / pos config matrix).
  • Matrix-sender unchanged (its registry already listed MATRIX_ROOM_ID).
  • Parallel tracks still dirty in git (ai track, app templates, lint-conventions, AGENT_TODO, docs) — not touched here.

Files changed (this track only)

  • bin/pos-communication-telegram-listener, bin/pos-communication-telegram-sender, bin/pos-communication-matrix-listener (D-A)
  • bin/pos-system-backup (V3)
  • bin/pos-network-checkport, bin/pos-share-smb-client, lib/share-lib.sh, bin/pos-network-download (V5)
  • config/telegram.env, config/matrix.env (new templates)
  • DOC/POS.md, DOC/howto/communication.md, DOC/APPS.md (docs)
  • DOC/AGENT_Context_Project.md, completions/pos.bash (make gen output)
  • apps/ai/llamacpp.sh (mode 755 only)