Repository navigation
feat(core)!: fail closed on field-level encryption in deployed stages - #663
Open
seanspeaks wants to merge 4 commits into
Open
seanspeaks wants to merge 4 commits into
seanspeaks wants to merge 4 commits into
Conversation
Field-level encryption used to be skipped whenever STAGE was dev, test or local, and silently turned off (with a warning) when no key was configured. `frigg deploy` defaults to --stage dev, so a plain deploy stored credentials in plaintext. The rule now keys off where the code runs, not the stage name, and lives in one place (database/encryption/encryption-config.js) shared by the Prisma client, DocumentDBEncryptionService, the integration-mapping helpers and the encryption health check: - Deployed (in Lambda, not serverless-offline / invoke local / Jest): KMS_KEY_ARN or AES_KEY_ID+AES_KEY encrypts on every stage, dev included. No key throws EncryptionConfigurationError at Prisma client creation, naming the fix, unless FRIGG_ENCRYPTION_DISABLED=true opts out explicitly (warned once per cold start). A configured key wins over the opt-out. - Local (frigg start, tests, scripts): unchanged. dev/test/local skip encryption; other stages encrypt when a key is set. The Prisma client also stops continuing without encryption when the extension fails to initialise. /health/detailed reports a deployed stage without a key as unhealthy and an opt-out as disabled; it no longer reads BYPASS_ENCRYPTION_STAGE, which never switched encryption off. BREAKING CHANGE: a deployed stage with no KMS_KEY_ARN and no AES_KEY_ID/AES_KEY now refuses to start instead of writing plaintext, including stages named dev, test or local. Set encryption.fieldLevelEncryptionMethod: 'kms' (or provide AES keys), or opt out with FRIGG_ENCRYPTION_DISABLED=true. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`encryption: { fieldLevelEncryptionMethod: 'none' }` is the declarative
way to run a deployed stage without field-level encryption now that core
refuses to start without a key. The environment builder turns it into
FRIGG_ENCRYPTION_DISABLED=true on every function, and the SSM offload
blocklist keeps that variable in the Lambda environment, since Prisma
reads it at INIT before SSM values load.
The KMS wiring already ignores the stage name, so an app with
fieldLevelEncryptionMethod: 'kms' deployed with --stage dev gets
KMS_KEY_ARN and encrypts.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Replace the "dev, test and local stages bypass encryption" guidance in CLAUDE.md, the core encryption README, the DocumentDB encryption design note, the frigg and canary skills, the infrastructure README and the website assistant prompt with the deployed/local rule, the explicit opt-out, and the startup error and its fix. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
If your organization's extra usage balance is empty, an organization admin can add extra usage credits at claude.ai/admin-settings/usage. If its monthly spend limit was reached, an admin can raise it on the same page. If neither applies, contact Anthropic support.
Once extra usage is available, comment @claude review on this pull request, or push a new commit, to trigger a review.
✅ Deploy Preview for friggframework-org ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
2 of 4 tasks
|
Open
8 tasks done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Summary
Field-level encryption now fails closed in deployed stages. Frigg used to skip encryption whenever
STAGEwasdev,testorlocal, and it silently wrote plaintext when no key was configured. Becausefrigg deploydefaults to--stage dev, a plain deploy stored OAuth tokens and API keys unencrypted.Encryption now depends on where the code runs, not on the stage name:
FRIGG_ENCRYPTION_DISABLED=true)KMS_KEY_ARNAES_KEY_ID+AES_KEYAES_KEY_IDwithoutAES_KEYEncryptionConfigurationErrorEncryptionConfigurationErrorDeployed means running in AWS Lambda (
AWS_LAMBDA_FUNCTION_NAME,LAMBDA_TASK_ROOTorAWS_EXECUTION_ENV=AWS_Lambda_*) and not under serverless-offline (IS_OFFLINE),serverless invoke local(IS_LOCAL) or Jest. Stage names alone aren't enough, because serverless-offline setsAWS_LAMBDA_FUNCTION_NAMEitself, sofrigg startkeeps working. CloudShell, CodeBuild and ECS count as local, so CLI commands that open a Prisma client in CI aren't affected.Changes
packages/core/database/encryption/encryption-config.jsholds the rule in one place.prisma.js, the DocumentDB encryption service, integration-mapping encryption and the encryption health check all use it; the DocumentDB service previously had its own copy of the stage check.EncryptionConfigurationErrorin the deployed no-key case. The message says what's missing and how to fix it, and the failed client isn't cached. A failed encryption-extension setup now re-throws instead of continuing unencrypted.encryption: { fieldLevelEncryptionMethod: 'none' }in the app definition (new schema enum value) setsFRIGG_ENCRYPTION_DISABLED=true. That variable is kept out of SSM offload, because Prisma reads it before SSM values load./health/detailedreports a deployed stage with no key asunhealthy, and an opt-out asdisabled.BYPASS_ENCRYPTION_STAGEwas only ever read by the health check, and is no longer read.CLAUDE.md, the core encryption README, the DocumentDB encryption doc, the devtools infrastructure README, the frigg and canary skills, and the website assistant's knowledge.Breaking change (for the 2.0.1 release notes, see #660)
A deployed stage with no key refuses to start: database access returns 500 and the logs show
EncryptionConfigurationErrorwith the fix. To fix it, addencryption: { fieldLevelEncryptionMethod: 'kms' }and redeploy (Frigg creates or discovers the key on every stage), provideAES_KEY_IDandAES_KEY, or opt out explicitly. Rows already written in plaintext stay readable and are encrypted the next time they're written.Known limits
fieldLevelEncryptionMethodwithdefault: "aes", which nothing applies. It's left unchanged here.Test plan
encryption-config.test.jsruntime matrix: offline, invoke-local, Jest, script, Lambda, ECS and CloudShell, each with KMS, AES, none and opt-outprisma.encryption.test.js: startup throws and nothing is cached; KMS on dev installs the extension; opt-out warns; offline bypasses; a failed extension setup throwsnext.infrastructure: 89 failures before and after, none new. Schemas 126/126.🤖 Generated with Claude Code
📦 Published PR as canary version:
2.0.0--canary.663.9683f8b.0✨ Test out this PR locally via:
npm install @friggframework/admin-scripts@2.0.0--canary.663.9683f8b.0 npm install @friggframework/core@2.0.0--canary.663.9683f8b.0 npm install @friggframework/devtools@2.0.0--canary.663.9683f8b.0 npm install @friggframework/eslint-config@2.0.0--canary.663.9683f8b.0 npm install @friggframework/prettier-config@2.0.0--canary.663.9683f8b.0 npm install @friggframework/schemas@2.0.0--canary.663.9683f8b.0 npm install @friggframework/serverless-plugin@2.0.0--canary.663.9683f8b.0 npm install @friggframework/test@2.0.0--canary.663.9683f8b.0 npm install @friggframework/ui@2.0.0--canary.663.9683f8b.0 # or yarn add @friggframework/admin-scripts@2.0.0--canary.663.9683f8b.0 yarn add @friggframework/core@2.0.0--canary.663.9683f8b.0 yarn add @friggframework/devtools@2.0.0--canary.663.9683f8b.0 yarn add @friggframework/eslint-config@2.0.0--canary.663.9683f8b.0 yarn add @friggframework/prettier-config@2.0.0--canary.663.9683f8b.0 yarn add @friggframework/schemas@2.0.0--canary.663.9683f8b.0 yarn add @friggframework/serverless-plugin@2.0.0--canary.663.9683f8b.0 yarn add @friggframework/test@2.0.0--canary.663.9683f8b.0 yarn add @friggframework/ui@2.0.0--canary.663.9683f8b.0