Commit Graph
4 Commits
Author SHA1 Message Date
archipelagoandClaude Fable 5 58cdea5e79 feat(appgate): apps with their own login can skip the node login
Demo images / Build & push demo images (push) Successful in 3m33s
Some apps carry a complete account system and are broken by an upstream
challenge: git clients speak basic-auth (not browser cookies), and a
BTCPay checkout link handed to a customer must open for that customer.
Both were behind the gate's login page — the "non-browser clients need an
access token" gap disclosed in five consecutive releases.

- New manifest port policy `auth: open`: the daemon still fronts the port
  exactly like `gated` (loopback pin, external binds, frame-header fixes,
  app-down retry page, Tor upstream) but serves it without the login
  challenge. Requires auth_rationale, same burden of proof as `none`.
  Gitea 3001 and BTCPay 23000 declare it.
- Runtime operator override per app (security.set-app-gate → app-configs/
  <id>.json "gateEnabled"), surfaced as Settings → app → Access control.
  Wins over the manifest in both directions and applies on the next
  request — no restart, and it works today on catalog-covered apps whose
  signed manifest still says `gated`.
- The gate resolves policy per-request from the live port map, so a
  toggle takes effect without waiting for the 60s rebind sweep. "Off"
  never releases the port: gated apps are loopback-pinned, so releasing
  would strand them, not open them.
- security.app-gate-status now reports gate_enabled + any override.
- New guard test pins the `auth: open` set (both entries reviewed); the
  `auth: none` count moves 25 → 26, absorbing pre-existing drift from the
  phoenixd onboarding (loopback JSON API with its own generated password).
- Docs: the manifest spec's ports row documented only host/container/
  protocol — bind, auth, auth_rationale and session_passthrough were
  undocumented. Added a full "Ports & the app gate" section plus a
  developer-guide entry telling app authors to enforce their own auth
  regardless, since the operator can flip the gate either way.

Verified live on archi-dev-box from an external address: gated → 401 gate
page; override off → Gitea 200 own page, BTCPay 302 to its own login,
git-over-HTTP info/refs 200; override on → 401 again; clear → default.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-16 11:40:07 -04:00
archipelagoandClaude Fable 5 56d6396142 feat(appgate): gate login gets the real dashboard badge + glass-button states
Demo images / Build & push demo images (push) Successful in 3m0s
- The badge is now the dashboard login's AnimatedLogo, square for square:
  inline SVG (20 white rects, 100ms stagger, 3s loop) inside the same
  gradient ring. The old <img> of favico-black-v2.svg baked a second ring
  into the ring and couldn't animate; the asset leaves the gate allowlist
  since nothing references it now.
- The submit button is .glass-button longhand: hover lift + lightening +
  rim glow, active press, disabled dim — the flat darken-only hover read
  as broken next to /login.
- Loading state: submitting flips the button to spinner + 'Signing in…'/
  'Verifying…' and disables it, via a single inline script admitted by
  CSP sha256 hash (not unsafe-inline; injected markup stays inert, and
  the page still works as a plain POST without JS).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-15 08:24:27 -04:00
archipelagoandClaude Fable 5 a80712963c feat(appgate): proxied apps become embeddable — gate neutralizes frame blocking
Apps that ship X-Frame-Options (Alby Hub: DENY) or a CSP frame-ancestors
directive rendered as a dead grey pane in the dashboard's embedded app
session; the historical fix was a bespoke per-app nginx strip proxy
(gitea). The gate now removes X-Frame-Options and strips ONLY the
frame-ancestors directive from proxied responses — the rest of the app's
CSP passes through untouched. The clickjacking threat those headers
address is handled the same way the gate's own pages handle it: every
proxied request is authenticated first, and the gate already declares
permissive frame-ancestors on its own responses. Unit-tested; verified
live on archi-dev-box (Alby Hub embeds, CSP intact).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-12 13:05:25 -04:00
Archipelago b67e1527a2 Archipelago — open-source initial import 2026-08-12 10:55:50 +00:00