
Security News
Another Round of TEA Protocol Spam Floods npm, But It’s Not a Worm
Recent coverage mislabels the latest TEA protocol spam as a worm. Here’s what’s actually happening.
@prisma/extension-policy
Advanced tools
Prisma Policy is a permission rules system for Prisma ORM and Prisma Postgres. With Policy, you can:
At the core of it, you define rules that allow/deny requests to your database based on model name, operation (e.g. findMany) and the parameters you pass to said operation.
A project with Prisma ORM (>=6.2.0) installed and a Prisma Postgres database. If you don’t have one, you can get started here.
The Prisma CLI being authenticated with Prisma Data Platform (via prisma platform auth login --early-access).
npm install @prisma/extension-policy
pnpm add @prisma/extension-policy
yarn add @prisma/extension-policy
bun install @prisma/extension-policy
PrismaClient with the Policy extensionFirst, import the extension and add it to your existing Prisma Client:
import { PrismaClient } from "@prisma/client";
import { withPolicy } from "@prisma/extension-policy";
import { z } from "zod";
import { decode } from "path/to/decode"; // imaginary import of your jwt token decode helper
export const prisma = new PrismaClient().$extends(
withPolicy({
contextSchema: z.object({
token: z.string(),
}),
rules: {
user: {
async read(req) {
// On each request, the context object can be used to perform custom auth/access business logic. We know it's shape thanks to the `contextSchema` property.
const { userId } = await decode(req.context.token);
return {
$where: { id: userId },
};
},
$allOperations: false,
},
$allModels: false,
$transaction: false,
},
}),
);
Note: While the rules are applied to your
PrismaClientinstance, this instance will retain full database access.
This example uses zod, but you can use any schema library that implements the standard schema specification.
This example includes Policy rules that will deny all requests except for reads (e.g. findMany) on user model. It also ensures a user only sees their own data by applying a where override (effectively AND(incoming_query_where, rule_$where)) that filters by the user's id (decoded from the session token).
PolicyClient for your applicationimport { PolicyClient } from "@prisma/extension-policy";
// it is very important to not forget the `type` annotation here, to tell TypeScript to only import the types!!!
import type { prisma as rpcClient } from "path/to/file/where/with-policy/is/used";
export const prisma = new PolicyClient<typeof rpcClient>({
publicKey: "<TBD>",
});
prisma policy deploy <rules_name> -f path/to/file/where/with-policy/is/used
Be sure to copy the public key from the deploy command's output in your terminal, and replace the <TBD> from the previous step.
PolicyClient to access Prisma PostgresPolicyClient is a lightweight version of PrismaClient that you can use in your browser. Once your rules are deployed, you can use it as follows in your application:
import { prisma } from "path/to/policy-client";
prisma.setGlobalContext({ token: "<some_session_token>" });
const users = await prisma.users.findMany();
This package exposes:
A Prisma Client extension called withPolicy that helps attach Prisma Policy-related configuration to an existing Prisma ORM client, making it suitable to act as a Remote Procedure Call (RPC) called object once bundled and deployed to Prisma Policy's workers.
A lightweight Remote Procedure Call (RPC) stub called PolicyClient that allows your application to execute Prisma ORM queries and transactions remotely on Prisma Policy's workers in a secure way (based on your Policy configuration).
The deployment logic is not part of this package, and is accessible via the Prisma CLI through prisma platform policy. A deployment's output will include a public key you'll need to pass to PolicyClient.
Here's a simplified high-level view of Policy's architecture:

Each request, that is received by Policy's workers, will be evaluated by a rule engine:
if a request does not adhere to your rules, it will be denied with a reason, and the PolicyClient will throw an error.
if a request adheres to your rules, it will be executed with the PrismaClient and the results will be sent to the PolicyClient.
Rules are defined with a JavaScript plain nested object.
The root object is defined as:
{
// model name must exist in your `PrismaClient`'s schema.
// when your schema changes, make sure to redeploy your rules,
// to avoid instant denies from the engine for requests that access new models.
[modelName: string]?: ModelRules;
// fallback in case the request's model name has no specific rules.
$allModels?: ModelRules;
// allow or deny transactions.
$transaction?: boolean;
}
Model rules are defined as follows:
type ModelRules =
// simple allow/deny toggle.
| boolean
// more nuanced rules.
| {
// rules for all create operations.
create?: OperationRules;
// rules for all read operations.
read?: OperationRules;
// rules for all update operations.
update?: OperationRules;
// rules for all delete operations.
delete?: OperationRules;
// fallback in case the request's operation group doesn't have specific rules.
$allOperations?: OperationRules;
// will deny requests if at least one of these fields is in the request's
// arguments or is returned by the query. If an operation has specific
// $blockedFields, they will override this property.
// Example: ['password']
$blockedFields?: string[];
};
Operation rules are best described by the following diagram:

It's like an 🧅.
$where overrides the incoming request's filtering by ANDing any existing filters with it.
The callback's req argument is an object that includes the model name, operation, args object, and the global context object.
$rule is a verbose way of defining both an access rule and additional rules/logic for a specific operation:
$before allows running custom code before the query is executed by PrismaClient.
$after allows running custom code after the query is executed by PrismaClient.
$blockedFields behaves similarly to the one that can be defined at the model level, but overrides it if it exists.
Here's a diagram depicting the rule engine's evaluation process in a simplified manner:

The rule engine is designed to introduce as little overhead as possible. As soon as a rule is not adhered by some check, the request is denied. Meaning, it doesn't try and run additional checks to collect more deny reasons.
If you need assistance, reach out in the #help-and-questions channel on our Discord, or connect with our community to see how others are using Policy.
FAQs
Prisma Client extension for Policy
The npm package @prisma/extension-policy receives a total of 40 weekly downloads. As such, @prisma/extension-policy popularity was classified as not popular.
We found that @prisma/extension-policy demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 8 open source maintainers 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
Recent coverage mislabels the latest TEA protocol spam as a worm. Here’s what’s actually happening.

Security News
PyPI adds Trusted Publishing support for GitLab Self-Managed as adoption reaches 25% of uploads

Research
/Security News
A malicious Chrome extension posing as an Ethereum wallet steals seed phrases by encoding them into Sui transactions, enabling full wallet takeover.