feat: add com.atproto.server.getServiceAuth endpoint#26
Merged
Conversation
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.
Deploying with
|
| 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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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:
Adds 4 new tests for the endpoint.