fix: Decrypt encrypted front component variables - #23494
Conversation
|
👋 Thanks for contributing to Twenty! We're excited to have you on board. Your PR has been set to draft while you work on it. Once you're done, mark it as Ready for review and our automated checks will run. By submitting your Pull Request, you acknowledge that you agree with the terms of our Contributor License Agreement. |
Greptile SummaryFixes front-component application-variable injection by:
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains. Important Files Changed
Reviews (3): Last reviewed commit: "test(server): integ test front comp appl..." | Re-trigger Greptile |
There was a problem hiding this comment.
Pull request overview
This PR fixes front-component application variables (isSecret: false) being injected into the front-component runtime as their encrypted at-rest envelope (enc:v2:...) instead of plaintext, by decrypting eligible values server-side while continuing to omit secret variables.
Changes:
- Pass
SecretEncryptionServiceinto the front-component variable sanitization utility and decrypt non-secret encrypted values before serialization. - Wire
SecretEncryptionModuleinto the front-component Nest module so the resolver can inject the encryption service. - Extend unit tests to cover decryption behavior and ensure secret variables are excluded without attempting decryption.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| packages/twenty-server/src/engine/metadata-modules/front-component/utils/strip-secret-from-application-variables.ts | Adds server-side decryption for non-secret application variable values before injecting them into front-component env. |
| packages/twenty-server/src/engine/metadata-modules/front-component/utils/tests/strip-secret-from-application-variables.spec.ts | Updates and adds tests covering decryption and secret-variable exclusion behavior. |
| packages/twenty-server/src/engine/metadata-modules/front-component/front-component.resolver.ts | Injects SecretEncryptionService and supplies it to the stripping/decryption utility. |
| packages/twenty-server/src/engine/metadata-modules/front-component/front-component.module.ts | Imports SecretEncryptionModule to make encryption services available in the front-component module. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| it('should decrypt non-secret encrypted variables', () => { | ||
| const encryptedValue = 'enc:v2:key-id:payload' as EncryptedString; | ||
|
|
||
| decryptVersionedOrThrow.mockReturnValue('pk.mapbox-token'); | ||
|
|
||
| expect( | ||
| stripSecretFromApplicationVariables( | ||
| [ | ||
| makeFlatVariable({ | ||
| key: 'MAPBOX_PUBLIC_ACCESS_TOKEN', | ||
| value: encryptedValue, | ||
| }), | ||
| ], | ||
| secretEncryptionService, | ||
| ), | ||
| ).toEqual({ MAPBOX_PUBLIC_ACCESS_TOKEN: 'pk.mapbox-token' }); | ||
| expect(decryptVersionedOrThrow).toHaveBeenCalledWith(encryptedValue, { | ||
| workspaceId: '00000000-0000-0000-0000-000000000000', | ||
| }); | ||
| }); | ||
| }); |
| isNonEmptyString(value) && isEncryptedString(value) | ||
| ? secretEncryptionService.decryptVersionedOrThrow(value, { | ||
| workspaceId: flatApplicationVariable.workspaceId, | ||
| }) | ||
| : value; |
|
We don't expose secret variables in front components for security reasons, you can access them via logic-functions https://docs.twenty.com/developers/extend/apps/layout/front-components#application-variables
|
LogDetails |
prastoin
left a comment
There was a problem hiding this comment.
Hey there thanks for reporting, double checking
|
@greptileai review |
🔍 Automated Pre-Review✅ No issues detected - This PR is ready for human review. 🧭 External PR Triage Review✅ Looks good — a maintainer can pick this up. Checks
Detailed findings (duplicate candidates, standards notes, summary) are in the workflow run logs. Automated pre-review — human approval still required. |
|
@prastoin thanks! (I tried to keep the surface of my PR minimal because I'm not too familiar with the code and its conventions.) The refactor looks good. It's kind of baffling that no one—neither users nor maintainers—noticed this feature shipped in a broken state back in v2.10. Anyway, glad it's included in tomorrow's release. |
|
@remihuigen no worries ! reporting is way more than enough
You took the words right out of my mouth |
Weiko
left a comment
There was a problem hiding this comment.
I'd rename the "dangerous" one buildEnvRecordIncludingSecrets or something like that now that you have buildEnvRecord / buildNonSecretEnvRecord? (you can probably find a better name)

Summary
Fixes #23492
Fixes front-component application variables returning their encrypted at-rest value instead of their configured plaintext value.
Non-secret application variables (
isSecret: false) are now decrypted server-side before being injected into the front-component environment. Secret variables remain excluded and are never decrypted or exposed to the browser.Root cause
The front-component resolver filtered secret application variables correctly, but forwarded the cached
encryptedValuedirectly. As a result,getApplicationVariable()returned anenc:v2:...envelope rather than the configured value.Changes
SecretEncryptionModuleto the front-component module.