All features

Feature breakdown · built with CraftHQ

SecuritySession

Session timeout with inactivity warning

Whole-team time at this build's pace

Estimated ~6 h

2 people incl. the product owner, requirements to merge

Estimate at this build's pace, not a measurement of this feature

An idle session warns the user with a countdown, then signs them out, so an unattended screen does not stay open.

Size: 8 FP · In-house IFPUG-style count, cross-checked by a second counter; not certified. Range 4 to 11. · How we counted 8 FP

How long a feature this size usually takes

Whole-team time — this build vs a typical team

8 FP · FP × 6.8 to 9.4 h (ISBSG 2023)

Whole-team time at this build's pace2 people incl. the product owner, requirements to merge
~6 h3 to 9 h

Estimate at this build's pace, not a measurement of this feature

A typical team, whole lifecycleRequirements to release · middle half of 512 comparable projects (Java, Agile), ISBSG 2023
~54 to 75 habout 1.5–2 person-weeksmedian ~63 h
grey band = a typical team, middle halfhatched = our whole-team estimate

Both figures are whole-team time over the whole lifecycle, so they compare like for like. Ours is this build's pace — about 0.8 hours per function point across the whole build (two people, including the product owner, with requirements and review time). The industry range is an ISBSG project-level figure applied to one feature, so it is indicative.

Workflow

How it moved through the workflow

Select a stage. The build shipped, so every stage is complete; a person approved the merge.

Request

Protect an unattended screen: warn the user before an idle session ends and then sign them out, with the timeout configurable.

Questions

One design decision was recorded before building.

Approved

The product owner signs off the breakdown by moving the story into the approved state, and the build runs against that reference.

Definition of ready

The questions are answered.
The acceptance criteria are testable.
The size is estimated.
The scope is checked for splitting.
The product owner has signed off.

Building

CraftHQ's build agents write the code and the tests together, run as a loop; a failing check halts the work until it passes.

Checks

Three checks run on every pull request: one on the product owner's machine as CraftHQ builds, one on the engineer's machine before review, and a code-quality scan in CI. Merging is gated by the CI check passing and a person's approval, enforced by branch protection.

Review

An engineer reviews the pull request and merges it.

Merged

The pull request is merged to main after a person approves it. Nothing merges without that approval.

Definition of done

Every acceptance criterion is checked; where a scenario has a dedicated test it is cited, and where it was verified by review that is stated.
The three checks are green.
A person approved the merge.

Breakdown

The feature breakdown

Business first, then the engineering view. Tab through it.

Overview

The gap it closes

An unattended, signed-in screen is a risk, but signing people out with no warning loses their work.

Who uses it

Every signed-in user, staff or customer.

User story

As a signed-in user, I want a warning before my session ends so that I am not signed out mid-task without notice.

Examples

Example 1

A user steps away. Near the timeout a countdown appears; they return, choose to stay signed in, and the session continues.

Example 2

A script quietly pings the server to keep the session alive without the user touching the screen. It does not count as activity, so the session still times out; and the server, not the browser, decides when a session has expired.

Dependencies & risks

Depends on

A 30-minute idle timeout, an absolute maximum session lifetime (12 hours for staff, 24 hours for customers), and a server that holds the authoritative remaining time and enforces it.

Risk & mitigation

A client-only timer could be stretched from the browser. Reduced by having the server own expiry and cap the absolute lifetime; the browser countdown only mirrors the server's expiry instant.

How it works

Simplified diagrams of the parts involved, the steps of one request, and where it runs.

Architecture

People
Signed-in useridle at a screen
Client (untrusted)
Session-timeout moduletracks real activity
Warning modallive countdown
Your app
App serverowns and decides expiry
Audit logrecords expiry
  • 1activity or idle
  • 2near timeout
  • 3re-sync remaining time
  • 4record the expiry
Simplified.

Sequence

Browserthe user
App serverowns the remaining time
Sessions + auditread and write
  • 1check remaining session time
  • 2time remaining
  • 3stay signed in (real activity)
  • 4extend on activity, or expire when idle or past the lifetime
  • 5continue or sign out
Simplified.

Infrastructure

Client (untrusted)
Web appthe warning modal, in the browser
Your app
App serverholds the authoritative timer; authenticates and pins the tenant
Databaseper-tenant isolation, sessions
  • 1session check (authenticate + tenant check)
  • 2read and write the session
Simplified.

Acceptance criteria

Each scenario is written as a Gherkin spec. The Engineering tab shows the test that covers each one, or notes where it was verified by review.

@sign-in @security
Feature: Session timeout with inactivity warning
As a signed-in user
I want a warning before my session ends
So that I am not signed out mid-task without notice
An idle session shows a countdown warning, then signs the user out. The server decides expiry; the browser timer only displays it.
Background:
Given a user is signed in
And an idle timeout and an absolute maximum lifetime are configured
Rule: A warning appears before an idle session ends
Scenario: The countdown warns before sign-out
Given a user has been idle and is near the timeout
When the warning threshold is reached
Then a live countdown warns the user the session will end
Scenario: Staying active keeps the session
Given the inactivity warning is showing
When the user chooses to stay signed in
Then the session continues
And the countdown clears
Rule: An idle session is signed out and recorded
Scenario: Idle sign-out
Given a user has been idle with no activity
When the countdown reaches zero
Then the user is signed out
And a background job records the expiry in the audit trail
Rule: The server decides expiry
Scenario: The browser timer cannot extend the session
Given a user's browser still shows time remaining
But the server considers the session expired
When the user takes their next action
Then the server rejects it and signs the user out
Scenario: The absolute lifetime caps the session
Given a user has stayed active up to the absolute maximum lifetime
When the next request is made after the lifetime is reached
Then the session ends regardless of activity
@edge-cases
Scenario Outline: Session states near the timeout
Given a user has been idle for "<idle>"
When the timer is checked against the server
Then the result is "<result>"
Examples:
| idle | result |
| under the threshold | session active |
| within the warning | countdown showing |
| past the timeout | signed out |

Questions

Questions raised in planning, each with the decision taken.

Should the timeout be a client-only timer, or owned by the server?

A client-only timer is simple but can be stretched from the browser and kept alive by a script without a real user. A server-owned timer decides expiry centrally and only resets on genuine activity.

AServer-authoritative: the server decides expiry and the browser timer only displays it; · recommended
BClient-only timer in the browser.
Decided: Server-authoritative; the browser only displays the remaining time (option A).

How we sized it

A function point measures what the software does — its inputs, outputs, lookups and the data it stores — regardless of language or how many lines it took. Each counted item is weighted by complexity: a user input counts 3–6 points, an output or report 4–7, a lookup 3–6, data the feature owns 7–10, and data read from elsewhere 5–7.

  • Show the time left before sign-out
    Lookup
    4
  • Extend the session to stay signed in
    User input
    4
  • Total
    8
8 function points (range 4–11). IFPUG-style count: each user action, lookup, output and stored data set, weighted by complexity. Technical plumbing is excluded, and a data store is counted once in the feature that owns it.

Not counted here

  • Session plumbing: technical, not a user function

Components touched

Session-timeout module

A client-side module that tracks idle time from real user activity and shows the warning modal near the timeout.

Warning modal

A live countdown with a stay-signed-in action.

Idle and absolute limits

A 30-minute idle timeout and an absolute maximum session lifetime (12 hours for staff, 24 hours for customers), enforced by the server.

Server-owned expiry

The server holds the authoritative remaining time, decides expiry, and a background job records each expiry in the audit trail. The browser timer only displays the remaining time.

Data touched

Sessionread

The remaining time is read from the server, which owns it.

Sessionwrite

The session is extended on real activity, or torn down on idle expiry or when the absolute lifetime is reached.

Audit logappend

A session-timeout event, recorded by a background job when a session expires.

Security decisions

  • The server decides expiry; the browser countdown only displays the remaining time, so a client timer cannot extend a session.
  • The absolute lifetime caps the session regardless of activity.
  • The idle timeout is 30 minutes and the absolute lifetime is 12 hours for staff and 24 hours for customers, enforced by the server.
  • An idle expiry ends the session and a background job records it in the audit trail.

Subtasks

  • A client-side session-timeout module tracking real activity, and a warning modal.
  • A configurable idle timeout and an absolute maximum lifetime.
  • Server-owned expiry that re-syncs the client; a background job records the expiry.

How each scenario is verified

  • The countdown warns before sign-out
    A client countdown unit test checks the server-authoritative seconds, the static and live chip, and the warning open and dismiss.
  • The server decides expiry, not the client
    A server expiry-audit integration test confirms a background job audits each newly expired session.
  • Staying active keeps the session
    A warning-modal unit test checks the live countdown, the stay-signed-in action and the in-flight disable.
  • The absolute lifetime caps the session regardless of activity
    Verified by review.

Risk tier

Logic A person approves every merge. This is a Logic-tier change; it carries automated tests for its rules.

Start here

Want this on your backlog?

Get a free baseline report on one repository, or scope a 3-month pilot measured against what your team’s work costs today.

Measured from your own git history
Every pull request tested before review
A person approves every merge