Skip to content

Feature Request: Simplify ATProto OAuth Setup (Remove Manual JWK Requirement) #95

@daviddao

Description

@daviddao

Describe the feature you'd like to request

Problem

The current createATProtoSDK function requires developers to manually generate and manage JWK (JSON Web Key) pairs for DPoP authentication:

const sdk = createATProtoSDK({
  oauth: {
    clientId: "https://your-app.com/client-metadata.json",
    redirectUri: "https://your-app.com/callback",
    scope: "atproto",
    jwksUri: "https://your-app.com/.well-known/jwks.json",  // Must host public key
    jwkPrivate: process.env.ATPROTO_JWK_PRIVATE!,            // Must generate & store private key
  },
});

This creates significant friction for developers because they must:

  1. Generate JWK key pairs - Learn cryptographic key generation tools or libraries
  2. Host public keys - Create and maintain a /.well-known/jwks.json endpoint
  3. Securely store private keys - Set up environment variables and secrets management
  4. Understand DPoP - Learn OAuth 2.0 DPoP specification details

This complexity is a barrier to adoption, especially for developers who just want to add ATProto authentication to their app.

Current Workaround

Developers currently use the lower-level @atproto/oauth-client-node package directly, which auto-generates DPoP keys:

import { NodeOAuthClient } from '@atproto/oauth-client-node'

const client = new NodeOAuthClient({
  clientMetadata: {
    client_name: 'My App',
    client_id: `${publicUrl}/api/oauth/client-metadata.json`,
    redirect_uris: [`${publicUrl}/api/oauth/callback`],
    scope: 'atproto',
    dpop_bound_access_tokens: true,
  },
})

However, this means:

  • Missing out on Hypercerts SDK features like sdk.repository(session)
  • Having to implement ATProto record storage manually
  • Duplicating authentication logic that the SDK should handle

Describe the solution you'd like

Proposed Solution

Make JWK setup optional with automatic key generation as the default:

Option 1: Auto-generate keys (default behavior)

const sdk = createATProtoSDK({
  oauth: {
    clientId: "https://your-app.com/client-metadata.json",
    redirectUri: "https://your-app.com/callback",
    scope: "atproto",
    // No jwksUri or jwkPrivate needed! SDK handles it internally
  },
});

The SDK would:

  • Auto-generate ephemeral JWK pairs on initialization
  • Handle DPoP signing internally
  • Store keys in the session/state stores provided

Option 2: Advanced users can still provide custom keys

const sdk = createATProtoSDK({
  oauth: {
    clientId: "https://your-app.com/client-metadata.json",
    redirectUri: "https://your-app.com/callback",
    scope: "atproto",
    // Optional: for advanced use cases
    jwksUri: "https://your-app.com/.well-known/jwks.json",
    jwkPrivate: process.env.ATPROTO_JWK_PRIVATE,
  },
});

Benefits

  1. Lower barrier to entry - Developers can get started immediately without crypto knowledge
  2. Better DX - Matches expectations from other OAuth libraries (simpler = better)
  3. Fewer configuration errors - Auto-generation eliminates key generation mistakes
  4. Increased adoption - More developers will use Hypercerts SDK instead of raw @atproto/oauth-client-node
  5. Still supports advanced use cases - Power users can still bring their own keys

Implementation Notes

The underlying @atproto/oauth-client-node already supports auto-generation of DPoP keys. The SDK could:

  1. Check if jwksUri and jwkPrivate are provided
  2. If not provided, let the OAuth client auto-generate keys
  3. Store generated keys in the session store for persistence across requests
  4. Provide a helper method to export keys if users want to persist them:
    const keys = await sdk.exportDpopKeys()
    // Save to database/file system for reuse

Related Work

  • @atproto/oauth-client-node - Already implements automatic DPoP key generation
  • Other OAuth libraries (NextAuth, Auth.js, Passport) - Don't require manual crypto key management
  • AT Protocol OAuth spec - DPoP is transparent to most application developers

Use Case

I'm building a hyperboard management tool and want to use ATProto authentication. The current JWK requirement is blocking me from using the Hypercerts SDK's repository() API, forcing me to either:

  • Use raw OAuth client and lose SDK features
  • Spend hours learning JWK generation (tangential to my actual feature)

Making JWK setup optional would let me authenticate users in minutes instead of hours.

Describe alternatives you've considered

Not using the SDK

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions