Skip to content

Conversation

@birdcar
Copy link

@birdcar birdcar commented Jan 5, 2026

Description

This PR implements AuthKit Sessions support for the PHP SDK, bringing it to parity with the Node, Python, and Ruby sdks.

Documentation

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

[x] Yes

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

@birdcar birdcar self-assigned this Jan 5, 2026
@birdcar birdcar marked this pull request as ready for review January 5, 2026 21:52
@birdcar birdcar requested a review from a team as a code owner January 5, 2026 21:52
@birdcar birdcar requested a review from dandorman January 5, 2026 21:52
@greptile-apps
Copy link
Contributor

greptile-apps bot commented Jan 5, 2026

Greptile Summary

This PR successfully implements AuthKit Sessions support for the PHP SDK, bringing it to parity with Node, Python, and Ruby SDKs. The implementation adds secure cookie-based session management with encrypted session storage using the Paragonie Halite library (libsodium).

Key Changes:

  • Added CookieSession class for managing encrypted session cookies with authenticate, refresh, and logout methods
  • Implemented HaliteSessionEncryption using libsodium with HKDF key derivation and TTL validation
  • Added session management methods to UserManagement: listSessions, revokeSession, sealSession, authenticateWithSessionCookie, loadSealedSession, getSessionFromCookie
  • Created resource models: Session, SessionAuthenticationSuccessResponse, SessionAuthenticationFailureResponse
  • Added comprehensive test coverage including a regression test for the previously reported parameter bug

Bug Fix:

  • Fixed the issue reported in previous review where CookieSession.refresh() was passing only 2 parameters to authenticateWithRefreshToken() instead of the required 5 parameters. A regression test (testRefreshPassesCorrectParametersToAuthenticateWithRefreshToken) was added to prevent this bug from reoccurring.

Security:

  • Uses industry-standard libsodium encryption via Halite
  • Implements proper key derivation with HKDF
  • Session data includes TTL validation to prevent expired session usage
  • No sensitive data logging violations detected
  • Sealed sessions contain access_token and refresh_token which are properly encrypted

Confidence Score: 5/5

  • This PR is safe to merge with high confidence - the implementation is secure, well-tested, and the previously reported bug has been fixed with a regression test
  • Score of 5 reflects: (1) comprehensive test coverage including unit tests and regression tests, (2) secure encryption implementation using industry-standard libsodium, (3) proper key derivation with HKDF, (4) the previously reported parameter bug has been fixed and protected with a regression test, (5) no security violations found against custom rules, (6) clean implementation following existing SDK patterns, (7) proper error handling with typed failure responses
  • No files require special attention - all files show high-quality implementation with proper testing

Important Files Changed

Filename Overview
lib/Session/HaliteSessionEncryption.php Implements secure session encryption with libsodium, HKDF key derivation, and TTL validation
lib/Resource/SessionAuthenticationFailureResponse.php Failure response with typed reasons (NO_SESSION_COOKIE_PROVIDED, INVALID_SESSION_COOKIE, INVALID_JWT)
lib/Resource/SessionAuthenticationSuccessResponse.php Success response with user data, tokens, roles, permissions, and nested resource construction
lib/CookieSession.php Session management class with authenticate, refresh, and logout methods. Previous parameter bug fixed with regression test.
lib/UserManagement.php Added session methods: listSessions, revokeSession, sealSession, authenticateWithSessionCookie, loadSealedSession, getSessionFromCookie

Sequence Diagram

sequenceDiagram
    participant Client
    participant App as PHP Application
    participant CookieSession
    participant UserManagement
    participant Encryption as HaliteSessionEncryption
    participant API as WorkOS API

    Note over Client,API: Initial Authentication & Session Creation
    Client->>App: Login request
    App->>API: authenticateWithPassword/authenticateWithCode
    API-->>App: AuthenticationResponse (access_token, refresh_token)
    App->>UserManagement: sealSession(sessionData, cookiePassword)
    UserManagement->>Encryption: seal(data, password, ttl)
    Encryption->>Encryption: deriveKey(password) via HKDF
    Encryption->>Encryption: encrypt with libsodium
    Encryption-->>UserManagement: sealed session string
    UserManagement-->>App: sealed session
    App->>Client: Set encrypted cookie

    Note over Client,API: Session Authentication
    Client->>App: Request with session cookie
    App->>UserManagement: getSessionFromCookie(cookiePassword)
    UserManagement->>CookieSession: new CookieSession(userMgmt, sealedSession, password)
    App->>CookieSession: authenticate()
    CookieSession->>UserManagement: authenticateWithSessionCookie(sealedSession, password)
    UserManagement->>Encryption: unseal(sealedSession, password)
    Encryption->>Encryption: decrypt with libsodium
    Encryption->>Encryption: validate TTL
    Encryption-->>UserManagement: session data (access_token, refresh_token)
    UserManagement->>API: POST /sessions/authenticate
    API-->>UserManagement: SessionAuthenticationSuccessResponse
    UserManagement-->>CookieSession: Success/Failure response
    CookieSession-->>App: Success/Failure response
    App-->>Client: Authenticated request

    Note over Client,API: Session Refresh
    App->>CookieSession: refresh(options)
    CookieSession->>CookieSession: authenticate() to get current session
    CookieSession->>UserManagement: authenticateWithRefreshToken(clientId, refreshToken, ip, ua, orgId)
    UserManagement->>API: POST /authenticate with refresh_token
    API-->>UserManagement: New access_token & refresh_token
    UserManagement-->>CookieSession: AuthenticationResponse
    CookieSession->>UserManagement: sealSession(newData, newPassword)
    UserManagement->>Encryption: seal(newData, newPassword)
    Encryption-->>UserManagement: new sealed session
    UserManagement-->>CookieSession: new sealed session
    CookieSession-->>App: [SuccessResponse, newSealedSession]
    App->>Client: Update cookie with new sealed session

    Note over Client,API: Session Logout
    App->>CookieSession: getLogoutUrl(returnTo)
    CookieSession->>CookieSession: authenticate() to get sessionId
    CookieSession->>UserManagement: getLogoutUrl(sessionId, returnTo)
    UserManagement-->>CookieSession: logout URL
    CookieSession-->>App: logout URL
    App->>Client: Redirect to logout URL
    Client->>API: GET /sessions/logout
    API-->>Client: Redirect to returnTo URL
Loading

Copy link
Contributor

@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.

11 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

@birdcar
Copy link
Author

birdcar commented Jan 6, 2026

@greptileai

Copy link
Contributor

@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.

11 files reviewed, no comments

Edit Code Review Agent Settings | Greptile

@birdcar birdcar added the enhancement New feature or request label Jan 6, 2026
@birdcar birdcar force-pushed the birdcar/session-implementation branch from 8ea745b to c80a0ed Compare January 6, 2026 23:57
@birdcar birdcar force-pushed the birdcar/session-implementation branch from c80a0ed to 19d649b Compare January 7, 2026 00:11
@birdcar
Copy link
Author

birdcar commented Jan 7, 2026

This doesn't have to wait, but it would likely be beneficial to wait until #316 merges so I can update the new list* methods to use it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Development

Successfully merging this pull request may close these issues.

2 participants