Challenge 6: Session Management and Dual Authorisation¶
Objective: Implement the two-person rule for safety-critical operations to prevent single-person abuse while understanding the security vs usability trade-offs.
Category: Access Control & Insider Threat Prevention
Difficulty: Intermediate
Time Required: 30-45 minutes
Learning outcomes¶
By completing this challenge, you will:
Understand the two-person rule for critical operations
Implement dual authorisation for safety bypasses
Manage authentication sessions and timeouts
Balance security requirements with operational needs
Detect potential collusion patterns
Understand when prevention isn’t enough (detection matters)
Background: two-person rule¶
The Problem: Some operations are too critical for one person. A single insider with valid credentials can abuse their access.
Examples of Critical Operations:
Reactor shutdown (SCRAM)
Safety system bypass
Emergency turbine stop
Force operations (overriding sensors)
Firmware uploads to PLCs
Two-Person Rule: Require independent authorisation from two different users, both with appropriate permissions.
Not About Technology: The two-person rule is fundamentally a procedural control enforced by technology. Technical controls verify two authenticated sessions, but cannot guarantee two different people are physically present.
Current state (infrastructure ready)¶
Good news: The dual authorisation infrastructure is already implemented:
AuthenticationManager - Dual auth method exists
Session Management - Timeout support, session tracking
Permission System - Role-based permissions (SAFETY_BYPASS, etc.)
Audit Logging - All dual auth attempts logged
Your job: Use the dual authorisation system for critical operations.
Part 1: Understanding dual authorisation¶
Step 1.1: Review available users and permissions¶
Check which users can perform safety bypasses:
python tools/blue_team.py rbac list-users
Example output:
Users (5):
admin (admin ) - permissions: all
supervisor1 (supervisor) - permissions: read, write, config, safety_bypass
supervisor2 (supervisor) - permissions: read, write, config, safety_bypass
operator1 (operator ) - permissions: read, write
operator2 (operator ) - permissions: read, write
Key Observations:
Only supervisors and admins have
SAFETY_BYPASSpermissionOperators can read/write but cannot bypass safety systems
Two-person rule requires two users with the permission
Step 1.2: Understand the dual authorisation API¶
The authentication system provides authorize_with_dual_auth():
from components.security.authentication import AuthenticationManager, PermissionType
auth = AuthenticationManager()
# Authenticate two users
session1 = await auth.authenticate("supervisor1", "super123")
session2 = await auth.authenticate("supervisor2", "super123")
# Dual authorisation for safety bypass
authorized = await auth.authorize_with_dual_auth(
session1, # First user's session
session2, # Second user's session
PermissionType.SAFETY_BYPASS, # Permission required
resource="reactor_safety_plc_1", # Device being accessed
reason="Planned maintenance" # Justification
)
if authorized:
# Both users authorised - proceed with bypass
await reactor_safety_plc.activate_bypass(authorization=session1)
Requirements:
Both sessions must be valid (not expired)
Both users must have the required permission
Must be two different users (can’t use same session twice)
All attempts are logged to audit trail
Part 2: Testing dual authorisation¶
Step 2.1: Run the dual authorisation demo¶
Execute the demonstration script:
python examples/dual_auth_demo.py
This demonstrates:
Scenario 1: Single user attempt (DENIED - same user twice)
Scenario 2: Two operators (DENIED - insufficient privileges)
Scenario 3: Two supervisors (GRANTED - two-person rule satisfied)
Scenario 4: Supervisor + Admin (GRANTED - role separation)
Watch the Output:
Which attempts succeeded?
Which attempts fail and why?
What gets logged to audit trail?
Step 2.2: Test with Blue Team CLI¶
View active sessions:
python tools/blue_team.py rbac list-sessions
Example output:
Active Sessions (2):
Session: a3b4c5d6...
User: supervisor1
Role: supervisor
Created: 125.3s
Expires: 3725.3s (0.9h remaining)
Session: e7f8g9h0...
User: supervisor2
Role: supervisor
Created: 126.1s
Expires: 3726.1s (0.9h remaining)
Check for:
Who is currently logged in?
When do sessions expire?
Are there any expired sessions?
Step 2.3: Force session logout (emergency)¶
Test session management:
# Logout a specific session
python tools/blue_team.py rbac logout-session a3b4c5d6 \
--reason "Emergency termination during security incident"
Use Cases:
Compromised credentials
User left session open
Testing session timeout handling
Emergency security lockdown
Part 3: Session timeout testing¶
Step 3.1: Understanding session timeouts¶
Session timeouts are configured in config/authentication.yml:
session_timeout_hours: 1 # Sessions expire after 1 hour (simulation time)
Why Timeouts Matter:
Prevent abandoned sessions from being exploited
Force periodic re-authentication
Limit window for session hijacking
Trade-off:
Long timeouts: Convenient, but risky if credentials compromised
Short timeouts: Secure, but disruptive during long operations
Step 3.2: Test session expiry¶
# Start a session
session = await auth.authenticate("supervisor1", "super123")
# Wait for timeout (in simulation)
await asyncio.sleep(3600 * 1.5) # Wait 1.5 hours (simulation time)
# Try to use expired session
authorized = await auth.authorize(
session,
PermissionType.SAFETY_BYPASS,
resource="reactor_1"
)
# Returns False - session expired
Question: What happens if a session expires during a critical operation?
Step 3.3: Handling timeout during dual auth¶
Consider this scenario:
Supervisor1 approves bypass operation
Waiting for Supervisor2 approval
Supervisor1’s session expires while waiting
Supervisor2 approves
Result: Dual auth fails because first session expired.
Solutions:
Session refresh mechanism
Time-limited approval windows
Re-authenticate if needed
Session extension for active operations
Part 4: Implementing dual auth in safety operations¶
Step 4.1: Modify Safety Bypass to Require Dual Auth¶
Current implementation uses single authorisation:
# components/devices/control_zone/safety/base_safety_controller.py
await controller.activate_bypass(authorization=session_id)
To require dual auth, create a wrapper or modify the operation:
# Example: Dual-auth wrapper for safety bypass
async def bypass_with_dual_auth(controller, session1, session2, reason=""):
"""Activate safety bypass with two-person rule."""
from components.security.authentication import (
AuthenticationManager,
PermissionType
)
auth = AuthenticationManager()
# Verify dual authorisation
authorized = await auth.authorize_with_dual_auth(
session1,
session2,
PermissionType.SAFETY_BYPASS,
resource=controller.device_name,
reason=reason
)
if authorized:
# Both users authorised - proceed with bypass
return await controller.activate_bypass(authorization=session1)
else:
print(f"❌ Dual authorisation required for safety bypass on {controller.device_name}")
return False
Step 4.2: Identify critical operations¶
Search for operations that should require dual auth:
# Find safety-related operations
grep -r "bypass\|SCRAM\|shutdown\|emergency" components/devices/control_zone/ | grep "async def"
Candidates:
Safety system bypass (
activate_bypass)Reactor SCRAM operations
Emergency turbine stop
Force mode (override sensors)
Manual trip commands
Decision Criteria:
Is it safety-critical?
Could single insider cause harm?
Is delay acceptable?
Are two qualified people available?
Part 5: Detection over prevention¶
Step 5.1: Monitoring dual auth patterns¶
Even with dual auth, insiders can collude. Detection is essential:
# Find all dual auth attempts
python tools/blue_team.py audit search "DUAL AUTHORISATION"
# Look for suspicious patterns
python tools/blue_team.py audit query --category security --action dual_auth
Red Flags:
Same pair of users always working together
Unusual times (3 AM bypasses)
Rapid succession of critical operations
No maintenance tickets for bypass reasons
Step 5.2: Collusion detection¶
# Export dual auth events for analysis
python tools/blue_team.py audit export --format csv --category security
# Analyse in spreadsheet:
# - Group by user pairs
# - Check frequency of same pairs
# - Look for anomalous timing
Statistical Indicators:
Pair appears > 80% of the time together
Only bypass during off-hours
Bypass frequency doesn’t match maintenance schedule
Step 5.3: Beyond technical controls¶
Technical controls verify:
Two authenticated sessions exist
Both users have permissions
Sessions are from different users
Technical controls CANNOT verify:
❌ Two people are physically present
❌ They aren’t colluding
❌ One isn’t coercing the other
❌ Authorisation is legitimate
Additional Controls:
Video recording of critical operations
Supervisor observation
Random audits
Three-person rule for most critical ops
Time-delayed authorisation (cooling-off period)
Part 6: Balancing security and operations¶
Scenario: Emergency during single-person shift¶
Problem:
Reactor approaching unsafe temperature
Need to bypass safety interlock to activate emergency cooling
Only one supervisor on shift
Two-person rule blocks the operation
Options:
Emergency Override Code:
Sealed envelope with override credentials
Requires breaking seal (evidence of use)
Automatic notification to security/management
Post-incident review required
Remote Approval:
Video call with off-duty supervisor
Verbal approval + session sharing
Risk: Session hijacking if compromised
Temporary Downgrade:
Security admin can temporarily remove dual auth requirement
Requires justification and approval
Automatically re-enabled after incident
Accept the Risk:
Dual auth delays emergency response
But prevents 99% of insider abuse
Trade-off: Safety vs Security
Discussion: What would you do?
Scenario: Shift change during long operation¶
Problem:
Started bypass procedure with Supervisor1 + Supervisor2
Operation takes 2 hours
Shift change at 1 hour mark
Supervisor1 leaves, Supervisor3 arrives
Session timeout approaching
Options:
Session Refresh:
Supervisor1 refreshes session before leaving
Risk: Session remains active after they leave
Re-authorise:
Supervisor3 provides second authorisation
But Supervisor1 already left - need to wait?
Session Handoff:
Transfer authorisation from Supervisor1 to Supervisor3
Technical complexity + audit trail confusion
Complete Before Shift Change:
Require operations to finish within shift
May not be practical for long procedures
Discussion: How would you design session handoff?
Part 7: Advanced dual authorisation¶
Time-delayed authorisation¶
Prevent impulsive or coerced decisions:
async def authorize_with_delay(session1, session2, action, delay_seconds=300):
"""
Require time delay between first and second authorisation.
Prevents:
- Impulsive decisions
- Coercion (victim has time to alert)
- Rushed bypasses during attacks
"""
# Record first authorisation
auth1_time = time.time()
auth1 = await auth.authorize(session1, action)
if not auth1:
return False
# Wait for time delay
await asyncio.sleep(delay_seconds)
# Second authorisation must be after delay
auth2 = await auth.authorize(session2, action)
auth2_time = time.time()
if auth2 and (auth2_time - auth1_time >= delay_seconds):
return True
return False
Benefits:
Cooling-off period
Time to reconsider
Harder to coerce both users quickly
Drawbacks:
Delays genuine emergencies
May be impractical
Three-person rule¶
For most critical operations:
authorized = await auth.authorize_with_multi_auth(
[session1, session2, session3], # Three users required
PermissionType.REACTOR_SHUTDOWN,
resource="reactor_1"
)
When to Use:
Reactor shutdown
Firmware uploads
Safety system configuration changes
Irreversible operations
Role separation¶
Require different roles (not just different users):
async def authorize_with_role_separation(session1, session2, action):
"""Require different roles (e.g., engineer + supervisor)."""
s1 = await auth.get_session(session1)
s2 = await auth.get_session(session2)
# Both must be authorised
if not (await auth.authorize(session1, action) and
await auth.authorize(session2, action)):
return False
# Must have different roles
if s1.user.role != s2.user.role:
return True
return False
Benefits:
Different perspectives
Checks and balances
Harder for single group to collude
Part 8: Testing and validation¶
Test Case 1: Legitimate bypass¶
# Two supervisors perform planned maintenance bypass
session1 = await auth.authenticate("supervisor1", "super123")
session2 = await auth.authenticate("supervisor2", "super123")
authorized = await auth.authorize_with_dual_auth(
session1, session2,
PermissionType.SAFETY_BYPASS,
resource="reactor_safety_plc_1",
reason="Planned maintenance - valve replacement"
)
assert authorized == True # Should succeed
Test Case 2: Single user attempt¶
# Try to use same session twice
authorized = await auth.authorize_with_dual_auth(
session1, session1, # Same session!
PermissionType.SAFETY_BYPASS,
resource="reactor_safety_plc_1"
)
assert authorized == False # Should fail
Test Case 3: Insufficient privileges¶
# Two operators try to bypass
op1 = await auth.authenticate("operator1", "pass123")
op2 = await auth.authenticate("operator2", "pass123")
authorized = await auth.authorize_with_dual_auth(
op1, op2,
PermissionType.SAFETY_BYPASS,
resource="reactor_safety_plc_1"
)
assert authorized == False # Should fail - operators lack permission
Test Case 4: Expired session¶
# First session expires before second authorisation
session1 = await auth.authenticate("supervisor1", "super123")
session2 = await auth.authenticate("supervisor2", "super123")
# Simulate session1 expiring
await asyncio.sleep(timeout_duration + 1)
authorized = await auth.authorize_with_dual_auth(
session1, session2, # session1 is expired
PermissionType.SAFETY_BYPASS,
resource="reactor_safety_plc_1"
)
assert authorized == False # Should fail - expired session
Reflection¶
What you can learn¶
Two-Person Rule:
Requires two different authenticated users
Both must have required permissions
Prevents single insider from abusing access
Cannot prevent collusion
Session Management:
Timeout prevents abandoned session abuse
But complicates long operations
Session refresh vs re-authentication trade-off
Logout required for security incidents
Trade-offs:
Security vs Usability: Two people slower than one
Prevention vs Detection: Can’t prevent all abuse, must detect
Compliance vs Emergency: Procedures may delay critical response
Beyond Technology:
Technical controls verify authentication, not intent
Physical presence cannot be verified remotely
Procedural controls still essential
Audit and detection remain critical
Discussion¶
Emergency Procedures:
How do you handle emergencies when only one qualified person available?
Should there be an override mechanism?
Who authorises the override?
Collusion:
How do you detect two insiders colluding?
Statistical analysis of user pairs?
Behaviour analytics?
Whistleblower mechanisms?
Usability:
Is two-person rule practical for all critical operations?
What operations genuinely need it?
How to reduce false security (security theatre)?
Detection vs Prevention:
Can all abuse be prevented?
When is detection more important?
How fast must you detect?
What’s the response process?
Challenge success criteria¶
You understand the two-person rule concept
You can use dual authorisation API
You can view and manage active sessions
You understand session timeout implications
You can identify critical operations requiring dual auth
You understand detection requirements for collusion
You can balance security and operational needs
Next steps¶
Combine with Other Challenges:
Challenge 3 (Logging): Audit dual auth usage patterns
Challenge 4 (Anomaly Detection): Detect collusion behavioural patterns
Challenge 5 (Protocol Filtering): Layer protocol and auth controls
Integration:
Modify SCRAM operations to require dual auth
Implement emergency override procedures
Deploy time-delayed authorisation for critical ops
Create collusion detection analytics
Implement session handoff for shift changes
References¶
Standards:
ISA 62443-3-3: Security technologies for IACS
ISA 62443-4-2: Technical security requirements for IACS components
NERC CIP-005: Electronic Security Perimeter(s)
Tools:
Blue Team CLI:
python tools/blue_team.py rbac --helpDual Auth Demo:
python examples/dual_auth_demo.pyAuthentication API:
components/security/authentication.py
Further Reading:
Two-Person Integrity (US Nuclear)
Dual Control in Banking Systems
Separation of Duties (SOD) in SAP