Open-issue triage and roadmap (post-2.9.0)
Maintainers usually reply within 1 day
@heskew is already working on this.
Since Oct 2, 2026.
Assessment
This issue has not been assessed yet.
Description
Snapshot as of 2026-10-02: 2.9.0 is released (#274). It ships #262, #263, #267, #268, #269, #270 (closes #228) and #271 (closes #264).
How to use this
- Each item gives a one-line reason, its status, its size, its dependencies, and whether an outside contributor can do it alone. "Alone" means implementing it and opening a PR without Harper-internal access. A maintainer still has to merge and release it.
- Sizes: S is under a day, M is a few days, L is a week or more including review.
- Security changes here go through a design note and a cross-model plan review before any code. The "Design (cleared …)" sections in #212, #213 and #231 are the approved plans, so read them before writing code.
- Each item appears in one section only. Blocked items are listed under Blocked, with their tier noted.
- When an item moves, update its line here. Close this issue when Tier 1 and Blocked are both empty.
Tier 1: security/correctness, do first
- #275: Azure
?appid=form of the shared-alias keys URL isn't recognized.- Why: this is a 2.9.0 regression for unpinned configs, which now get a misleading "set
issuer" warning and a doomed discovery attempt. A pinned config binds to Microsoft's shared key pool withissuerValidated: true, whichsrc/lib/DESIGN.mdsays must never happen. - Status: the fix with tests is in draft PR #276. It needs the pre-push cross-model review, then review, merge and a 2.9.1 patch.
- Size: S. Deps: none. Outside contributor: yes.
- Why: this is a 2.9.0 regression for unpinned configs, which now get a misleading "set
- #231 §3: bind adopted accounts to a stable
(iss, sub)in a plugin-ownedoauth_identitiestable, not to a verified email (OIDC Core §5.7).- Why: if an IdP reassigns an email, the new holder silently inherits the existing account's role.
- Status: designed and cleared, ready to implement. Ship the default policy, which requires pre-registration, first.
- Size: L. Deps: none for the default policy. The opt-in
allowFirstBindWithoutPreRegistrationneeds an atomic insert-if-absent write, which HarperFast/harper#2990 does not provide (itsifVersionis fenced torequest.session.update). Defer that opt-in, or find another primitive for it. - Outside contributor: yes.
- #273: a roleless trusted session can inherit a role when a matching
hdb_useris created later.- Why: sessions never expire by default, so someone who controls an email can hold a session until an admin happens to create that username.
- Status: needs a design note. First check whether #231 §3's binding gate covers it, or whether core's session-to-role resolution bypasses it.
- Size: M. Deps: after #231 §3; possibly a Harper core change (file a linked harper issue if so). Outside contributor: the design and plugin side, yes; a core change, no.
- #277: session docs are wrong about expiry.
- Why: line 141 of
docs/token-refresh-and-sessions.mdsays Harper sessions "default 24 hours" and that an expired session "is deleted fromhdb_session". In fact there is no default expiry, and the plugin clears session fields rather than deleting the row. That leads operators to underestimate #231 §1 and #273. - Status: filed; needs the docs fix. Size: S. Deps: none. Outside contributor: yes.
- Why: line 141 of
Tier 2: UX/devexp
- #272: Azure multi-tenant, where only an allowlist of tenants can adopt accounts while anyone can still sign in.
- Why: today operators must choose between open sign-in and account adoption.
- Status: needs a design note and plan review. The tenant must be proven by the signing key's
issuerin Microsoft's JWKS, whichjwks-rsadoesn't expose. A bounded fetch likesrc/lib/mcp/jwksFetcher.tsis the likely route. - Size: L. Deps: rebase on #275. Outside contributor: yes.
- Two small sub-items can ship on their own (S each, outside contributor yes):
- warn when
azureAuthorizeIssuerHostreturns null for an Azure-looking host; - optionally, redirect a pinned v1 alias to the tenant's own keys instead of throwing.
- warn when
- PR #234: optionally serve the OAuth endpoints as HTTP middleware, so a catch-all handler such as Next.js with
files: '*'doesn't hide/oauth/*.- Why: in those apps login is unreachable.
- Status: stalled on requested changes since 2026-09-26. Registering with
urlPathroutes every/oauth/*request only through the new sub-chain. With the option off, every/oauth/*request returns 404 (8 integration failures); with it on, POST endpoints return 404. - Fix from the review: register without
urlPath, check the mount prefix in the handler, and callnext(request)otherwise. Add an integration fixture covering a GET login and one POST. - Size: S–M. Deps: none. Outside contributor: yes, as the author's update or a takeover.
- No issue tracks the underlying problem; file one so it survives the PR.
Tier 3: maintenance/perf
- #258: remove the transition-era
typ: JWTacceptance fromtypAccepted()insrc/lib/mcp/tokenIssuer.tsand updatedocs/mcp-oauth-conformance.md.- Why: RFC 9068 §4 is strict about
typ, and the transition branch has no expiry in code. - Status: time-gated. 2.9.0 is the first release that mints
at+jwt. Removal is safe only when no node older than 2.9.0 can still be minting tokens. - Target a later minor (at least 2.11) or the next major. Its CHANGELOG entry must warn that a rolling upgrade straight from below 2.9 gives up to one
mcp.accessTokenTtl(default 3600 s) of 401s. - Size: S. Deps: time only. Outside contributor: yes.
- Why: RFC 9068 §4 is strict about
Blocked (with the exact blocker)
- #212 (Tier 1): a concurrent token refresh can resurrect a logged-out session.
- Blocker: HarperFast/harper#2990 (open, closes HarperFast/harper#2983) must merge and ship in a Harper release. It adds
request.session.update(data, { ifVersion })andrequest.session.version. The plugin then raises itsharperpeer minimum, because an older core silently ignores the second argument. - Unblocked now: design the plugin-side cross-node defense.
ifVersionis atomic on the local node only, andhdb_sessionreplicates last-write-wins. - Size: L in total (the plugin change is M once core ships). Outside contributor: the plugin side, yes; the core merge and release, no.
- Blocker: HarperFast/harper#2990 (open, closes HarperFast/harper#2983) must merge and ship in a Harper release. It adds
- #213 (Tier 1): a request that invalidates an OAuth session still runs once as the old user.
- Blocker: HarperFast/harper#2984,
request.invalidateSessionAuthentication(). It is open and has no PR. - Plugin side afterwards: call it at the five continuation points, add a reachable capability check, and raise the peer minimum. The persistence-failure parts already shipped in #268.
- Size: core M, plugin S–M. Outside contributor: can write the core PR in the public harper repo; merging needs core maintainers.
- Blocker: HarperFast/harper#2984,
- #231 §1 (Tier 1): durably neutralize sessions from before the adoption gate, including on the operations API.
- Blocker: a Harper core product and operations decision between two candidates:
- Candidate A: a new
hdb_session_v2table and a cookie rename, for a rolling path. - Candidate B: a quiesced, cluster-wide purge of
system.hdb_session.
- Candidate A: a new
- Unblocked prep: test whether an old Harper node's operations API can write the new system table generically. The result decides whether Candidate A is viable.
- Interim mitigation: clear
system.hdb_session. - Size: L (core). Outside contributor: the prep, yes; the decision, no.
- Blocker: a Harper core product and operations decision between two candidates:
- #244 (Tier 2), remaining part: make interactive CIMD
private_key_jwton by default.- Blocker (external): ChatGPT still signs its client assertions with the token-endpoint URL as
aud, which RFC 7523bis forbids. The publication of RFC 7523bis is the most likely trigger for a change. - Re-run the live capture before each release. On deployments that opted in, watch the logged
aud form. - Size: S once unblocked. Outside contributor: yes, with their own ChatGPT account and a reachable test authorization server.
- Blocker (external): ChatGPT still signs its client assertions with the token-endpoint URL as
- #156 (Tier 3): MCP SEP-2350 scope step-up, plus the 403
insufficient_scopechallenge deferred from #202.- Blocker: per-tool scopes, which have no tracking issue or design (#86 is closed). Today's token scoping is role-level.
- Size: L. Outside contributor: not until a scope model is decided.
Likely fixed / close candidates (with evidence)
- #244: the reported failure, ChatGPT refused with
invalid_client, was fixed by #245 and hardened by #253, both shipped in 2.8.0 (see its CHANGELOG). The body's own status block says "Fixed". It stays open only for the default-flip gate.- Close it and open a narrow "default-on interactive
private_key_jwt" issue that carries the gate checklist, or retitle this one.
- Close it and open a narrow "default-on interactive
- #231: most sections have shipped.
- §2 shipped in #232 (2.7.0).
- §4 and §5a–d shipped in #263 (2.9.0). #271 then relaxed §4's startup hard-fail to background OIDC discovery.
- §6 is done: #230 was closed via #239.
- Split §1 and §3 into their own issues, copying the design sections verbatim, then close this umbrella.
- #156: item 2 shipped in #192. The final-spec re-verify is done: #202 is closed and the conformance matrix is in
docs/mcp-oauth-conformance.md.- What remains depends on unscheduled work. Retitle it as a per-tool-scopes umbrella, or close it as not planned until that is scheduled.
- No duplicates found.
- #273 was split out of #231 §3 on purpose.
- #212 (persisted-row race) and #213 (in-request identity) complement each other.
- #275 (
?appid=) is distinct from the bare v1-alias case recorded as fixed in #272.
Suggested order of work
- Finish #276 (#275): pre-push review, merge, and release 2.9.1.
- Fix the session-expiry docs (#277).
- Split #231 into separate §1 and §3 issues and close the umbrella. Close or retitle #244 and #156.
- Implement #231 §3 with the default pre-registration policy and without the first-bind opt-in.
- Write the #273 design note, checking it against the #231 §3 gate.
- Design #212's cross-node defense now. Ship the plugin change once HarperFast/harper#2990 is in a Harper release.
- Get HarperFast/harper#2984 implemented (a core PR is welcome), then do #213's plugin side.
- Unstick PR #234, through the author's update or a takeover, and file an issue for the catch-all problem.
- Ship the two small #272 sub-items, then write #272's design note.
- #231 §1, once Harper core picks Candidate A or B. Run the old-node table-write test beforehand to inform that choice.
- #258, once the time gate passes.
- #244's default flip, once ChatGPT signs with the issuer as
aud. - #156, once per-tool scopes are scheduled.
- Dominant language
- JavaScript
- Stars
- 1
- Forks
- 3
- Avg merge
- 7h 4m
- Merged PRs (30d)
- 24
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from HarperFast/oauth
-
Difficulty 4/5 3-5 days Newbie friendliness 53/100
HarperFast/oauth#284 ·
Maintainers usually reply within 1 day
-
bug
Difficulty 3/5 1-2 days Newbie friendliness 69/100
HarperFast/oauth#283 ·
Maintainers usually reply within 1 day
-
Difficulty 5/5 Over a week Newbie friendliness 18/100
HarperFast/oauth#280 ·
Maintainers usually reply within 1 day
-
Session docs overstate expiry: no default lifetime, and invalidation clears fields rather than deleting the rowPossibly taken @heskew claimed this 23 days ago. Open
HarperFast/oauth#277 · 1 assignee ·
Maintainers usually reply within 1 day
-
Azure ?appid= form of the shared-alias keys URL isn't recognizedPossibly taken @heskew claimed this 23 days ago. Open
HarperFast/oauth#275 · 1 assignee ·
Maintainers usually reply within 1 day
All issues in HarperFast/oauth
Similar issues
-
Clinic sharing: fast sync refusal message suggests Delete Data, which only developer builds haveOpenbug
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
avniproject/avni-client#2228 ·
-
bug confirmed issue
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
open-webui/open-webui#33196 · 2 comments ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
fable-compiler/Fable#5157 ·
Maintainers usually reply within 1 day
-
New tool: PaperBananaPossibly taken @github-actions claimed this today. Opensubmission triage
Difficulty 1/5 Under an hour Newbie friendliness 75/100
kausalflow/tools#243 · 1 comment ·
Maintainers usually reply within 1 day
-
area: apple-music area: build-release bug effort: small priority: high
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
ChristianTabor/Argon#32 ·
Maintainers usually reply within 1 day