Skip to content

feat(backend): *WIP* Add machine authentication support #5689

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

wobsoriano
Copy link
Member

@wobsoriano wobsoriano commented Apr 22, 2025

Description

This PR adds machine authentication support (atm only in the backend SDK) by introducing support for 4 token types: api_key, oauth_token, machine_token, and session_token. To maintain backwards compatibility, session_token remains the default authentication method when no specific token type is specified. This ensures existing apps continue to work without modification while allowing new applications to opt-in to machine authentication methods through the acceptsToken option.

Key changes:

  • Deprecated SignedInState and SignedOutState in favor of AuthenticatedState and UnauthenticatedState to better represent both session and machine authentication states. They still return the same properties, with an added tokenType and isAuthenticated properties (deprecating isSignedIn).
  • The toAuth() method now returns a different value if the tokenType is not a session_token. For now, we landed on the id, name, subject and claims property for machine auth tokens.
  • Added two new internal functions in authenticateRequest: authenticateAnyRequestWithTokenInHeader and authenticateMachineRequestWithTokenInHeader to handle machine authentication.
  • The internal signedIn and signedOut functions have been updated to accommodate machine auth.
  • Added new error types and codes specific to machine token verification (MachineTokenVerificationErrorCode)
  • Added new APIs (APIKeysApi, IdPOAuthAccessTokenApi, and MachineTokensApi) used inside a new verifyMachineAuthToken function to validate tokens against their respective endpoints
  • Added test for various scenarios for token validation, handling different token types, token mismatch, and proper error responses when verification fails

Here's an example usage pattern with API key:

Say C1 wants to protect their endpoints in a Hono app:

import { serve } from '@hono/node-server'
import { createMiddleware } from 'hono/factory'
import { Hono } from 'hono'
import { clerkClient } from './client'
import { HTTPException } from 'hono/http-exception'

const app = new Hono()

const clerkMiddleware = createMiddleware(async (c, next) => {
  const authReq = await clerkClient.authenticateRequest(c.req.raw, {
    acceptsToken: 'api_key'
  })

  if (!authReq.isAuthenticated) {
    throw new HTTPException(401, { message: 'Unauthorized' })
  }

  await next()
})

app.post('/api/protected', clerkMiddleware, async (c, next) => {
  return c.text('Hello from /api/protected')
})

Then C2 can access it by passing the api_key:

const resp = await fetch('http://localhost:3000/api/protected', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${process.env.API_KEY}`
  },
})

const data = await resp.text()

P.S. I attempted to break this down into smaller PRs but the changes are tightly coupled 😞 So sorry and thank you in advance reviewer!

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

Copy link

vercel bot commented Apr 22, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
clerk-js-sandbox ✅ Ready (Inspect) Visit Preview 💬 Add feedback Apr 23, 2025 6:12pm

Copy link

changeset-bot bot commented Apr 22, 2025

⚠️ No Changeset found

Latest commit: a3a3d03

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants