* docs(spec+plan): WebUI obfuscation design and implementation plan (ref #44)
Spec: docs/superpowers/specs/2026-05-12-webui-obfuscation-design.md
Plan: docs/superpowers/plans/2026-05-12-webui-obfuscation.md
The design locks the SecuBox WebUI to admin.<HOSTNAME>.<DOMAIN_SUFFIX>
via strict-regex ACLs in HAProxy AND nginx, both driven by
/etc/default/secubox as the single source of truth. New package
secubox-defaults ships the env file; secubox-haproxy API exposes
/webui/admin-domain (info), /webui/nginx-config (JWT, rendered vhost),
/webui/refresh (JWT, cache invalidate). A safe renderer script writes
the nginx vhost atomically; haproxyctl + Python /generate both inject
the strict ACL at the top of http-in and https-in frontends.
Plan has 15 tasks with TDD steps, exact file paths, and complete code
in every step (no TBD/TODO). Acceptance criteria + integration test
script included.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(secubox-defaults): scaffold package skeleton (ref #44)
* feat(secubox-defaults): ship /etc/default/secubox env file (ref #44)
* feat(secubox-defaults): postinst autodetect + dpkg-trigger (ref #44)
* feat(secubox-haproxy): webui_identity helper + tests (ref #44)
Implement webui_identity module that parses /etc/default/secubox
and exposes canonical admin URL + regex pattern for HAProxy acl.
New module:
- api/webui_identity.py: Parses SECUBOX_HOSTNAME and SECUBOX_DOMAIN_SUFFIX
with LRU cache and invalidation support.
Tests (TDD):
- tests/test_webui_identity.py: 5 test cases covering basic parsing,
missing hostname validation, custom suffix handling, comment handling,
and cache invalidation.
- tests/conftest.py: sys.path bootstrap for api/ imports.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(webui_identity): catch OSError on defaults read + test (ref #44)
* feat(secubox-haproxy): GET /webui/admin-domain endpoint (ref #44)
* feat(secubox-haproxy): GET /webui/nginx-config rendered vhost (ref #44)
* feat(secubox-haproxy): POST /webui/refresh cache invalidation (ref #44)
* feat(secubox-haproxy): secubox-render-nginx-webui safe renderer (ref #44)
* feat(haproxyctl): inject strict-regex WebUI ACL at frontend top (ref #44)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(secubox-haproxy): /generate symmetry with strict WebUI ACL (ref #44)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(secubox-haproxy): dpkg-trigger refresh on secubox-defaults-changed (ref #44)
* build(secubox-haproxy): depend on secubox-defaults (ref #44)
* test(infra): integration test for WebUI obfuscation (ref #44)
* docs: HISTORY Session 159 — WebUI obfuscation (ref #44)
Records the complete WebUI obfuscation work: new secubox-defaults
package, three /webui/* endpoints, nginx renderer script, haproxyctl
+ Python generator symmetry, dpkg trigger plumbing, integration test.
Includes notes on the brainstorming → spec → plan → subagent-driven
execution flow and the 6 fix iterations caught by reviewers.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: CyberMind-FR <gandalf@Gk2.net>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two bug fixes to the CMSD-1.0 license-header tool:
1. detect_existing() previously matched the SPDX token anywhere in the
first 10 lines, including inside docstrings and prose comments.
Tightened the matcher to require comment markers (#, //, *, <!--)
and whitespace before the SPDX token.
Regression tests:
- test_detect_existing_no_false_match_in_docstring
- test_detect_existing_no_false_match_inline_comment_prose
2. _read_enrollment() now returns ["**"] when the allowlist file is
absent, per spec §5.2 "missing file → repo-wide enforcement".
Previously it returned [] (nothing enforced), making Phase C closure
impossible without an additional file.
Empty allowlist file still returns [] (Phase A initial), so
test_main_empty_allowlist_passes_check is unaffected.
New tests:
- test_read_enrollment_missing_file_means_repo_wide
- test_main_check_missing_allowlist_enforces_repo_wide
Suite: 49 → 53 passing. --check still exits 0 repo-wide.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Discovered during Phase B pilot: running `--fix packages/secubox-hub`
yielded zero files because walk() computed `rel` relative to the walk
root (the subdir) while allowlist patterns are repo-relative.
Add optional `repo_root` parameter to walk(); when present, allowlist
matching uses paths relative to it instead of the walk root.
Backwards-compatible (defaults to None, preserving existing tests).
main() passes the discovered repo_root through.
Regression test added: test_walk_subdir_with_repo_root_arg.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Brainstormed design for adding the SPDX-CMSD-1.0 header to every
first-party source file (~2,170 across 6 languages), backed by a
reusable Python tool (scripts/license-headers.py), a CI check, and
a phased per-package rollout. Spec covers scope, header rendering
per language, placement rules, tool architecture, CI integration
with an enrollment allowlist, and verification steps.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>