Repository navigation
Description
Background
Revocation sets revokedAt, and lookupApiKey refuses the key on the next
request. A long-lived connection never makes another request — a websocket
subscription authenticated once (after L238) keeps streaming, and so does a
GraphQL subscription.
So revoking a leaked key stops new requests and does nothing about the stream
already running, which is the one that matters: it is continuous, it is the
most valuable data, and it will keep flowing until the client chooses to
disconnect.
What to build
- On revocation, close live connections belonging to that key.
- Connections must be findable by key — which is what L238's key context on the
connection is for; build on it rather than inventing a second registry. - Close with a code and reason the client can distinguish from a restart, so
reconnect logic does not simply retry forever. - Multiple instances: a key revoked on one instance must drop connections held
by another. Redis pub/sub is already in the stack for exactly this shape.
Acceptance criteria
- Revoking a key closes its live connections
- The close carries a distinguishable code and reason
- Revocation propagates across instances
- Other keys' connections are unaffected
- A test proves a subscription stops after revocation
Drips Wave · Complexity: Intermediate · 150 points
Repo: Divinity-Labs/Lens. Auth is src/api/auth.ts, key minting
src/api/admin.ts, usage reporting src/api/usage.ts, metering
src/x402/metering.ts, the ApiKey model in prisma/schema.prisma.
Run the tests: npm test. The tests are vitest, not jest. A single file
is npx vitest run src/__tests__/auth.test.ts.
Load test (prices) is already failing on main. Not your PR.
Do not weaken what is already right. Three things are correct today and
should survive every change here:
generateApiKey()islens_plusrandomBytes(24)— 192 bits. Do not
shorten it, and do not make it guessable or sequential.hashApiKey()is an unsalted SHA-256. That is correct for a
high-entropy random key: it must stay fast and deterministic so a lookup is
one indexed query. Do not "improve" it into bcrypt or argon2 — those are for
low-entropy human passwords, and here they would only make every request slow.- Only the hash is ever stored. The plaintext is returned once, at creation,
and never again.
Admin routes carry config: { public: true }. That does not mean public —
it means "skip the API-key hook", because they enforce ADMIN_TOKEN instead.
Removing that flag locks the admin surface behind the keys it exists to mint.
Never elide an address, a key or a token in code, comments, tests or
documentation. Write it in full or not at all — and never write a real key
anywhere.
Required: Before submitting, join the contributor Telegram so your work can be tracked and counted toward the Stellar Wave: https://t.me/+fxHXq8f1SwlkZDBk
Activity
Miracle656 commentedon Oct 18, 2026
⏸️ Not funded in the current Wave — please do not start yet
This issue is real and the work is wanted, but it is not currently part of the Drips Wave programme, so a PR against it right now would earn no points. I would rather say that plainly up front than have anyone find out after writing the code.
The repo's Wave budget for this round is exhausted — 25,000 points across 271 labelled issues — and this batch was published just after it ran out. That is my error in pacing, not a reflection on the issue.
What happens next: it will be added to the Wave when the next round opens, at the points value in its label. The description, the acceptance criteria and the code references all stay as they are, so nothing here is wasted.
If you want something to work on today, pick an issue that is already in the Wave — the
Stellar Wavelabel plus an unassigned state is the signal, and Drips will let you apply for it. If Drips will not let you apply for an issue, that is the budget, not you.If you have already started on this one, say so here and I will make sure you are first in line for it when the next round opens.
feat(ws): close live streaming connections on key revocation with red…
Joyful12-tech commentedon Oct 19, 2026
@Joyful12-tech has applied to work on this issue as part of the Stellar Wave Program's 10th wave.
ℹ️ Repo Maintainers: To accept this application, review their application or assign @Joyful12-tech to this issue.
onyekachi66 commentedon Oct 19, 2026
@onyekachi66 has applied to work on this issue as part of the Stellar Wave Program's 10th wave.
ℹ️ Repo Maintainers: To accept this application, review their application or assign @onyekachi66 to this issue.
Riri-dev1 commentedon Oct 19, 2026
@Riri-dev1 has applied to work on this issue as part of the Stellar Wave Program's 10th wave.
ℹ️ Repo Maintainers: To accept this application, review their application or assign @Riri-dev1 to this issue.
drips-wave commentedon Oct 20, 2026
Congratulations, @Riri-dev1! 🎉 Your application was accepted by the repo's maintainers, and the issue is due on October 22, 2026.
🧑💻 @Riri-dev1: Please resolve the issue such that the repo's maintainers have enough time to review your contribution before the due date. You'll earn Points for completing the issue on-time, which will make you eligible for a share of the Stellar Wave Program's reward pool.
Warning
When opening a PR, please link it to this issue to ensure it gets tracked accurately. Points are awarded when this issue is marked as completed by the maintainer.
🤠 Repo maintainers: Please keep an eye on the contributor's progress and review their work before the due date. You can manage this issue, including adjusting its complexity and points, here.
🌊 Happy Wave 🌊
fix: close live connections on key revocation with cross-instance pro…
feat(ws): close live streaming connections on key revocation with red…
fix: close live connections on key revocation with cross-instance pro…