Both found while setting up the on-node test, and both fail silently in the same direction — the gate reports success while protecting nothing, which is the exact failure the module was written to prevent. 1. Loopback-pinned ports were skipped entirely. `identity.rs` dropped any port whose manifest sets `bind: 127.0.0.1`, reasoning that a loopback publish is not externally reachable. But `listener.rs` requires loopback-pinning as the PRECONDITION for gating — while an app holds 0.0.0.0:<port> the kernel will not let the gate bind that port at all. So the two contradicted each other: pinning an app, the one action that lets the gate take over, was also what removed it from the gated set. Completing the entire migration would have gated nothing, and GateStatus would have reported zero unprotected ports while doing it. `bind` cannot carry this decision, because two unrelated intentions produce an identical loopback publish: Bitcoin's RPC 8332 is pinned so the LAN CANNOT reach it (fronting it would newly expose it on every host address, behind a login but exposed where it deliberately was not), whereas a migrated app is pinned precisely so the gate CAN. Inferring from `bind` breaks one or the other, so the intent is now declared: `PortAuth::Local` means the first case. The three ports that are host-local by intent (bitcoin-core/knots 8332, aiui 5180 — all already `bind: 127.0.0.1`) say so, and a loopback publish with `auth: session` stays gated. A test pins that property. 2. The port map was never refreshed. `AppGate::refresh()` existed, was documented as making catalog changes apply without a restart, and was called by nothing. The map was built once in `new()`, so an app installed while the daemon runs would never be gated — and would never appear in `unprotected` either, so the node would report itself fully enforced while serving a brand-new app to anyone who asked. The sweep now refreshes before classifying. Tests: 22/22 appgate, 73/73 archipelago-container. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
40 lines
917 B
YAML
40 lines
917 B
YAML
app:
|
|
id: aiui
|
|
name: AI Assistant
|
|
version: 0.1.0
|
|
description: Conversational AI interface for Archipelago. Quarantined — communicates only via context broker.
|
|
internal: true # System-managed, not shown in App Store
|
|
|
|
container:
|
|
image: localhost/archipelago-aiui:latest
|
|
pull_policy: always
|
|
|
|
resources:
|
|
cpu_limit: 1
|
|
memory_limit: 512Mi
|
|
disk_limit: 1Gi
|
|
|
|
security:
|
|
capabilities: []
|
|
readonly_root: true
|
|
no_new_privileges: true
|
|
user: 1000
|
|
seccomp_profile: default
|
|
network_policy: isolated # No outbound network — all data comes via context broker
|
|
apparmor_profile: aiui
|
|
|
|
ports:
|
|
- host: 5180
|
|
container: 80
|
|
protocol: tcp
|
|
bind: 127.0.0.1 # Only accessible via nginx proxy, not externally
|
|
auth: local
|
|
|
|
health_check:
|
|
type: http
|
|
endpoint: http://localhost:80
|
|
path: /
|
|
interval: 60s
|
|
timeout: 5s
|
|
retries: 3
|