Commit graph

9 commits

Author SHA1 Message Date
Lars Rossen
828b2c3f1b podman: document internet exposure and what identity does not gate
lab1 is now published with proxyAllowedZones: [internet]. Enabling OAuth does
not disable Portainer's internal login — POST /api/auth stays live and still
accepts the break-glass admin, confirmed against the public endpoint (422
Invalid credentials, not a refused path). So publishing the console publishes a
password path too; the remedy, if that is unacceptable, is to promote an OIDC
user to administrator and delete the local admin, at the cost of break-glass.

Also records that the operator's admin-VPN overlay (admin, 10.255.1.0/24) is
not in the internal default allow-set, which is why a remote admin on the
WireGuard tunnel also gets 403.
2026-08-25 09:56:01 +02:00
Lars Rossen
04b4437c95 Merge portainer into podman: engine plus GUI in one module
Podman is the container foundation, Portainer CE is the web interface onto it,
running as a container on the very engine it manages. This is what the separate
portainer module already did, so it is retired rather than duplicated.

Two sockets on purpose: the rootful one is the Docker-compatible API Portainer
drives (it does not support rootless), the rootless user socket is for people
who ssh in and run containers by hand — which was the original podman module's
point and is worth keeping.

An explicit proxyDomain lets the module publish at the environment's own domain
instead of <module>.<environment-domain>, making it that environment's gateway.

DESIGN.md keeps the Cockpit identity analysis: it is the reason for the change,
and anyone proposing 'just put Cockpit behind forward-auth' should read it.
2026-08-25 09:30:11 +02:00
Lars Rossen
ffc9e12526 portainer: reopen Portainer's admin-init window when it has closed
Portainer stops accepting POST /api/users/admin/init a few minutes after start
and answers 303 with Redirect-Reason: AdminInitTimeout. Any transient failure
during that window therefore made the module permanently un-bootstrappable.
update.sh now restarts the container to reset the timer, waits for the API and
retries once, re-reading the setup token because a fresh one is minted at every
start.

Also splits the OIDC precondition: the single condition reported the secrets env
as missing whenever the admin session was absent, which is what sent the first
debugging pass down the wrong path.
2026-08-24 20:59:55 +02:00
Lars Rossen
1c48eb4634 portainer: gate the admin bootstrap on being able to log in
The previous guard was 'does the password file exist'. The first lab1 install
wrote the password, then failed init on the missing setup token — leaving a file
that made every later run skip the bootstrap and then fail to authenticate, so
OIDC never got configured. Ask Portainer instead: try /api/auth, and bootstrap
only when that yields no token. The JWT is then reused for the settings PUT
rather than logging in twice.
2026-08-24 20:58:22 +02:00
Lars Rossen
77f361120a portainer: fix admin bootstrap and the published-domain derivation
First live install on lab1 surfaced two bugs.

Portainer 2.39.6 refuses POST /api/users/admin/init with 403 unless the
X-Setup-Token header carries the token it prints once at startup; update.sh now
reads it out of podman logs, matching the 64-hex value because the log line puts
ANSI colour codes between the key and the token.

The domain fallback asked get_variant_config for the DEFAULT environment, so a
module installed into lab1 advertised portainer-lab1.makerfloss.eu while Caddy
actually publishes portainer-lab1.lab1.makerfloss.eu — which would also have put
a mismatched RedirectURI into Portainer's OAuth settings. It now derives from the
module's own environment, as identity/install-service.sh does.

Confirmed on the live system: identity:identity works — the OIDC application is
created and /etc/secrets/portainer.env is written before install.sh runs.
2026-08-24 20:55:26 +02:00
Lars Rossen
bca395d7f9 Add portainer and komodo as parallel container-management modules
portainer: Portainer CE on rootful podman (Portainer drives the
Docker-compatible API, and rootless is not supported upstream), published via
network:proxy with proxyAllowedZones left unset so members reach it from a
client zone but the internet does not. Login is OIDC: identity:identity writes
the client credentials, update.sh resolves the endpoints from the discovery
document and PUTs them into /api/settings. A break-glass local admin stays for
when Authentik is down. Multi-host is the agent on :9001 per host.

komodo: scaffold only — komodo.json plus a README that specifies what
install.sh and update.sh must do. GPL, no edition split, but it needs a
database and models builds and stacks, so it is the alternative rather than
the teaching example.

Neither has been run on a live TAPPaaS yet; both are catalogued as incomplete.
2026-08-23 09:45:01 +02:00
Lars Rossen
1ca204c405 podman: write up how (and whether) it can integrate with identity
Cockpit is not an OIDC client and cannot be configured into one, so
identity:identity is the wrong dependency. Records the three real options —
accessControl URL gating, an Authentik LDAP outpost with SSSD, and a custom
Cockpit auth command — with the recommendation to take the first, raise the
second upstream, and leave the third alone.

Also flags that accessControl's install-service requires proxyDomain in the
resolved config and, unlike identity's, does not derive it — to verify on a
live install before relying on it.
2026-08-22 20:40:25 +02:00
Lars Rossen
8166ebda40 README: correct the repository add invocation
repository.sh takes the URL positionally (name is derived from it), clones over
https, and defaults to the stable branch — which this repo does not have.
2026-08-22 18:57:01 +02:00
Lars Rossen
1dba304085 Seed the MakerFLOSS devops repo with the podman module
README, a module-catalog.json validated against TAPPaaS's
module-catalog-fields.json, and the podman module copied verbatim from
Community/src/larsrossen/containers/podman into a flat src/containers/ layout
(the catalog carries the explicit moduleJson path, so layout is free).
2026-08-22 18:46:24 +02:00