SC-23(3): Unique System-generated Session Identifiers
SC-23(3) requires you to generate a unique, system-created session identifier for every user or system session and to reject any session identifier not generated by your system. To operationalize it, standardize session creation in your apps and identity layers, prevent client-supplied or predictable IDs, and retain evidence that session tokens are unique, server-generated, and validated on every request. 1
Key takeaways:
- Generate a unique session ID on the server for every session; never accept a client-provided session ID. 1
- Enforce “system-generated only” by validating token origin/format and rotating IDs at key lifecycle events (login, privilege change). 1
- Keep audit-ready artifacts: designs, configs, code references, and logs that demonstrate issuance and rejection behavior. 1
The sc-23(3): unique system-generated session identifiers requirement is a narrow control with an outsized impact on account takeover, session fixation, and replay risk. Assessors look for one thing: proof that your systems, not the user’s browser or a calling client, create the session identifier, and that your systems refuse to honor identifiers that did not come from your issuance flow. 1
For a CCO, GRC lead, or compliance officer supporting engineering, the fastest path is to translate SC-23(3) into a small set of non-negotiable technical rules: server-side generation, strong uniqueness properties, strict validation, and a controlled lifecycle (create, rotate, expire, revoke). Then you wrap those rules in repeatable evidence: documented standards, implementation tickets, configuration baselines, and test results that you can hand to an auditor without reverse-engineering your own stack.
This page gives requirement-level implementation guidance you can push into SDLC and platform engineering, including common audit hangups, evidence to retain, and a practical execution plan. The text is aligned to NIST SP 800-53 Rev. 5. 2
Regulatory text
Requirement (verbatim): “Generate a unique session identifier for each session with {{ insert: param, sc-23.03_odp }} and recognize only session identifiers that are system-generated.” 1
Operator translation (what you must do):
- Every session gets its own unique identifier created by the system at session establishment. 1
- The system must only recognize system-generated identifiers. If a request arrives with a session identifier that is malformed, unissued, expired, or otherwise not produced by your session service, it must be rejected or treated as unauthenticated. 1
The placeholder sc-23.03_odp is an organization-defined parameter in the catalog. Treat it as your policy knob for where/when sessions exist (web apps, APIs, privileged admin consoles, VPN portals, etc.) and what “session” means in your architecture. 1
Plain-English interpretation
SC-23(3) is a “no DIY sessions” rule. Users and calling clients cannot choose the session identifier, influence it, or reuse a prior identifier to force the server into binding an authenticated state to an attacker-chosen token. Your system issues the identifier, records it server-side (or signs it such that tampering is detectable), and validates it on each request before honoring any session state.
If you use modern stateless tokens (for example, signed tokens carried by the client), SC-23(3) still applies: the token must be minted by your system and requests with non-minted tokens must fail validation.
Who it applies to
Entity scope: Federal information systems and contractor systems handling federal data. 1
Operational scope (where the control shows up in real life):
- Web application sessions (cookies, server session stores)
- API “sessions” where you issue an access token that confers ongoing access
- Administrative consoles and privileged access portals
- Remote access gateways and SSO front doors
- Third-party hosted applications where you configure session/token behavior (SaaS), and you must still document how the provider satisfies “system-generated only”
If you have multiple stacks (legacy monolith, newer microservices, separate mobile backend), assessors will expect consistent rules or documented exceptions with compensating controls.
What you actually need to do (step-by-step)
1) Define “session” and set the control boundary
- Inventory all authentication entry points: SSO, app-native login, API token issuance, administrative tools, and any service-to-service session equivalents.
- Decide which components are the “session issuer” for each flow (IdP, gateway, app server, auth service).
- Document the organization-defined parameter behind
sc-23.03_odpas a short scoping statement: which systems and session types are in-scope and why. 1
Deliverable: SC-23(3) scope statement + system list mapped to session mechanism.
2) Standardize server-side session ID generation
For each in-scope system:
- Ensure the session identifier is generated only on the server (or by a controlled security service) during session creation. 1
- Use an approved session/token library native to your framework rather than custom code.
- Ensure uniqueness properties are appropriate for your risk level (the control requires uniqueness; your security engineering standard should define how you meet that consistently).
Practical pattern: Put session issuance behind a single service or shared library so teams cannot “roll their own” session IDs in edge cases.
3) Enforce “recognize only system-generated” through strict validation
You need a hard fail path when the identifier is not system-generated. Implement:
- Format/structure validation (expected length/charset, correct prefix, correct signature structure for signed tokens)
- Issuer validation (for signed tokens, validate signature and issuer claims; for server-stored sessions, validate the ID exists in the session store and is active)
- Lifecycle validation (not expired, not revoked, not outside allowed client context if you bind sessions to device/browser characteristics)
Control objective: A client cannot set sessionId=abc and have the server accept it. The server must ignore, overwrite, or reject that identifier and proceed as unauthenticated. 1
4) Rotate session identifiers at risk-relevant events
SC-23(3) is about unique identifiers per session. In practice, auditors often ask how you prevent fixation across authentication boundaries. Adopt engineering requirements to:
- Issue a fresh session ID at login (new authenticated session).
- Rotate on privilege elevation or sensitive changes (password reset, MFA enrollment changes, role changes).
- Invalidate old session identifiers on logout and on high-risk events (suspicious activity, user disablement).
Keep these as documented engineering standards even if you implement them differently across stacks.
5) Centralize configuration and set minimum baselines
Common settings you should baseline 1:
- Cookie settings (for cookie-based sessions): Secure, HttpOnly, SameSite policy where applicable
- Token validation settings (for JWT/OIDC): accepted algorithms, required claims, clock skew handling, issuer/audience allowlists
- Session store TTL and revocation behavior
SC-23(3) does not list these specifics, but they are often the operational proof points that show “system-generated only” is real.
6) Test the control like an attacker would
Add test cases to QA/security testing:
- Attempt session fixation: supply a known session ID before login and confirm it is not accepted post-login.
- Attempt token tampering: modify a signed token and confirm rejection.
- Attempt replay of expired/revoked tokens and confirm rejection.
Tip: Keep a small set of reproducible tests and run them per major release for in-scope apps.
7) Make it auditable (map owner, procedure, recurring evidence)
Assign a control owner (often IAM/platform security) and document:
- The implementation procedure (how teams create sessions, validate them, rotate/expire them)
- Recurring evidence artifacts (what gets collected each quarter/release)
This mapping is explicitly called out as recommended control hygiene for SC-23(3). 1
Required evidence and artifacts to retain
Keep evidence that is credible to both engineers and auditors:
Governance
- SC-23(3) control narrative (1–2 pages) with scope and architecture patterns 1
- Secure coding standard or authentication/session standard that forbids client-provided session identifiers
Technical
- Configuration exports or screenshots from:
- IdP token settings (issuer/audience, signing settings)
- API gateway token validation policies
- Application session middleware configuration
- Code references (links to repositories/paths) showing:
- Session ID generation call sites
- Validation logic and rejection paths
- Test results:
- Automated unit/integration tests for invalid token rejection
- Security test notes for session fixation attempts
Operational
- Log samples showing:
- Rejected requests due to invalid/unknown session IDs
- Session creation events (without logging secrets)
- Change tickets demonstrating rollout and approvals for session changes
If you use Daydream to run control operations, store the owner assignment, implementation procedure, and the recurring evidence checklist alongside each in-scope system so you can produce a consistent package at audit time.
Common exam/audit questions and hangups
- “Show me that session identifiers are system-generated.” Expect a request for code/config plus a demo where a client-supplied identifier is rejected. 1
- “Are session IDs unique per session?” Auditors may ask how you prevent reuse after logout or expiration.
- “Which systems are in-scope?” If your scoping is vague, they will expand it for you. Tie scope to the
sc-23.03_odpparameter and your system inventory. 1 - “How do third-party applications meet this?” You need provider documentation/config evidence, plus your own settings and contractual/security review notes.
Frequent implementation mistakes (and how to avoid them)
- Accepting session IDs from URL parameters or request headers. Fix by stripping/ignoring client-provided IDs and generating a new one server-side at session creation.
- Custom session/token code in one legacy service. Fix by mandating a standard library and putting exceptions through security architecture review.
- No explicit rejection telemetry. Fix by logging validation failures at a safe level (no secrets) so you can prove the system refused non-generated identifiers.
- Stateless tokens accepted without issuer/signature enforcement. Fix by requiring signature validation and strict issuer/audience allowlists in every verifier.
- Evidence scattered across teams. Fix by collecting a standardized “SC-23(3) evidence packet” per system, tied to a named owner. 1
Risk implications (why operators care)
If an attacker can force a victim to authenticate into an attacker-chosen session ID (session fixation) or if the system accepts arbitrary identifiers, you can see account takeover without credential compromise. This risk often surfaces as “authentication looked normal in logs,” because the attacker abuses session state rather than passwords. SC-23(3) is one of the controls that makes those attacks harder by design. 1
Practical 30/60/90-day execution plan
First 30 days (Immediate stabilization)
- Name a single control owner and backups; document scope for what counts as a session in your environment. 1
- Inventory in-scope apps and token/session mechanisms.
- Pick standard patterns per stack (web, API, mobile, admin).
- Identify highest-risk gaps: any place a client can pass a session ID that the server honors.
Days 31–60 (Implementation and validation)
- Update app frameworks/gateways/IdP configs to enforce server-generated identifiers and strict validation.
- Add session rotation rules at login and privilege change in at least your highest-risk systems.
- Implement test cases for fixation and tampering; run them against a staging environment.
- Start collecting the recurring evidence packet per system.
Days 61–90 (Operationalize and audit-package)
- Expand coverage to remaining in-scope systems and document exceptions with compensating controls.
- Add monitoring alerts for spikes in invalid session/token submissions.
- Complete an internal assessment walkthrough: show configs, code references, and test outputs in one place.
- Build a repeatable evidence cadence in Daydream: ownership, procedures, and quarterly evidence requests aligned to SC-23(3). 1
Frequently Asked Questions
Does SC-23(3) apply if we use JWTs and “stateless sessions”?
Yes. The token still functions as the session identifier, so it must be minted by your system and rejected if it is not system-generated (invalid signature, wrong issuer, tampered claims). 1
How do we prove “unique” without generating statistics?
Keep design evidence: the approved library/mechanism used to generate identifiers, plus test cases that show new sessions get new identifiers and that old identifiers are invalidated. The requirement is uniqueness and system generation, not a numeric collision analysis. 1
What does “recognize only session identifiers that are system-generated” mean in an audit?
Auditors typically want to see that client-supplied session IDs are ignored or rejected and that only identifiers created by your issuance path will be accepted. Demonstrate with a negative test and supporting logs/config. 1
Are URL-based session IDs allowed?
They are high-risk operationally because they are easy to copy, replay, and leak via referrers and logs. If you must support them, you need strong controls to ensure they are still system-generated and strictly validated, and you should document the exception and risk acceptance. 1
How do we handle third-party SaaS where we can’t see session code?
Treat the SaaS as in-scope where it handles federal data, then collect provider documentation and your configuration settings (SSO/token policies) as evidence. Record the control mapping and evidence cadence so audits do not stall on “black box” services. 1
Who should own SC-23(3): IAM or application teams?
Assign a primary owner (often IAM/platform security) for the standard and evidence, and require application teams to implement the standard in their services. Auditors look for clear ownership and repeatable artifacts across systems. 1
Footnotes
Frequently Asked Questions
Does SC-23(3) apply if we use JWTs and “stateless sessions”?
Yes. The token still functions as the session identifier, so it must be minted by your system and rejected if it is not system-generated (invalid signature, wrong issuer, tampered claims). (Source: NIST SP 800-53 Rev. 5 OSCAL JSON)
How do we prove “unique” without generating statistics?
Keep design evidence: the approved library/mechanism used to generate identifiers, plus test cases that show new sessions get new identifiers and that old identifiers are invalidated. The requirement is uniqueness and system generation, not a numeric collision analysis. (Source: NIST SP 800-53 Rev. 5 OSCAL JSON)
What does “recognize only session identifiers that are system-generated” mean in an audit?
Auditors typically want to see that client-supplied session IDs are ignored or rejected and that only identifiers created by your issuance path will be accepted. Demonstrate with a negative test and supporting logs/config. (Source: NIST SP 800-53 Rev. 5 OSCAL JSON)
Are URL-based session IDs allowed?
They are high-risk operationally because they are easy to copy, replay, and leak via referrers and logs. If you must support them, you need strong controls to ensure they are still system-generated and strictly validated, and you should document the exception and risk acceptance. (Source: NIST SP 800-53 Rev. 5 OSCAL JSON)
How do we handle third-party SaaS where we can’t see session code?
Treat the SaaS as in-scope where it handles federal data, then collect provider documentation and your configuration settings (SSO/token policies) as evidence. Record the control mapping and evidence cadence so audits do not stall on “black box” services. (Source: NIST SP 800-53 Rev. 5 OSCAL JSON)
Who should own SC-23(3): IAM or application teams?
Assign a primary owner (often IAM/platform security) for the standard and evidence, and require application teams to implement the standard in their services. Auditors look for clear ownership and repeatable artifacts across systems. (Source: NIST SP 800-53 Rev. 5 OSCAL JSON)
Operationalize this requirement
Map requirement text to controls, owners, evidence, and review workflows inside Daydream.
See Daydream