Skip to content

Endpoint Plugin

The endpoint plugin is already included in @kilpi/core. Apply the plugin in your Kilpi configuration as follows.

kilpi.ts
export const Kilpi = createKilpi({
getSubject,
policies,
plugins: [EndpointPlugin({ secret: process.env.KILPI_SECRET })]
})

The secret can be included in the client bundle.

Usage

The endpoint plugin exposes the Kilpi.createPostEndpoint() function which constructs a web-standard request-response handler function. You can integrate it with your framework of choice however you want. For example, with Next you would do the followings

app/api/kilpi/route.ts
export const POST = Kilpi.createPostEndpoint();

See this guide for how to set up the client to call the endpoint with utility functions including batching, caching and deduplication, as shown below.

await KilpiClient.fetchIsAuthorized({ key: "documents:delete", resource: myDocument });

API reference

The API is designed for @kilpi/client and is not optimized for calling manually, however it is possible.

Basic fetch example

The following is a basic example of how you can call the endpoint manually. It includes bearer authentication with secret and superJsonStringify for serializing the request body.

import { stringify as superJsonStringify } from "superjson";
const secret = "...";
function callKilpiApiEndpoint(body: RequestBody) {
const respones = await fetch("https://example.com/api/kilpi", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${secret}`,
},
body: superJsonStringify(body),
})
if (!response.ok) throw new Error("Failed to call Kilpi API");
return (await response.json()) as ResponseBody;
}

Request body schema

The request body is serialized with SuperJSON.

For batching purposes, the Kilpi API is always called with an array of items, each one of which has a unique requestId and a type indicating the type of the request.

type RequestBody = Array<
| {
requestId: string;
type: "getIsAuthorized";
// Indicate which policy to evaluate (e.g. "documents:create")
policy: string;
// Optionally provide the resource for evaluating the policy on
resource?: any;
}
| {
requestId: string;
type: "getSubject";
}
>

Response schema

The response is always a corresponding array of items, with each item having a matching requestId and data attribute indicating the response data for that item.

type ResponseBody = Array<{ requestId: string, data: any }>