Authentication
Both go in apps/coconut-os/.env.local, beside DATABASE_URL. Nothing else has to change: the middleware and the shell both switch themselves on once the keys are present.
The publishable key for the Clerk instance. This is what the sign in widget and the route middleware use. It is public, and it is the variable that decides whether any route is gated at all.
The secret key for the same Clerk instance. This is what the server uses to verify a session before looking up the ThcUser row behind it. It is a credential and must not be committed.
Both keys must name the SAME Clerk instance as the ops dashboard, because the identity this console looks up is ThcUser.clerkUserId, and those rows were written against that instance by apps/api/scripts/add-staff.ts. Pointing this app at a different Clerk instance would produce accounts that sign in successfully and match no staff row, which is refused rather than granted, but it is a confusing way to find that out.
A Clerk account is not access on its own. Signing in proves which account you are. The role and the active flag are read from the ThcUser row keyed by that account, so somebody who has never been added by an owner can sign in and still do nothing.