Pinned 2026 toolchains (Go 1.26, Rust 1.98/edition 2024, Python 3.14 + uv, Node 24, Zig 0.16, NixOS 26.05), postgres 18 / mongo 8, lockfiles built from, non-root runtimes, .dockerignore, per-project LICENSE, READMEs with the git.devai.io clone line, checkout@v7 CI. Security fixes in the legacy Rust APIs (any-password login, self-assigned admin, hard-coded JWT secret), JWT alg/exp/sub enforcement across the blog series, safe markdown links in the frontends, and many smaller bugs — every project was built, run and exercised end to end. Adds scripts/publish.sh + a CI publish job that splits every folder into its own repo at git.devai.io/templates/<folder>. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01128fhuZbgivaSJvtMf4s1G
46 lines
2.1 KiB
Markdown
46 lines
2.1 KiB
Markdown
# Clerk auth (drop-in)
|
|
|
|
Replaces the template's local email/password auth with [Clerk](https://clerk.com)
|
|
session tokens. Users sign up and sign in through Clerk (hosted pages or one of
|
|
its frontend SDKs); this API only verifies the session JWT Clerk issues.
|
|
|
|
`clerk.go` validates `Authorization: Bearer <token>` against your Clerk
|
|
instance's JWKS endpoint (RS256 signature, issuer, expiry, `azp`) and exposes
|
|
the Clerk user id via `userID(r)` — the same helper the local setup provides, so the post handlers keep working.
|
|
|
|
## Swap steps
|
|
|
|
1. Copy `clerk.go` into the project root and change `package clerkauth` to
|
|
`package main`.
|
|
2. Delete `auth.go` — register, login, and HS256 tokens are Clerk's job now.
|
|
3. In `main.go`, drop the `AUTH_SECRET` lookup (and the `secret` field on
|
|
`app`), drop the `/auth/register` and `/auth/login` routes, and wrap the
|
|
protected routes with the Clerk middleware:
|
|
|
|
```go
|
|
requireAuth := newClerkAuth()
|
|
mux.HandleFunc("POST /posts", requireAuth(a.createPost))
|
|
mux.HandleFunc("PUT /posts/{id}", requireAuth(a.updatePost))
|
|
mux.HandleFunc("DELETE /posts/{id}", requireAuth(a.deletePost))
|
|
```
|
|
|
|
4. Author ids are now Clerk user ids (strings like `user_2f...`), not integers:
|
|
- in `schema.sql`, drop the `users` table and change `posts.author_id` to
|
|
`TEXT NOT NULL` (no foreign key) — then reset the database
|
|
(`docker compose down`, delete `./data`) so the new schema applies;
|
|
- in `posts.go`, change the `post.AuthorID` field to `string` and use
|
|
`userID(r)` directly instead of `strconv.ParseInt(userID(r), 10, 64)`.
|
|
5. Environment: remove `AUTH_SECRET`, add your instance's issuer and the
|
|
origins allowed to mint tokens for this API (checked against the `azp`
|
|
claim; leave it unset to skip the check):
|
|
|
|
```
|
|
CLERK_ISSUER=https://your-app.clerk.accounts.dev
|
|
CLERK_AUTHORIZED_PARTIES=https://your-site.com,http://localhost:5173
|
|
```
|
|
|
|
The issuer is your Frontend API URL (Clerk dashboard → API keys);
|
|
production instances use your own domain, e.g. `https://clerk.your-site.com`.
|
|
|
|
After the swap `go vet ./...` should pass and every `(auth)` route expects a
|
|
Clerk session JWT.
|