NorthskySocial / NorthskySocial/invite-code-manager

Machine-facing routes must be added to the Cloudflare Access application

Open
#20 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
4
Forks
0
Avg merge
1d 17h
Merged PRs (30d)
5

Description

Root cause of a live incident on the vetting side: a blocked applicant kept a working invite code because every revocation since #17 shipped has failed.

What happened

POST /invite-codes/disable (added in #17) returns, to the vetting Worker:

401 {"status":"error","message":"Auth Error: Request did not arrive through Cloudflare Access"}

That is AccessClient failing closed, correctly: the request carried no Cf-Access-Jwt-Assertion. It carried none because the Cloudflare Access application in front of this service is scoped to the exact path /api/invite-codes/issue. Requests to any other path are not inside the app, so Cloudflare never exchanges the service token for a JWT and passes them straight to the origin.

Confirmed without credentials:

path response
/api/invite-codes/issue 403, Cloudflare Access page — behind Access
/api/invite-codes/disable 401 JSON from this service — not behind Access
/api/invite-codes/anything 404 from this service — not behind Access

/invite-codes/issue works. /invite-codes/disable never has. The fail-closed design held — nothing was exposed — but the endpoint was dead on arrival, and nothing at deploy time said so.

Fix (configuration)

Zero Trust → Access → Applications → this app: add /api/invite-codes/disable. Better: scope the app to /api/invite-codes/*, so the next machine-facing route is covered by default rather than by someone remembering.

Worth doing in this repo

  • Document it. The README's section on AccessClient should say plainly: a new route using it must also be added to the Access application, or it will 401 in production while passing every test here.
  • Make the tests say it. The existing AccessClient tests prove the extractor refuses a request with no JWT. That is the behaviour that hid this — a route outside the Access app produces exactly the response the tests call correct. A comment on refuses_every_request_when_access_is_not_configured noting that "no JWT" in production most likely means "path not in the Access app" would have shortened the diagnosis.
  • Consider a startup check. Not the path config itself (the service cannot see it), but the /health endpoint could report which routes require AccessClient, so a deploy checklist has something to compare against.

Cross-reference: NorthskySocial/invite-vetting#98 adds the banner that would have surfaced this on the vetting side within a day rather than a fortnight.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the README section on AccessClient and the existing test named refuses_every_request_when_access_is_not_configured. Verify the Cloudflare Access application covers /api/invite-codes/*, then document the route requirement and the production meaning of a missing JWT; completion should also include the relevant test context.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
api, backend, documentation, security, testing
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.