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

  • Implements AuthKit Sessions support for the PHP SDK to achieve feature parity with Node, Python, and Ruby SDKs
  • Adds comprehensive session management functionality including encrypted cookie storage, authentication, refresh operations, and session lifecycle management
  • Introduces flexible encryption architecture with two implementations: HaliteSessionEncryption using libsodium for maximum security and SigningOnlySessionHandler for performance-critical scenarios

Important Files Changed

Filename Overview
lib/UserManagement.php Core integration of session management capabilities with dependency injection for encryption providers and proper error handling
lib/CookieSession.php New session wrapper class providing authentication, refresh, and logout functionality for encrypted session cookies
lib/Session/HaliteSessionEncryption.php Secure session encryption implementation using libsodium with HKDF key derivation and TTL validation
lib/Session/SigningOnlySessionHandler.php Alternative HMAC-based session signing without encryption for performance-critical environments

Confidence score: 4/5

  • This PR is safe to merge but would benefit from addressing minor implementation issues before production use
  • Score reflects comprehensive testing coverage and well-structured implementation, but lowered due to missing input validation in encryption classes and potential edge cases with base64/JSON parsing
  • Pay close attention to lib/Session/HaliteSessionEncryption.php for input validation improvements and the unused import cleanup

Sequence Diagram

sequenceDiagram
    participant User
    participant App
    participant CookieSession
    participant UserManagement
    participant HaliteSessionEncryption
    participant WorkOSAPI

    User->>App: "Request with session cookie"
    App->>UserManagement: "getSessionFromCookie(cookiePassword)"
    UserManagement->>UserManagement: "Extract cookie from $_COOKIE"
    UserManagement->>UserManagement: "loadSealedSession(sealedSession, cookiePassword)"
    UserManagement->>CookieSession: "new CookieSession(userManagement, sealedSession, cookiePassword)"
    App->>CookieSession: "authenticate()"
    CookieSession->>UserManagement: "authenticateWithSessionCookie(sealedSession, cookiePassword)"
    UserManagement->>HaliteSessionEncryption: "unseal(sealedSession, cookiePassword)"
    HaliteSessionEncryption-->>UserManagement: "sessionData"
    UserManagement->>WorkOSAPI: "POST user_management/sessions/authenticate"
    WorkOSAPI-->>UserManagement: "authentication response"
    UserManagement-->>CookieSession: "SessionAuthenticationSuccessResponse"
    CookieSession-->>App: "authentication result"
    App-->>User: "authenticated response"
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 2 times, most recently 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.

Copy link

@dandorman dandorman left a comment

Choose a reason for hiding this comment

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

This seems good to me, outside of a couple nits. (And i am woefully out of date on my PHP knowledge, so take anything i say with a grain of salt.)

The code looks good, Halite seems like a reasonable choice for an encryption library. I think that is my sole caveat with this PR. It does indeed bring the PHP SDK closer to how the others operate, but that includes the sealed session stuff i think we're hoping to deprecate. Most frameworks provide their own way to encrypt and/or sign cookies, there's little reason for us to add our own layer. Additionally, this creates another island of un-interoperability, where sessions sealed in one platform can't easily be unsealed in another. (cc @cmatheson , who has more thoughts/knowledge on the matter)

Would it be possible to make the sealed-session stuff optional? I don't want to overburden you, but @nicknisi has done some excellent work at paving the way to make session backing more plugin in the JS world.

But if we're not interested in pursuing any of that now, let me know. I don't want to hold this up if we'd rather get parity.

@birdcar
Copy link
Author

birdcar commented Jan 16, 2026

Would it be possible to make the sealed-session stuff optional?

@dandorman everything is possible and "pairity" is only one concern. I'm happy to wait and discuss, I just figured I'd use whatever skills I could to push the SDKs to unity (and, selfishly, I want to be able to use this specific feature in my own projects)

Add paragonie/halite ^4.0 for PHP 7.3+ compatible symmetric encryption.
This library provides libsodium-based encryption for session data.
Add Session resource class for representing user sessions with
properties: id, userId, ipAddress, userAgent, organizationId,
authenticationMethod, status, expiresAt, endedAt, createdAt, updatedAt.
Add SessionAuthenticationFailureResponse with failure reason constants:
- NO_SESSION_COOKIE_PROVIDED
- INVALID_SESSION_COOKIE
- ENCRYPTION_ERROR
- HTTP_ERROR

Add SessionAuthenticationSuccessResponse with full session data including
user, tokens, organization, roles, permissions, entitlements, and impersonator.
Add SessionEncryptionInterface defining seal/unseal contract for
session encryption providers.

Add HaliteSessionEncryption implementing libsodium-based symmetric
encryption with HKDF key derivation and TTL validation. Default
TTL is 30 days to match WorkOS session lifetime.

Include comprehensive tests for encryption, TTL expiration,
wrong password handling, and data integrity.
Add SigningOnlySessionHandler as an alternative to full encryption.
Uses HMAC-SHA256 for integrity verification without encrypting the
payload. Suitable for TLS-only environments where encryption overhead
is undesirable.

Includes version field for future compatibility, TTL validation,
and constant-time signature comparison to prevent timing attacks.
Add session management methods:
- listSessions: List sessions for a user with pagination
- revokeSession: Revoke a specific session
- authenticateWithSessionCookie: Validate sealed session cookies
- loadSealedSession: Create CookieSession from sealed data
- getSessionFromCookie: Extract session from HTTP cookies

Support injectable SessionEncryptionInterface for custom encryption
providers, defaulting to HaliteSessionEncryption.
Add CookieSession for high-level session management:
- authenticate: Validate session and return user data
- refresh: Refresh expired tokens and return raw tokens for re-sealing
- getLogoutUrl: Generate logout URL for the session

Designed to match workos-node CookieSession behavior. Sealing tokens
is the responsibility of the calling code (e.g., authkit-php).
@birdcar birdcar force-pushed the birdcar/session-implementation branch from 4971150 to 36e0279 Compare January 16, 2026 22:28
@birdcar
Copy link
Author

birdcar commented Jan 16, 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.

13 files reviewed, no comments

Edit Code Review Agent Settings | Greptile

Change catch blocks from \Exception to Exception\BaseRequestException
to only catch HTTP-related errors from Client::request(). This prevents
accidentally swallowing unrelated errors like TypeErrors or configuration
issues that should bubble up for debugging.

Addresses review feedback on PR #315.
Copy link

@dandorman dandorman left a comment

Choose a reason for hiding this comment

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

Yeah, i guess it's not worth keeping our PHP friends out in the cold.

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.

3 participants