Skip to content

Allow pluggable encryptors for session seal/unseal#432

Merged
gjtorikian merged 1 commit intomainfrom
byo-algo
Feb 4, 2026
Merged

Allow pluggable encryptors for session seal/unseal#432
gjtorikian merged 1 commit intomainfrom
byo-algo

Conversation

@gjtorikian
Copy link
Contributor

Description

Update to #430, this allows users to BYO encryptor for sealed sessions, if they're not using our default of aes_gcm.

@molly-higgins when this PR is merged and released, you should be able to run:

iron_encryptor = MyApp::IronSealUnseal.new  

session = WorkOS::Session.new(                                                                                                                        
    user_management: user_management,                                                                                                                   
    client_id: client_id,                                                                                                                               
    session_data: sealed_cookie,                                                                                                                        
    cookie_password: password,                                                                                                                          
    encryptor: iron_encryptor  # Custom encryptor for Iron/Next.js compatibility                                                                        
  )  

MyApp::IronSealUnseal will need to define its own seal and unseal methods.

Documentation

Does this require changes to the WorkOS Docs? E.g. the API Reference or code snippets need updates.

[ ] Yes

If yes, link a related docs PR and add a docs maintainer as a reviewer. Their approval is required.

@gjtorikian gjtorikian requested a review from a team as a code owner February 4, 2026 18:41
@gjtorikian gjtorikian requested review from ericroberts and removed request for a team February 4, 2026 18:41
@greptile-apps
Copy link

greptile-apps bot commented Feb 4, 2026

Greptile Overview

Greptile Summary

This PR refactors session encryption to support pluggable encryptors, allowing users to bring their own encryption implementation (e.g., Iron seal/unseal for Next.js compatibility).

Key Changes:

  • Extracted AES-256-GCM encryption logic into WorkOS::Encryptors::AesGcm class
  • Added encryptor parameter throughout the session workflow (Session, UserManagement.load_sealed_session, authentication responses)
  • Implemented encryptor validation to ensure custom implementations respond to #seal and #unseal methods
  • Maintained backward compatibility - defaults to AesGcm encryptor when none provided
  • Added comprehensive test coverage for both default and custom encryptors

Architecture:
The refactoring follows a clean plugin pattern where encryption behavior is delegated to interchangeable encryptor objects, while the core session management logic remains unchanged. The Session class now validates encryptors at initialization and passes them through the entire authentication lifecycle.

Confidence Score: 5/5

  • This PR is safe to merge with no concerns
  • The refactoring is well-designed with proper encapsulation, comprehensive test coverage, input validation, and maintains backward compatibility. No security issues or breaking changes detected.
  • No files require special attention

Important Files Changed

Filename Overview
lib/workos/encryptors/aes_gcm.rb Extracted AES-256-GCM encryption logic into a dedicated encryptor class with clean interface
lib/workos/session.rb Refactored to use pluggable encryptors with validation and backward compatibility
lib/workos/authentication_response.rb Updated to pass encryptor parameter through to Session.seal_data
lib/workos/refresh_authentication_response.rb Updated to pass encryptor parameter through to Session.seal_data
spec/lib/workos/encryptors/aes_gcm_spec.rb Comprehensive test coverage for AesGcm encryptor including round-trip, error cases, and IV randomization
spec/lib/workos/session_spec.rb Added tests for custom encryptor support including validation and defaults

Sequence Diagram

sequenceDiagram
    participant User
    participant UserManagement
    participant Session
    participant AuthResponse
    participant Encryptor
    
    Note over User,Encryptor: Authentication Flow with Custom Encryptor
    
    User->>UserManagement: load_sealed_session(encryptor: custom_encryptor)
    UserManagement->>Session: new(encryptor: custom_encryptor)
    Session->>Session: validate_encryptor!(encryptor)
    Note over Session: Validates encryptor responds to #seal and #unseal
    Session->>Session: @encryptor = custom_encryptor || AesGcm.new
    
    User->>Session: authenticate()
    Session->>Encryptor: unseal(session_data, cookie_password)
    Encryptor-->>Session: unsealed session data
    Session->>Session: JWT.decode(access_token)
    Session-->>User: authentication result
    
    User->>Session: refresh()
    Session->>Encryptor: unseal(session_data, cookie_password)
    Encryptor-->>Session: unsealed session data
    Session->>UserManagement: authenticate_with_refresh_token(session: {encryptor: @encryptor})
    UserManagement->>AuthResponse: new(response, session)
    AuthResponse->>Session: seal_data(data, key, encryptor: session[:encryptor])
    Session->>Encryptor: seal(data, key)
    Encryptor-->>Session: sealed session
    Session-->>AuthResponse: sealed_session
    AuthResponse-->>UserManagement: authentication_response
    UserManagement-->>Session: auth_response
    Session-->>User: refresh result with new sealed_session
Loading

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

6 files reviewed, no comments

Edit Code Review Agent Settings | Greptile

@gjtorikian gjtorikian merged commit bcaaff6 into main Feb 4, 2026
4 checks passed
@gjtorikian gjtorikian deleted the byo-algo branch February 4, 2026 19:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants