Skip to content

🌩️ feat: Strict CloudFront signed cookie enforcement via requireSignedAccess#13078

Merged
danny-avila merged 4 commits into
danny-avila:devfrom
upman:cloudfront/require-signed-access
May 12, 2026
Merged

🌩️ feat: Strict CloudFront signed cookie enforcement via requireSignedAccess#13078
danny-avila merged 4 commits into
danny-avila:devfrom
upman:cloudfront/require-signed-access

Conversation

@upman

@upman upman commented May 11, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds an opt-in cloudfront.requireSignedAccess config flag that turns the existing CloudFront signed-cookie support into a hard startup contract. Today the cookie strategy is best-effort: misconfigured deployments silently fall back to public OAC or to broken image delivery. Operators who put CloudFront in front of LibreChat specifically to keep private images private have no way to assert that signing is actually wired up — strict mode closes that gap.

When requireSignedAccess: true:

  • imageSigning must equal "cookies" (signed URL mode is not implemented yet). Enforced both by a Zod refinement on cloudfrontConfigSchema and by a runtime guard in initializeCloudFront, so misconfiguration fails fast with a clear message.
  • Both CLOUDFRONT_KEY_PAIR_ID and CLOUDFRONT_PRIVATE_KEY must be set. Missing either one fails initialization.
  • initializeFileStorage throws on CloudFront init failure to block startup rather than logging and continuing.

When the flag is unset / false, existing OSS behavior is unchanged: missing keys still log-and-continue, and the cookie strategy stays best-effort.

Also adds low-noise logs at startup (strict mode enabled, strict failure reasons) and a single success log on cookie issuance with only path count + expiry seconds — no signed URLs, policies, signatures, private keys, or cookie values are ever logged.

Change Type

  • New feature (non-breaking change which adds functionality)

Testing

Unit-tested via Jest in the affected workspaces. From the repo root:

npm run build:data-provider
(cd packages/data-provider && npx jest src/cloudfront-config.spec.ts)
(cd packages/api && npx jest src/cdn/__tests__/cloudfront.test.ts src/app/__tests__/cdn.test.ts)

New coverage:

  • cloudfront-config.spec.ts: schema rejects requireSignedAccess=true when imageSigning is "none" or "url", accepts it with "cookies" + cookieDomain.
  • cloudfront.test.ts: runtime guard returns false (and logs the strict-failure reason) for missing keys, imageSigning="none", and imageSigning="url"; logs strict-mode-enabled info when configured correctly.
  • cdn.test.ts: initializeFileStorage throws when CloudFront init fails and requireSignedAccess=true; does not throw when false.

Test Configuration:

No special configuration. Tests use jest.mock for the AWS SDK and logger — no live CloudFront, no real keys.

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

upman added 2 commits May 12, 2026 00:37
…cess

Introduces cloudfront.requireSignedAccess (default false). When enabled,
initializeCloudFront requires both CLOUDFRONT_KEY_PAIR_ID and
CLOUDFRONT_PRIVATE_KEY, rejects the unimplemented imageSigning="url"
mode, and initializeFileStorage throws to block startup on any
CloudFront init failure. OSS path is unchanged: missing keys still
log-and-continue when requireSignedAccess is false.

Adds low-noise startup and cookie-issuance logs without leaking signed
URLs, policies, signatures, private keys, or cookie values.
…ookies"

Previously requireSignedAccess=true was accepted with imageSigning="none"
or "url", but setCloudFrontCookies() only runs for "cookies" — leaving
strict mode toothless: CloudFront stayed publicly accessible, or image
delivery broke on a distribution that actually requires signed access.

Adds a Zod refinement plus a runtime guard in initializeCloudFront so
the only currently-functional strict configuration is imageSigning
"cookies". Signed URL mode can lift this restriction once implemented.
@danny-avila

Copy link
Copy Markdown
Owner

@codex review

@danny-avila

Copy link
Copy Markdown
Owner

@upman please resolve failing typescript checks

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🎉

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@danny-avila danny-avila changed the base branch from main to dev May 12, 2026 01:15
@danny-avila

Copy link
Copy Markdown
Owner

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep them coming!

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@danny-avila

Copy link
Copy Markdown
Owner

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Bravo.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@danny-avila danny-avila changed the title 🌩️ feat: Strict CloudFront signed cookie enforcement via requireSignedAccess 🌩️ feat: Strict CloudFront signed cookie enforcement via requireSignedAccess May 12, 2026
@danny-avila danny-avila merged commit 05d4e90 into danny-avila:dev May 12, 2026
15 checks passed
fuuuzzy pushed a commit to fuuuzzy/LibreChat that referenced this pull request May 15, 2026
…edAccess` (danny-avila#13078)

* feat(cloudfront): add requireSignedAccess to enforce strict signed access

Introduces cloudfront.requireSignedAccess (default false). When enabled,
initializeCloudFront requires both CLOUDFRONT_KEY_PAIR_ID and
CLOUDFRONT_PRIVATE_KEY, rejects the unimplemented imageSigning="url"
mode, and initializeFileStorage throws to block startup on any
CloudFront init failure. OSS path is unchanged: missing keys still
log-and-continue when requireSignedAccess is false.

Adds low-noise startup and cookie-issuance logs without leaking signed
URLs, policies, signatures, private keys, or cookie values.

* fix(cloudfront): reject requireSignedAccess unless imageSigning is "cookies"

Previously requireSignedAccess=true was accepted with imageSigning="none"
or "url", but setCloudFrontCookies() only runs for "cookies" — leaving
strict mode toothless: CloudFront stayed publicly accessible, or image
delivery broke on a distribution that actually requires signed access.

Adds a Zod refinement plus a runtime guard in initializeCloudFront so
the only currently-functional strict configuration is imageSigning
"cookies". Signed URL mode can lift this restriction once implemented.

* fix(cloudfront): resolve strict access type checks

* chore(cloudfront): reduce strict startup log noise

---------

Co-authored-by: Danny Avila <danny@librechat.ai>
patricia2510 pushed a commit to lexaeon-org/libre-chat that referenced this pull request May 21, 2026
…edAccess` (danny-avila#13078)

* feat(cloudfront): add requireSignedAccess to enforce strict signed access

Introduces cloudfront.requireSignedAccess (default false). When enabled,
initializeCloudFront requires both CLOUDFRONT_KEY_PAIR_ID and
CLOUDFRONT_PRIVATE_KEY, rejects the unimplemented imageSigning="url"
mode, and initializeFileStorage throws to block startup on any
CloudFront init failure. OSS path is unchanged: missing keys still
log-and-continue when requireSignedAccess is false.

Adds low-noise startup and cookie-issuance logs without leaking signed
URLs, policies, signatures, private keys, or cookie values.

* fix(cloudfront): reject requireSignedAccess unless imageSigning is "cookies"

Previously requireSignedAccess=true was accepted with imageSigning="none"
or "url", but setCloudFrontCookies() only runs for "cookies" — leaving
strict mode toothless: CloudFront stayed publicly accessible, or image
delivery broke on a distribution that actually requires signed access.

Adds a Zod refinement plus a runtime guard in initializeCloudFront so
the only currently-functional strict configuration is imageSigning
"cookies". Signed URL mode can lift this restriction once implemented.

* fix(cloudfront): resolve strict access type checks

* chore(cloudfront): reduce strict startup log noise

---------

Co-authored-by: Danny Avila <danny@librechat.ai>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants