triplit icon indicating copy to clipboard operation
triplit copied to clipboard

Docs: Better auth guide?

Open Blankeos opened this issue 4 months ago • 3 comments

https://www.triplit.dev/docs/auth/integration-guides/clerk

Possible: https://www.triplit.dev/docs/auth/integration-guides/better-auth

Blankeos avatar Jul 30 '25 07:07 Blankeos

Managed to figure it out + also kind of a scrub at this stuff, so I'll write a quick little guide for myself and others here, since It kinda worked for me so I'll just write it here:

better auth + triplit for scrubs

  1. The better auth schema
  • TL;DR; just use jwt() plugin + the RS256 algorithm.
  • Why RS256? Because EdDSA (better-auth's default) for some reason is impossible to turn into a PEM format (I tried the online converter and an npm package to do it) that Triplit wants. But RSA is widely supported by these PEM formatters for some reason. This is a blackbox to me.
  1. The important env variables:
# Better Auth uses it by default, but configurable via the "secret" property in betterAuth({ ... })
# This is your PRIVATE KEY
BETTER_AUTH_SECRET="" 

# Triplit uses it by default, but not configurable afaik
# This is your PUBLIC KEY and will be used to verify a JWT
EXTERNAL_JWT_SECRET="
  1. Important endpoints:
  • If you setup better-auth correctly, by default you will get:
    • /api/auth/token - to get a JWT token of a currently logged in user.
    • /api/auth/jwks - to get the public key.
  1. Creating the PRIVATE and PUBLIC keys.
  • If you're new to this like I am, there are two ways openssl and ssh-keygen. But for some reason, you will prefer openssl because sshkeygen creates a non-pem public key format.
# Openssl way:
openssl genrsa -out rsa-private.key 2048
openssl rsa -in rsa-private.key -pubout -out rsa-private.key.pub

# sshkeygen way
ssh-keygen -t rsa -b 2048 -m PEM -f rsa-private.key # This both generates an rsa-private.key.pub that will 
openssl rsa -in rsa-private.key -pubout -out rsa-private.key.pub # Run the same command to get a pem format.

Tbh I also don't know why 2048 length is used (it just worked for me). Also the difference between .pem and .key. I will never know lol because you end up copying this into .env later anyway.

You'll also end up realizing the PUBLIC key is actually completely useless lol. I'll explain why below.

  1. Using the keys in .env
# Use the rsa-private.key (private key)
BETTER_AUTH_SECRET="-----BEGIN RSA PRIVATE KEY-----
MII.../CozvyI
d5..Aprf9cP
-----END RSA PRIVATE KEY-----" 

# Use the rsa-private.key.pub (public key)
EXTERNAL_JWT_SECRET="-----BEGIN PUBLIC KEY-----
MII.../CozvyI
d5..Aprf9cP
-----END PUBLIC KEY-----"

So the public key is actually useless at the moment and won't work, you can in fact try this by logging in your user, getting the JWT, pasting that on jwt.io, and also pasting the current public key (in pem format) and see if it's verified (it won't be). I think because better-auth does privateKeyEncryption by default?

  1. Anyway to fix that last gotcha...
  • Just go to /api/auth/jwks to get the public key in jwks format. fyi This is also stored in the database under jwks table. It's just 1 entry.
  • Go to https://8gwifi.org/jwkconvertfunctions.jsp and paste the jwks json in there, and submit.
  • You will get a pem formatted public key.

And now your auth should work!! Somehow!

Blankeos avatar Jul 30 '25 19:07 Blankeos

Thanks for the contribution! We should try to setup a guide in our docs. @daveycodez also has some libraries related to this: https://github.com/daveyplate/better-auth-triplit

wernst avatar Jul 30 '25 19:07 wernst

Using the JWT plugin adds a lot of extra overhead and API requests. My adapter signs the JWT as session.token whenever a session is created, using the normal BETTER_AUTH_SECRET as the signing key

daveycodez avatar Jul 30 '25 20:07 daveycodez