Skip to content

feat: add com.atproto.server.getServiceAuth endpoint#26

Merged
ascorbic merged 10 commits into
mainfrom
claude/fix-video-upload-auth-dDcaZ
Dec 29, 2025
Merged

feat: add com.atproto.server.getServiceAuth endpoint#26
ascorbic merged 10 commits into
mainfrom
claude/fix-video-upload-auth-dDcaZ

Conversation

@ascorbic
Copy link
Copy Markdown
Owner

This endpoint is required for video uploads. Clients call it to get
a service JWT to authenticate with external services like the video
service (did:web:video.bsky.app).

The endpoint:

  • Requires authentication
  • Takes 'aud' (required) and 'lxm' (optional) query params
  • Returns a signed service JWT with the requested audience and lxm claims

Adds 4 new tests for the endpoint.

This endpoint is required for video uploads. Clients call it to get
a service JWT to authenticate with external services like the video
service (did:web:video.bsky.app).

The endpoint:
- Requires authentication
- Takes 'aud' (required) and 'lxm' (optional) query params
- Returns a signed service JWT with the requested audience and lxm claims

Adds 4 new tests for the endpoint.
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented Dec 28, 2025

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
atproto-pds 832559f Dec 29 2025, 10:03 AM

The video service (video.bsky.app) calls uploadBlob on the PDS using
a service JWT issued by getServiceAuth. The auth middleware now accepts
these ES256K-signed service JWTs in addition to HS256 session JWTs.

Auth flow:
1. Client gets service JWT via getServiceAuth(aud=PDS, lxm=uploadBlob)
2. Client sends video to video.bsky.app with this token
3. Video service calls uploadBlob on PDS using the same token
4. PDS verifies the service JWT signature and allows the upload

Adds verifyServiceJwt() function and integration test for the flow.
The actual fix was wrapping Buffer with Uint8Array, not removing caching.
Cloudflare Workers' Buffer polyfill doesn't work correctly with
@atproto/crypto's verifySignature() - it needs true Uint8Array instances.

Restores caching for better performance while keeping the Uint8Array fix.
Extract keypair caching to a shared module (keypair.ts) used by both
service-auth.ts (for creating service JWTs) and session.ts (for verifying
them). This ensures consistent behavior and reduces code duplication.
Move keypair caching, verifyServiceJwt, and ServiceJwtPayload from
separate modules into service-auth.ts where they logically belong
alongside createServiceJwt.
Add app.bsky.embed.video schema for video post support, along with
all dependent defs schemas (embed.defs, actor.defs, feed.defs,
graph.defs, notification.defs) that are referenced by other lexicons.
Scans all lexicon JSON files for external references and verifies
that corresponding lexicon files exist. Useful for ensuring all
dependencies are satisfied when adding new schemas.
Use jsonToLex() to convert incoming JSON records to proper lexicon
format before validation. This handles $link -> CID conversion and
blob object -> BlobRef conversion, fixing video embed validation.
@ascorbic ascorbic merged commit 407eaba into main Dec 29, 2025
3 checks passed
@ascorbic ascorbic deleted the claude/fix-video-upload-auth-dDcaZ branch December 29, 2025 11:09
@mixie-bot mixie-bot Bot mentioned this pull request Dec 29, 2025
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.

2 participants