Skip to content

Sign attachment URLs instead of putting the file token in them (GRYT-1549) - #281

Merged
sivert-io merged 1 commit into
mainfrom
claude/GRYT-1549-signed-file-urls
Sep 29, 2026
Merged

sivert-io merged 1 commit into
mainfrom
claude/GRYT-1549-signed-file-urls

Conversation

@sivert-io

@sivert-io sivert-io commented Sep 28, 2026 •

Copy link
Copy Markdown
Member

GRYT-1549, the phone half. attachmentUrl put the file token in ?t= for an Image source, and those loads can't wait for the identity proof (#268). This is the phone's copy of Gryt-chat/client#724. The findings and options are in Gryt-chat/server#251.

What changes

  • src/connection/fileAccess.ts replaces fileToken.ts. It holds each server's signing key in memory and signs with @noble/hashes. attachmentUrl adds u, k, e and s in place of t, and no caller changed.
  • The key comes from server:joined, token:refreshed and the new file:key (a restored session), through applyFileAccess in tokens.ts.
  • guard.refuse() drops the key when the host counts as refused. markRefused now returns that. clearTokens drops it too.
  • Older servers. A server that sends only fileToken still works through ?t=. That token stays in SecureStore, but readTokens no longer puts it in memory. restoreFileToken does that right after guard.release(), so never before the proof. Once a server sends a key, its stored token is deleted.

What changes behaviour

  • Until the key arrives, an attachment URL carries nothing. On a restored session that's one round trip after the proof, before the channel list comes back. A cached screen drawn in that gap shows its pictures once it renders again.
  • URLs last 5 to 10 minutes and change every five minutes.

Checked

  • npx tsc --noEmit, yarn test (1279) and yarn test:comment-length pass.
  • fileAccess.test.ts: the server's vector, nothing before a key, 5 to 10 minutes, one file each, stable within a step, the server's clock, forgetting, and the old-server token (kept, restored after the proof, deleted once a key arrives, never taken over a key).
  • proofGate.test.ts: an impostor's refusal takes the key away. Mutation-checked: without forgetFileAccess in refuse, it fails.

Review-required: none. This is all in the mobile repo.

🤖 Generated with Claude Code

…1549)

The phone's copy of the desktop change. attachmentUrl signs each URL per
file with a key the server hands over after its identity proof, held in
memory. A refused server loses it, and an older server's stored token is
only used after that server has proved itself.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@sivert-io
sivert-io merged commit c4301f4 into main Sep 29, 2026
5 checks passed
@sivert-io
sivert-io deleted the claude/GRYT-1549-signed-file-urls branch September 29, 2026 00:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant