ServerAuth & Sessions
Runbook
Troubleshooting authentication and session issues in the CRM server.
Session Issues
Users logged out unexpectedly
Symptoms: Users are redirected to login despite valid credentials.
Diagnosis:
- Check browser dev tools → Application → Cookies
- Verify cookie domain matches the current domain
- Check session TTL in database
Common Causes:
- Cookie domain misconfiguration (check
BETTER_AUTH_URL) - Session expired in database
NODE_ENVmismatch between server and cookie settings
Resolution:
# Check session in database
psql -c "SELECT * FROM session WHERE user_id = '<user_id>'"Session cookie not set
Symptoms: API calls succeed but no session cookie in response.
Diagnosis:
- Check response headers for
set-cookie - Verify
sameSiteandsecuresettings - Check CORS configuration
Resolution:
- Ensure
CORS_ORIGINincludes the requesting domain - Check
trustedOriginsin auth config
API Key Issues
API key requests fail with 401 Unauthorized
Symptoms: Requests with x-api-key header return 401.
Diagnosis:
const data = await auth.api.verifyApiKey({ body: { key: apiKey } });
console.log(data.valid, data.key);Common Causes:
- API key invalid or revoked
- API key not associated with a user (
referenceIdmissing) - Organization mismatch
Resolution:
- Verify API key exists in database
- Ensure key has
referenceIdset - Check
x-tenant-idheader if org-specific key
Organization Issues
"User does not have access to organization"
Symptoms: 401 error when accessing org-scoped data.
Diagnosis:
const membership = await basePrisma.member.findFirst({
where: { userId: user.id, organization: { slug: orgSlug } },
});Resolution:
- User must be a member of the organization
- Check membership table for user-org pair
"User has no organization"
Symptoms: 401 error on first login, no org context.
Resolution:
- Ensure user is added to an organization during signup
- Check organization hook or seed data
Extension Token Issues
Extension token invalid/expired
Symptoms: Extensions fail to authenticate with Action API.
Diagnosis:
- Check token expiration
- Verify
EXTENSION_TOKEN_SECRETmatches
Resolution:
// Re-generate token for testing
const token = generateExtensionToken({
orgId: "...",
userId: "...",
scopes: ["read", "write"],
});Common Causes:
- Token TTL expired
EXTENSION_TOKEN_SECRETmismatch between servers- Token not scoped correctly
Debugging Tips
Enable Auth Logging
// In auth config
advanced: {
verbose: true, // Enable verbose logging
}Check Session in Handler
app.get("/debug/session", requireAuth, async (c) => {
return c.json({
user: c.get("user"),
session: c.get("session"),
org: c.get("org"),
});
});Database Queries
-- Check active sessions
SELECT s.id, s.expires_at, u.email
FROM session s
JOIN "user" u ON s.user_id = u.id;
-- Check API keys
SELECT k.id, k.reference_id, k.name
FROM api_key k
WHERE k.revoked = false;