entra-emulator v0.9.0
WS-Federation passive sign-out, Go 1.26.6, and the last two protocol rows
that had no witness outside our own tests.
WS-Federation sign-out
GET|POST /{tid}/wsfed now dispatches on wa before minting. wa=wsignout1.0
never posts a wresult; it ends the shared session and 302s to a separately
registered wsfed-reply, so a sign-out cannot be used to bounce a browser
somewhere the tenant never trusted.
Witnessed by an unmodified Microsoft.AspNetCore.Authentication.WsFederation
completing SignOut (python3 e2e/run.py wsfed). Multi-RP
wsignoutcleanup1.0 remains out of scope, and the parity row says so.
Go 1.26.6
govulncheck reported standard-library vulnerabilities across every Go repo in
the family — 6 to 8 each — all of them resolved by moving off Go 1.25. The go
directive and toolchain line both move, and CI now reads the version from
go.mod rather than pinning it in twenty-one places.
Two scanners join CI at the same time: secret scanning over history, and
govulncheck on every push.
Two rows that only our own tests had checked
JAR by reference (e2e/jar). The property under test is not that the
feature works but that the SSRF guard holds: an authorize endpoint fetching
a caller-supplied URL is a request-forgery primitive unless it reaches only
origins the tenant already trusted. The request object is a real RS256 JWT.
Concurrency contracts (e2e/concurrency). The parity row claims real
atomic SQL, not best-effort, which is a claim about presenting the same
credential twice. Sequential replay cannot test it — a server that marks a
code spent non-atomically passes replay and fails under a race — so every check
uses each credential twice, concurrently.
Hardening you will not see at runtime
- CVE-2026-17106 —
moby/go-archivebumped past the tar-escape advisory.
Transitive through testcontainers, which still pins the vulnerable version at
its own latest, so upstream would not have fixed it. - Every CI job now has a timeout. Thirteen did not, and a hung job held a
runner until the platform's own limit. - The
go mod downloadpre-warm is gone from the e2e runner. On a stale module
it rewrotego.modin place and exited 0, so a suite could report green
against a file the repo never committed.go testalone fetches what it needs
and stops with the message you actually want. - CI now fails when any module's
go.modis untidy. The release pipeline runs
go mod tidyas a hook, so an untidy module would otherwise be rewritten
mid-release and the binaries built from state nobody committed — silently,
because a successful tidy prints nothing. - Documentation links and sidebar reachability are gated.
Upgrading
Nothing to migrate. No endpoint changed shape, and the tenant and seeded object
ids are unchanged from v0.8.1.
If you build from source, the go directive is now 1.26.6.