You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Every portal-side test in this tree runs against the old plugin generation.
Nothing exercises the 0.6.0 half, because no published image carries it yet.
Verified on 2026-09-07, on both candidate tags:
yadd/lemonldap-ng-portal:latest (2026-09-01)
…:2.23.3-3 (2026-08-30)
LLNG core
2.23.3
2.23.3
PamAccess.pm
2.22.0
2.22.0
/pam/whoami route
absent
absent
/pam/bastion-token route
present
present
_checkCaller (signature check)
absent
absent
pamAccessRequireFingerprint
absent
absent
pamAccessBastionVoucherUnboundTtl
absent
absent
docker run --rm --entrypoint sh yadd/lemonldap-ng-portal:latest -c \
'grep -c "whoami\|_checkCaller" /usr/share/perl5/Lemonldap/NG/Portal/Plugins/PamAccess.pm'
So :latest is not ahead of 2.23.3-3 in any respect that matters here.
(The tag is 2.23.3-3; v2.23.3-3 does not exist on the registry.)
What that leaves untested
Each of these is implemented on our side, documented in UPGRADE-NOTES.md, and
exercised by nothing:
Exact PAM scope matching (UPGRADE-NOTES.md step B4) — that an RP
granted pam-prod loses /pam/*.
That the fallback is not taken when /pam/whoami exists. Today it is
always taken, so a regression that made it unconditional would pass.
Why this is a ticket and not a TODO
docker-demo-cert/sso/Dockerfile is now deliberately pinned to 2.23.3-3-non-root, with the reason in a comment. That pin is correct and
should stay: it is the only thing keeping the legacy /pam/bastion-token
fallback covered once a newer image exists.
But the pin also means that when the 0.6.0 image is published, nothing will
start failing and nothing will start passing — coverage of the new generation
simply will not appear. There is no signal. Hence this.
What to do when an image lands
Point one demo at it — a new docker-demo-next/sso, or move docker-demo-maxsec — and leave docker-demo-cert pinned where it is.
Add the portal-side assertions the new generation makes possible, at least
items 1, 2 and 3 above.
Extend tests/test_ob_upgrade.sh, which today upgrades a host from v0.6.2, with the portal-upgrade direction: old portal → new portal with
0.7.0 hosts on both sides, which is the sequence UPGRADE-NOTES.md step B1
tells operators to follow.
Acceptance
One demo runs a portal whose PamAccess.pm has a /pam/whoami route and a _checkCaller, asserted rather than assumed.
docker-demo-cert still runs a portal without them, and tests/test_ob_upgrade.sh's pin assertion still passes.
ob-bastion-id is shown taking the /pam/whoami path against the new portal
and the fallback against the old one — the same binary, both branches.
pamAccessRequestSigningMode = required is exercised end to end.
Detecting that it has landed
Worth a scheduled CI job rather than someone remembering: fail (or open a
notice) when :latest gains a whoami route while every demo is still pinned
below it. The one-liner above is the whole check.
Found while adding ob-post-upgrade and the upgrade suite (#261), where the
pin was introduced.
The gap
Every portal-side test in this tree runs against the old plugin generation.
Nothing exercises the 0.6.0 half, because no published image carries it yet.
Verified on 2026-09-07, on both candidate tags:
yadd/lemonldap-ng-portal:latest(2026-09-01)…:2.23.3-3(2026-08-30)PamAccess.pm/pam/whoamiroute/pam/bastion-tokenroute_checkCaller(signature check)pamAccessRequireFingerprintpamAccessBastionVoucherUnboundTtldocker run --rm --entrypoint sh yadd/lemonldap-ng-portal:latest -c \ 'grep -c "whoami\|_checkCaller" /usr/share/perl5/Lemonldap/NG/Portal/Plugins/PamAccess.pm'So
:latestis not ahead of2.23.3-3in any respect that matters here.(The tag is
2.23.3-3;v2.23.3-3does not exist on the registry.)What that leaves untested
Each of these is implemented on our side, documented in
UPGRADE-NOTES.md, andexercised by nothing:
POST /pam/whoami— the primary path ofob-bastion-id(ob-bastion-id breaks when /pam/bastion-token is removed, and deploy-shell.sh silently writes a wrong bastion id when it does #246). Onlyits legacy fallback is covered today, and only by accident of the portal
being old.
tests/test_ob_bastion_id.shcovers the shapes against a mock,not against a real portal.
in CI checks a signature, so
pamAccessRequestSigningMode = optionaland= requiredhave never been exercised end to end — including the failuremode
UPGRADE-NOTES.mdstep B3 is written to prevent.pamAccessRequireFingerprintand the 15-minutepamAccessBastionVoucherUnboundTtl(SSH fingerprint binding is dropped with only a DEBUG log when the spool is missing #192, Fingerprint spool: move the trust root offnobodyto a socket-activated root daemon #249). The host-side half istested; the portal-side refusal and the short-TTL hop failure are not.
sshCaAdminRulefail-closed (Ship and document locationRules for /device and /ssh/* in the production setups #195).tests/test_ob_llng_location_rules.shcompiles the rules; nothing checks that the routes actually answer 403 when
the rule is unset.
UPGRADE-NOTES.mdstep B4) — that an RPgranted
pam-prodloses/pam/*./pam/whoamiexists. Today it isalways taken, so a regression that made it unconditional would pass.
Why this is a ticket and not a TODO
docker-demo-cert/sso/Dockerfileis now deliberately pinned to2.23.3-3-non-root, with the reason in a comment. That pin is correct andshould stay: it is the only thing keeping the legacy
/pam/bastion-tokenfallback covered once a newer image exists.
But the pin also means that when the 0.6.0 image is published, nothing will
start failing and nothing will start passing — coverage of the new generation
simply will not appear. There is no signal. Hence this.
What to do when an image lands
docker-demo-next/sso, or movedocker-demo-maxsec— and leavedocker-demo-certpinned where it is.items 1, 2 and 3 above.
tests/test_ob_upgrade.sh, which today upgrades a host fromv0.6.2, with the portal-upgrade direction: old portal → new portal with0.7.0 hosts on both sides, which is the sequence
UPGRADE-NOTES.mdstep B1tells operators to follow.
Acceptance
PamAccess.pmhas a/pam/whoamiroute and a_checkCaller, asserted rather than assumed.docker-demo-certstill runs a portal without them, andtests/test_ob_upgrade.sh's pin assertion still passes.ob-bastion-idis shown taking the/pam/whoamipath against the new portaland the fallback against the old one — the same binary, both branches.
pamAccessRequestSigningMode = requiredis exercised end to end.Detecting that it has landed
Worth a scheduled CI job rather than someone remembering: fail (or open a
notice) when
:latestgains awhoamiroute while every demo is still pinnedbelow it. The one-liner above is the whole check.
Found while adding
ob-post-upgradeand the upgrade suite (#261), where thepin was introduced.
https://claude.ai/code/session_011q88Fs4nFuUs7JMvmgbBTN