Audience: Owners, Admins, Security, Backend
βOutcomes: Correctly hardened sign-in, scoped permissions, and auditable sessions
Principles
Tenant isolation by org context on every request.
Least privilege via RBAC; sensitive actions gated by KYC.
Strong auth: 2FA for admins; SSO (SAML/OIDC) for enterprise.
Sessions (Express)
app.use(session({ name: 'connect.sid', secret: process.env.SESSION_SECRET!, cookie: { httpOnly: true, sameSite: 'lax', secure: process.env.NODE_ENV==='production' }, rolling: true, // sliding TTL refresh resave: false, saveUninitialized: false }));
RBAC & KYC guards
function requireRole(...roles: Array<'owner'|'admin'|'member'>) { return (req,res,next) => !req.user ? res.status(401).json({message:'Auth required'}) : !roles.includes(req.user.role) ? res.status(403).json({message:'Insufficient role'}) : next(); } const enforceKyc = (action:string)=>async(req,res,next)=>{ const r = await kycService.enforceKycForAction(req.user.id, action); if(!r.allowed) return res.status(403).json({requiresKyc:true,message:r.reason}); next(); };
CSRF stance
JSON-only API + strict CORS + SameSite=Lax β low CSRF risk.
If HTML forms/embeds exist, add CSRF tokens (double-submit or server-issued).
QA checklist
Admin actions appear in audit log with actor + correlation ID.
KYC-gated endpoints return
403 { requiresKyc: true }
when not verified.Session cookie is httpOnly+Secure+SameSite=Lax in prod.
Runbook: account takeover suspicion
Force-logout all sessions for user;
Require password reset & 2FA on next login;
Review recent audit entries & IP/ASN;
Notify org Owner.