![PyPI Now Supports iOS and Android Wheels for Mobile Python Development](https://cdn.sanity.io/images/cgdhsj6q/production/96416c872705517a6a65ad9646ce3e7caef623a0-1024x1024.webp?w=400&fit=max&auto=format)
Security News
PyPI Now Supports iOS and Android Wheels for Mobile Python Development
PyPI now supports iOS and Android wheels, making it easier for Python developers to distribute mobile packages.
prisma-field-encryption
Advanced tools
prisma-field-encryption
Transparent field-level encryption at rest for Prisma.
See this Twitter thread for more information.
$ yarn add prisma-field-encryption
# or
$ npm i prisma-field-encryption
import { PrismaClient } from '@prisma/client'
import { fieldEncryptionMiddleware } from 'prisma-field-encryption'
export const client = new PrismaClient()
// This is a function, don't forget to call it:
client.$use(fieldEncryptionMiddleware())
Tip: place the middleware as low as you need cleartext data.
Any middleware registered after field encryption will receive encrypted data for the selected fields.
Generate an encryption key:
$ cloak generate
The preferred method to provide your key is via the PRISMA_FIELD_ENCRYPTION_KEY
environment variable:
# .env
PRISMA_FIELD_ENCRYPTION_KEY=k1.aesgcm256.DbQoar8ZLuUsOHZNyrnjlskInHDYlzF3q6y1KGM7DUM=
You can also pass it directly in the configuration:
client.$use(
fieldEncryptionMiddleware({
// Don't version hardcoded keys though, this is an example:
encryptionKey: 'k1.aesgcm256.DbQoar8ZLuUsOHZNyrnjlskInHDYlzF3q6y1KGM7DUM='
})
)
Tip: a key provided in code will take precedence over a key from the environment.
In your Prisma schema, add /// @encrypted
to the fields you want to encrypt:
model Post {
id Int @id @default(autoincrement())
title String
content String? /// @encrypted <- annotate fields to encrypt
published Boolean @default(false)
author User? @relation(fields: [authorId], references: [id], onDelete: Cascade, onUpdate: Cascade)
authorId Int?
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String? /// @encrypted <- can be optional
posts Post[]
}
Tip: make sure you use a triple-slash. Double slash comments won't work.
$ prisma generate
You're done!
Adding encryption to an existing field is a transparent operation: Prisma will encrypt data on new writes, and decrypt on read when data is encrypted, but your existing data will remain in clear text.
Encrypting existing data should be done in a migration. We will provide tools to help with this in a future update.
Roadmap:
This library is based on @47ng/cloak, which comes with key management built-in. Here are the basic principles:
This allows seamless rotation of the encryption key:
The PRISMA_FIELD_DECRYPTION_KEYS
can contain a comma-separated list of keys
to use for decryption:
PRISMA_FIELD_DECRYPTION_KEYS=key1,key2,key3
Or specify keys programmatically:
prismaClient.$use(
fieldEncryptionMiddleware({
decryptionKeys: [
'k1.aesgcm256.DbQoar8ZLuUsOHZNyrnjlskInHDYlzF3q6y1KGM7DUM='
// Add other keys here. Order does not matter.
]
})
)
Tip: the current encryption key is already part of the decryption keys, no need to add it there.
Key rotation on existing fields (decrypt with old key and re-encrypt with the new one) should be done in a migration.
Roadmap:
You can only encrypt String
fields.
You cannot filter on encrypted fields:
// User.name has an /// @encrypted annotation
// This will always return empty results:
prisma.user.findUnique({ where: { name: 'secret' } })
This is because the encryption is not deterministic: encrypting the same input multiple times will yield different outputs, due to the use of random initialisation vectors. Therefore Prisma cannot match the query to the data.
For the same reason, indexes should not be placed on encrypted fields.
Raw database access operations are not supported.
Adding encryption adds overhead, both in storage space and in time to run queries, though its impact hasn't been measured yet.
The middleware reads the Prisma AST (DMMF) to find annotations (only triple-slash comments make it there) and build a list of encrypted Model.field pairs.
When a query is received, if there's input data to encrypt (write operations), the relevant fields are encrypted. Then the encrypted data is sent to the database.
Data returned from the database is scanned for encrypted fields, and those are attempted to be decrypted. Errors will be logged and any unencrypted data will be passed through, allowing seamless setup.
Some data is sensitive, and it's easy to give read access to the database to a contractor or have backups end up somewhere they shouldn't be.
For those cases, encrypting the data per-field can make sense.
An example use-case is Two Factor authentication TOTP secrets: your app needs them to authenticate your users, but nobody else should have access to them.
Cipher used: AES-GCM with 256 bit keys.
🚨 DO NOT USE THIS TO ENCRYPT PASSWORDS 🚨
Passwords should be hashed & salted using a slow, constant-time one-way function.
Don't reinvent the wheel: use Argon2id if you can, otherwise scrypt.
MIT - Made with ❤️ by François Best
Using this package at work ? Sponsor me to help with support and maintenance.
FAQs
Transparent field-level encryption at rest for Prisma
The npm package prisma-field-encryption receives a total of 14,696 weekly downloads. As such, prisma-field-encryption popularity was classified as popular.
We found that prisma-field-encryption demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
PyPI now supports iOS and Android wheels, making it easier for Python developers to distribute mobile packages.
Security News
Create React App is officially deprecated due to React 19 issues and lack of maintenance—developers should switch to Vite or other modern alternatives.
Security News
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.