Backend · Skill
Design sessions and permissions
design-sessions-and-permissions
Plans auth and permissions for a custom backend without a hosted provider - sessions or JWTs, OAuth, password hashing, token refresh and revocation, then role-based access control and record ownership checks on the server. Use when the user is rolling their own auth, choosing between sessions and JWT, adding roles or admin-only routes, or one user can read another user's records.
Works with: Any AI Not yet model-tested; testing Jan 2027
Paste it into ChatGPT, Claude, Gemini or any AI chat, then tell it about your project. How it works
Install in Claude Code, Cursor or Codex (optional)
Only for AI coding tools that read skill folders. Run one line in a terminal, in your project folder. It downloads this skill's text files from TheSkillVault and nothing else; you can read them first with “View raw SKILL.md”.
Claude Code (all your projects)
curl -fsSL --create-dirs 'https://theskillvault.ai/api/skills/design-sessions-and-permissions/raw' -o ~/'.claude/skills/design-sessions-and-permissions/SKILL.md' && curl -fsSL --create-dirs 'https://theskillvault.ai/api/skills/design-sessions-and-permissions/files/LICENSE.txt' -o ~/'.claude/skills/design-sessions-and-permissions/LICENSE.txt'Cursor (this project)
curl -fsSL --create-dirs 'https://theskillvault.ai/api/skills/design-sessions-and-permissions/raw' -o '.cursor/skills/design-sessions-and-permissions/SKILL.md' && curl -fsSL --create-dirs 'https://theskillvault.ai/api/skills/design-sessions-and-permissions/files/LICENSE.txt' -o '.cursor/skills/design-sessions-and-permissions/LICENSE.txt'Codex and other Agent Skills tools (this project)
curl -fsSL --create-dirs 'https://theskillvault.ai/api/skills/design-sessions-and-permissions/raw' -o '.agents/skills/design-sessions-and-permissions/SKILL.md' && curl -fsSL --create-dirs 'https://theskillvault.ai/api/skills/design-sessions-and-permissions/files/LICENSE.txt' -o '.agents/skills/design-sessions-and-permissions/LICENSE.txt'
Or connect the whole library over MCP
Add TheSkillVault to Cursor or add this to your app's MCP settings (read-only; help):
{
"mcpServers": {
"theskillvault": {
"url": "https://theskillvault.ai/mcp"
}
}
}Auth is two questions. Authentication asks who you are. Authorisation asks what you may do. Most leaks come from answering the second one only in the browser.
When to use
- You are building your own sign-in instead of using a hosted provider.
- You need to choose between server sessions and JWTs.
- You want roles such as admin, editor and viewer, or owner-only records.
- A user reported they could open another user's page or data.
When not to use
- You already picked Clerk or Supabase Auth. Use add-clerk-auth or set-up-supabase-auth, then come back here for roles and ownership checks.
- You only need a password on a single internal page. Put it behind your host's access controls instead.
Choose a strategy
| Need | Pick | Why | | --- | --- | --- | | One web app, one server | Server session in an httpOnly cookie | Simple, revocable, nothing secret in the browser | | Mobile app or several APIs | Short access JWT plus a refresh token | Each service can verify without a shared store | | "Sign in with Google or GitHub" | OAuth 2.0 / OpenID Connect, code flow with PKCE | You never handle their password | | Company single sign-on | OIDC or SAML through a provider | Buying is cheaper than building |
Steps
- Write down who signs in, how (password, magic link, Google), and what each role may do. Keep it to one short table.
- Pick a strategy from the table above. When in doubt, use sessions.
- Hash passwords with Argon2id or bcrypt. Never store, log or email a plain password.
- Issue the credential. Sessions go in a cookie marked
HttpOnly,SecureandSameSite=Lax. Access JWTs live 15 minutes or less. - Rotate refresh tokens on each use and store them hashed, so you can revoke them on logout or theft.
- For OAuth, use the authorisation code flow with PKCE and check the
statevalue on the callback. - Add one server-side middleware that loads the user, and reject the request with 401 when there is none.
- Check the role on every protected route, and return 403 when it is missing.
- Check ownership on every record: load it, compare its owner to the signed-in user, then act.
- Add rate limits and lockout delays on login, signup and password reset.
- Log sign-ins, failures and role changes without logging tokens or passwords.
// Ownership check: never trust the id in the URL on its own.
export async function getInvoice(req: Request, user: User) {
const invoice = await db.invoice.findUnique({ where: { id: req.params.id } });
if (!invoice) return notFound();
if (invoice.ownerId !== user.id && user.role !== "admin") return notFound(); // 404 hides that it exists
return json(invoice);
}
Gotchas
- Hiding a button is not access control. The server must refuse the request too.
- JWTs cannot be taken back before they expire. Keep them short or keep a deny list.
- Tokens in
localStoragecan be read by any injected script. Prefer httpOnly cookies. - Cookie sessions need CSRF protection on forms that change data.
SameSite=Laxplus a token covers most apps. - Reset links must be single-use, expire within an hour and never reveal whether an email is registered.
- Keep signing secrets in environment variables, never in the repo, and rotate them if one leaks.
Portability
Works with any framework or language: Express, Hono, Next.js route handlers, FastAPI, Django or Rails. If you use a hosted provider instead of building sign-in, steps 7 to 11 still apply to your own API.
Example prompt
"My app has users and teams. Set up email and Google sign-in with sessions, add admin and member roles, and make sure users can only see their own team's projects."
Done when
- Every protected route returns 401 when signed out and 403 or 404 for the wrong user or role.
- Passwords are hashed and no token, password or secret appears in logs or the repo.
- Login and reset are rate limited, and logout revokes the session or refresh token.
---
Adapted from "auth-implementation-patterns" in wshobson/agents (MIT, Copyright (c) 2024 Seth Hobson). See LICENSE.txt.
Bundled files
Licence
Adapted from Seth Hobson (wshobson/agents, auth-implementation-patterns) (Copyright (c) 2024 Seth Hobson), MIT License. Adapted by TheSkillVault on 2026-11-02: rewritten as a decision table and build order for app builders, with original ownership-check and cookie examples; the reference library was not copied; added when-not-to-use, gotchas, portability and done-when. Not the original file.
Licence: MIT License. Attribution when you reuse it: Based on work by Seth Hobson (wshobson/agents, auth-implementation-patterns) (Copyright (c) 2024 Seth Hobson, MIT License), https://github.com/wshobson/agents/tree/7e2fb559cf4b824b27f1fec49fe88f7511066d26/plugins/developer-essentials/skills/auth-implementation-patterns; adapted by TheSkillVault, https://theskillvault.ai