Skip to content

fix: v0.21 OpenID Provider follow-ups and the external delivery subject - #571

Merged
Bccorb merged 6 commits into
mainfrom
fix/v021-oidc-followups
Nov 4, 2026
Merged

Bccorb merged 6 commits into
mainfrom
fix/v021-oidc-followups

Conversation

@Bccorb

@Bccorb Bccorb commented Nov 3, 2026

Copy link
Copy Markdown
Contributor

Three v0.21 follow-ups. Each has a test commit that fails on main first, then the fix. The test commits were made with --no-verify, because the pre-commit hook runs coverage, which a deliberately failing test cannot pass; every fix commit went through the full hook.

Closes #542
Closes #543
Closes #556 (part 2; parts 1 and 3 merged in #567)

The release PR is untouched; this ships with v0.23.0.

#556 part 2: require the external delivery subject

src/lib/externalDelivery.ts requires sub to be exactly seamless-auth-external-delivery to unlock external delivery. The it.fails test marked TODO(#556) is now a plain it and fails on main. The conformance pin moves to seamless-cli v0.27.2 (28a363f), whose harness mints that subject.

All four adapters already send that subject on every external delivery request (audited on Node 662b6aa, Go cee15df, Python 3f8e828, Rust c096a97). Adopter-visible: a service token with any other subject no longer gets codes, links or notices back; the API sends them itself. Custom backends that mint their own delivery token must set that sub.

#542: expired_token for an expired device code

findOidcPayload reads a DeviceCode by id for 10 minutes past its expiry (DEVICE_CODE_EXPIRED_GRACE_MS), and the purge keeps those rows for the window. Every other model, the user-code and uid lookups, and consume still treat an expired row as gone, so an expired code can never be consumed. The window is a choice the issue left open.

No edge adapter change is needed: oidc-provider loads the code with ignoreExpiration and throws ExpiredToken on isExpired. The edge-side tests are being added in the provider repo.

#543: back-channel logout to the one application whose grant ends

destroyOidcPayload('Grant', id) now sends that grant's client a logout token for its session (new sendBackchannelLogoutForClient, claiming only that session:client row), unless another live grant still signs that client in on the session. The library's partial logout and its revoke() both destroy the grant this way, so "only sign out of this app" and library revocations are covered. The other application's row survives and the session stays live; a later full logout tells only the remaining app. Each app is told exactly once.

Gap noted: the API has no admin or user route that revokes one application for a user; one added later should go through the same path.

Checks

lint, typecheck, format, check:changeset-bump, generate:api clean. Unit: 2840 passed, coverage 99.04% statements. Postgres suite: 183 of 184 files pass; oidcApplications.spec.ts > application resources fails with "Invalid system_config" on a fresh database, and fails the same way on a clean main.

…al delivery

A valid internal service token with any subject used to unlock external
delivery. Only a token signed for seamless-auth-external-delivery does now.
The conformance harness pin moves to seamless-cli v0.27.2, which mints that
subject for delivery requests.

Refs #556
@Bccorb
Bccorb merged commit bcab4d1 into main Nov 4, 2026
9 checks passed
@Bccorb
Bccorb deleted the fix/v021-oidc-followups branch November 4, 2026 22:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant