Session management
Skill almasumdev/awesome-mobile-backend-agent-skills/.github/skills/auth/session-management
Agent skills for the backend-for-mobile layer: APIs, auth, push, sync, and BaaS integrations.
npx -y skills add almasumdev/awesome-mobile-backend-agent-skills --skill session-managementAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Model multi-device sessions on the backend with sliding vs absolute expiry, device listing, and remote logout. Use when building the session model or a "Your devices" screen.
SKILL.md
5.0 KB, ~1.3k tokens by cl100k_base, as published. Nobody here has run it
Session Management
Instructions
A session represents one (user, device) pair. Mobile apps run for months; sessions must be long enough to be painless but short enough to contain damage after loss or theft.
1. Session Model
-- Postgres-ish
CREATE TABLE sessions (
id TEXT PRIMARY KEY, -- ULID
user_id TEXT NOT NULL,
device_id TEXT NOT NULL,
device_label TEXT, -- "Pixel 9 Pro", "iPhone 15"
created_at TIMESTAMPTZ NOT NULL,
last_used_at TIMESTAMPTZ NOT NULL,
absolute_expiry TIMESTAMPTZ NOT NULL,
sliding_expiry TIMESTAMPTZ NOT NULL,
revoked_at TIMESTAMPTZ,
ip_last INET,
ua_last TEXT
);
One row per active session family (see token-strategy). Refresh tokens are rows in a child table with session_id FK.
2. Sliding vs Absolute Expiry
Use both, and revoke when either trips.
- Sliding window: extends on each successful refresh. Typical: 30 days from
last_used_at. Lets active users stay signed in forever; idle devices drop off. - Absolute window: hard ceiling from
created_at. Typical: 90–180 days. Forces periodic re-auth even on active devices.
valid_session <=> now() < MIN(sliding_expiry, absolute_expiry) AND revoked_at IS NULL
Adjust for the app's risk profile. Banking: sliding 7d / absolute 30d. Social: sliding 60d / absolute 365d.
3. Multi-Device Behavior
Every login creates a new session row -- never reuse across devices. A user has N concurrent sessions (one per device_id).
Listing devices:
GET /v1/me/sessions
{
"items": [
{ "id": "sess_01HX7...", "device_label": "iPhone 15", "last_used_at": "2026-04-10T09:12:00Z", "current": true },
{ "id": "sess_01HX6...", "device_label": "Pixel 9", "last_used_at": "2026-03-28T17:02:00Z", "current": false }
]
}
Revoke a single device:
DELETE /v1/me/sessions/{id}
Revoke all except current (security event):
POST /v1/me/sessions/revoke-others
4. Revocation Semantics
Revocation hides behind the two-layer model from token-strategy:
- Mark
revoked_at = now()on the session row. Child refresh tokens inherit via JOIN. - Publish the
session_id(a.k.a.sid) to a short-lived denylist (Redis set with TTL = access-token max lifetime, e.g., 15 min). - Resource services check
sidagainst the denylist before honoring an access token.
After the access-token TTL, the denylist entry expires; refresh attempts will fail independently because the DB row is revoked.
5. Concurrency Caps (Optional)
For high-assurance apps, cap concurrent sessions per user (e.g., 5). On login, if the count is exceeded, revoke the least-recently-used session.
// Kotlin/JVM pseudocode
fun enforceCap(userId: String, max: Int = 5) {
val active = sessions.listActive(userId).sortedBy { it.lastUsedAt }
val toRevoke = active.size - (max - 1)
if (toRevoke > 0) active.take(toRevoke).forEach { sessions.revoke(it.id, reason = "CAP") }
}
Client UX: show the evicted device in a "Signed out of X to make room" notification on next login.
6. Security-Sensitive Actions
Password change, 2FA enrollment change, email change, account deletion:
- Revoke all sessions except the one performing the action.
- Force re-auth for the current session within 30 days (reset absolute expiry).
7. Step-Up Auth
For high-risk actions (large transfer, adding a new recipient), require a fresh authentication within N minutes even on a long-lived session. Track last_mfa_at on the session row; enforce in the API layer:
# FastAPI dependency
def require_fresh_auth(max_age: timedelta = timedelta(minutes=5)):
def dep(session: Session = Depends(current_session)):
if not session.last_mfa_at or now() - session.last_mfa_at > max_age:
raise HTTPException(401, {"error": {"code": "REAUTH_REQUIRED"}})
return dep
8. Client Consumption
When the app receives REAUTH_REQUIRED or INVALID_SESSION, it navigates to the login screen and drops the refresh token. Do not attempt silent retry.
// Swift
switch error {
case .reauthRequired:
await router.present(.login(reason: .reauth))
case .invalidSession:
await tokenStore.clear()
await router.replaceRoot(.login(reason: .expired))
}
Checklist
- Session row per (user, device) with sliding + absolute expiry.
-
GET /me/sessions,DELETE /me/sessions/{id},revoke-othersendpoints implemented. - Revocation writes DB + publishes to short-lived denylist.
- Concurrent-session cap decision recorded (with or without).
- Password / 2FA / email changes revoke other sessions.
-
last_mfa_attracked; step-up enforced on high-risk endpoints. - Client treats
INVALID_SESSION/REAUTH_REQUIREDas non-retryable. - Session events (create, revoke, reuse) logged for audit.
Gives 0 of the 12 instructions most auth identity skills give in ~1.3k tokens
Counted across 409 of the 410 authors here whose files we hold, read 2026-08-06
- hash passwords with bcrypt or argon2in 53 of 409, across 43 files
- use parameterized queriesin 47 of 409, across 39 files
- load SECRET_KEY from environment variablesin 23 of 409, across 14 files
- validate all input server-sidein 19 of 409, across 11 files
- refresh access tokens before expiryin 17 of 409, across 9 files
- store tokens in httponly cookiesin 17 of 409, across 16 files
- store refresh tokens securelyin 16 of 409, across 6 files
- validate webhook signatures before processingin 15 of 409, across 5 files
- sanitize user inputsin 15 of 409, across 9 files
- implement rate limiting on auth endpointsin 14 of 409, across 9 files
- encrypt sensitive data at restin 13 of 409, across 10 files
- validate uploaded file extensions and sizesin 12 of 409, across 5 files
Said here and by no other author read
- create one session row per user-device pair
- use both sliding and absolute expiry
- revoke the session when either expiry trips
- never reuse a session across devices
- track last multi-factor authentication time on the session
- require fresh authentication for high-risk actions
Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.