Add Clerk authentication to your app
You are an agent wiring Clerk as the external identity provider for end-user login / accounts in a DeployMill-managed app. Read this together with the general deploymill://guides/auth reference (the four platform facts about auth on DeployMill still apply) and deploymill://guides/secrets (the secret hand-off).
DeployMill operates nothing here
This is bring-your-own auth. DeployMill does not run a user store, a login UI, or any token validation for you. What it does is small and explicit:
- It records your choice in the
authblock of.deploymill/project.json(provider-neutral config). - It hands off the Clerk secret values the normal way (
set_env_vars/request_secret) so the agent never sees them. - On
reconcile_projectit runs a read-only presence-check that the expected env-var names are set on the app, and emits a typedauth_secret_missinghint (with this guide's URI) when they are not. It reads key names only, never the values.
Clerk holds your users, sessions, and login pages. Your app talks to Clerk with its SDK.
The env-var contract
Clerk needs these env vars on the app:
CLERK_SECRET_KEY: secret. Push it through the vault / hand-off, never into a transcript.CLERK_PUBLISHABLE_KEY: not secret, safe toset_env_vars.
These are the exact names the reconcile presence-check looks for. If either is missing, reconcile_project returns applied.auth.hint === "auth_secret_missing" with the missing name(s) in applied.auth.missingEnvKeys and a pointer to this guide.
The secret hand-off (agent never sees values)
request_secret({ name: "CLERK_SECRET_KEY" })→ hand the returned link to the user → pollsecret_request_status→bind_secret({ applicationId, name: "CLERK_SECRET_KEY" })(or declare it undersecretsinproject.jsonand reconcile). The value is resolved server-side. It never appears in chat.set_env_vars({ applicationId, vars: { CLERK_PUBLISHABLE_KEY: "pk_live_…" } }). The publishable key is not secret.
See deploymill://guides/secrets for the full vault flow.
App-side SDK snippet
A minimal Express/Node sketch using @clerk/express:
import { clerkMiddleware, requireAuth, getAuth } from "@clerk/express";
// Reads CLERK_SECRET_KEY + CLERK_PUBLISHABLE_KEY from the env DeployMill injected.
app.use(clerkMiddleware());
app.get("/me", requireAuth(), (req, res) => {
const { userId } = getAuth(req);
res.json({ userId });
});
(Use the matching Clerk SDK for your framework. The env-var names are the same.)
The auth project.json block
Declare the provider so reconcile records it and runs the presence-check:
{
"version": 2,
"auth": { "provider": "clerk", "audience": "users" }
}
audience is optional and only "users" today (end-user login). Then reconcile_project. If the keys are wired you get applied.auth.hint === null. If not, fix the missing names it reports and reconcile again.