Skip to content

🔐 feat(auth): add CloudFront signed cookie support#12235

Open
AtefBellaaj wants to merge 1 commit intofeat/cloudfront-cdn-strategy-phase1from
feat/cloudfront-cdn-signed-cookies
Open

🔐 feat(auth): add CloudFront signed cookie support#12235
AtefBellaaj wants to merge 1 commit intofeat/cloudfront-cdn-strategy-phase1from
feat/cloudfront-cdn-signed-cookies

Conversation

@AtefBellaaj
Copy link
Collaborator

@AtefBellaaj AtefBellaaj commented Mar 15, 2026

Summary

Adds CloudFront signed cookie support for secure CDN image delivery. When imageSigning: "cookies" is configured, authentication endpoints automatically set CloudFront signed cookies, allowing browsers to access protected CDN images without per-URL signatures. Cookies are scoped to /images/* and cleared on logout to prevent post-logout CDN access.

This is part of the CloudFront CDN file strategy implementation. Signed cookies are set during login (setAuthTokens, setOpenIDAuthTokens) and cleared on logout. They require a shared parent domain between the API and CloudFront distribution (e.g., API at api.example.com, CDN at cdn.example.com, with cookieDomain: ".example.com").

Key changes:

  • Implement setCloudFrontCookies and clearCloudFrontCookies in packages/api/src/cdn/cloudfront-cookies.ts
  • Scope cookie policy to /images/* (not wildcard) since only images are served via CloudFront cookies
  • Set cookie path: '/images' so browsers only send cookies for image requests
  • Use proper security attributes (secure, httpOnly, sameSite: 'none') on both set and clear operations
  • Validate all 3 expected cookies are returned from AWS SDK before reporting success
  • Integrate cookie setting into both auth token flows (login)
  • Call clearCloudFrontCookies on logout to revoke CDN access (with internal error handling)
  • Add cookieDomain (required for cookies mode, must start with .) and cookieExpiry config options
  • Tighten schema: cookieDomain validated to start with ., cookieExpiry capped at 604800s (7 days)
  • Add Zod validation ensuring cookieDomain is set when imageSigning: "cookies"
  • Return false from initializeCloudFront when imageSigning="cookies" but signing keys are absent
  • Add DEFAULT_COOKIE_EXPIRY fallback const for robustness when Zod defaults are not applied to raw YAML config
  • Clarify urlExpiry in librechat.example.yaml as reserved for future signed-URL mode

Change Type

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update
  • Translation update

Testing

  1. Configure CloudFront with imageSigning: "cookies" and required env vars (CLOUDFRONT_KEY_PAIR_ID, CLOUDFRONT_PRIVATE_KEY)
  2. Set cookieDomain to shared parent domain (must start with ., e.g. .example.com)
  3. Login via standard or OpenID auth
  4. Verify CloudFront-Policy, CloudFront-Signature, and CloudFront-Key-Pair-Id cookies are set with path=/images
  5. Verify CDN image requests to /images/* succeed with cookies
  6. Logout and verify the three CloudFront cookies are cleared with proper security attributes

Unit tests added for:

  • setCloudFrontCookies called during both auth flows
  • setCloudFrontCookies returns false when AWS SDK returns empty or partial cookies
  • setCloudFrontCookies sets cookies with correct security attributes and path
  • clearCloudFrontCookies called on logout with matching security attributes
  • clearCloudFrontCookies handles errors gracefully without failing logout
  • Auth succeeds regardless of cookie function return value
  • Config validation rejects cookieDomain not starting with .
  • Config validation rejects missing cookieDomain when cookies enabled
  • initializeCloudFront returns false when cookies mode lacks signing keys
  • setCloudFrontCookies handles missing cookieExpiry gracefully via DEFAULT_COOKIE_EXPIRY

Checklist

  • My code adheres to this project's style guidelines
  • I have performed a self-review of my own code
  • My changes do not introduce new warnings
  • I have written tests demonstrating that my changes are effective or that my feature works
  • Local unit tests pass with my changes

@AtefBellaaj AtefBellaaj added the ✨ enhancement New feature or request label Mar 15, 2026
@AtefBellaaj AtefBellaaj force-pushed the feat/cloudfront-cdn-signed-cookies branch from 2294f32 to 198cc5d Compare March 15, 2026 14:36
    - Integrate CloudFront signed cookies into authentication flow for secure CDN access.
    - Set cookies on login (setAuthTokens, setOpenIDAuthTokens) when imageSigning="cookies".
    - Clear cookies on logout (clearCloudFrontCookies) to prevent post-logout CDN access.
    - Add cookieDomain and cookieExpiry config options with validation requiring shared parent domain.
    - Tighten schema: cookieDomain requires min(1), leading-dot validation, cookieExpiry capped at 604800s (7 days).
    - Return false from initializeCloudFront when imageSigning="cookies" but signing keys are absent.
    - Refactor cloudfront-cookies.ts: single config read, remove isCloudFrontCookiesEnabled export,
      add DEFAULT_COOKIE_EXPIRY fallback const for robustness against missing Zod defaults.
    - Move cloudfront-cookies.ts from auth/ to cdn/ layer; cookies are CDN access grants, not auth tokens.
    - Fix clearCloudFrontCookies: add httpOnly/secure/sameSite security attributes and try-catch error guard.
    - Add REQUIRED_CF_COOKIES validation: assert all 3 cookies present before setting any; log error on missing key.
    - Scope CloudFront policy resource and cookie path to /images (was /* and /); limits CDN grant to image content.
    - Fix trailing-slash regex to /\/+$/ to handle multiple slashes; upgrade signing failure log to error level.
    - Clarify urlExpiry in librechat.example.yaml as reserved for future signed-URL mode.
@AtefBellaaj AtefBellaaj force-pushed the feat/cloudfront-cdn-signed-cookies branch from 198cc5d to 85ab1b1 Compare March 15, 2026 21:25
@AtefBellaaj AtefBellaaj marked this pull request as ready for review March 15, 2026 21:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨ enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant