🔥 Introducing Kilpi v1.0 and the new Kilpi API — Read the article

Authorization made simple Turtle Emoji

Kilpi is the open-source TypeScript authorization library designed for developers who need flexible, powerful, and intuitive authorization.

npm install @kilpi/core

Designed and created by Jussi Nevavuori with ❤️ in Brisbane & Helsinki

Too few developers consider authorization.

This leads to technical debt:

Implicit policies, authorization logic scattered all over the codebase, duplicated access control rules, complex if-else statements, authorization logic mixed with business logic, security risks and vulnerabilities, and spending days instead of minutes to change a single access control rule.

This is expensive, stressful and dangerous.

async function deletePost(post: Post) {
const user = await getCurrentUser();
if (!user) {
return Response.redirect("/sign-in", 302);
} else if (
user.role === "admin"
|| user.id === post.userId
|| user.team?.id === post.teamId
) {
await db.posts.deleteById(post.id);
return new Response("Post deleted", { status: 200 });
} else {
return new Response("Forbidden", { status: 403 });
}
}

Wouldn't this be better?

Cheap, stress-free and secure.

A well designed authorization system and explicit policies solve maintainability, security, readability and many more issues caused by ad-hoc authorization.

And Kilpi is the tool for building your authorization system.

async function deletePost(post: Post) {
const { granted } = await Kilpi.posts.delete(post).authorize();
if (granted) {
await db.posts.deleteById(post.id);
}
}

And wait until you learn about .assert() — this becomes even shorter!

What is authorization?

Identify

Authentication


Authentication (not authorization) is asking "Who are you?" to recognize and verify the identity of the subject (the user or even another service or AI agent).

Ask

Enforcement


Authorization and enforcement is asking a question before proceeding, for example

Can Subject User Alice Action Delete the Object Post #7 ?

Answer

Policy


The answers to those questions are based on the policies.

The delete post policy

"A post can be deleted if the user is authenticated and they are either an admin or the author of the post."

Kilpi is built on these concepts.

Authentication

Define your subject by fetching it from any authentication system.

Policy

Define your policies in the simplest way possible — as TypeScript functions.

Enforcement

The universal .authorize() method is all you need.


And there's so much more to make this 10x more powerful! Just wait until you see the <Authorize /> component for example.

export const Kilpi = createKilpi({
// AUTHENTICATION
async getSubject() {
return await getCurrentUser();
},
// POLICY
policies: {
posts: {
async delete(subject, post: Post) {
if (!subject) return Deny();
if (subject.role === "admin") return Grant(subject);
if (subject.id === post.userId) return Grant(subject);
return Deny();
}
}
}
})
// ENFORCEMENT
const { granted } = await Kilpi.posts.delete(post).authorize();
if (granted) { ... }

Your authorization layer with everything your need.

Designed to solve real problems for real applications, Kilpi was born after trying to solve the same problem time after time, in project after project.

Designed for developers

The Kilpi API is designed to be intuitive to read and learn, fast to write and expressive of the developer's intent.

Policies as functions

Not only are policies versionable, but simply functions with the full power of TypeScript.

Works with everything

Kilpi works with any TS / JS runtime, library or framework, any authentication provider.

Authorization components

First-class support for frameworks with plugins that provide hooks and components to authorize your UI.

Flexible authorization model

The Kilpi model can implement DAC, MAC, ABAC, RBAC, ReBAC, EBAC, ROBAC and many more models.

Protected queries

Authorizing reads or redacting data can be a surprisingly complex issue without a good tool such as Kilpi.

Server-first authorization

All authorization decisions are made on the server side, ensuring security and compliance.

Type-safe authorization client

Infer the types and query authorization decisions on the client using a tRPC inspired client.

Extensions with plugins

Extend Kilpi with ready-made or custom plugins to fit your use case.

Type-safety at 100%

Autocomplete everything — Kilpi is designed to the highest TypeScript standards.

High performance

Not only does Kilpi add no overhead, it can even improve your authorization performance.

Battle tested and secure

Production-ready, tested and secure authorization layer trusted in real-world applications.

Fast installation

Install the package and protect your first feature in minutes.

Gradually adoptible

Start using policy by policy, feature by feature.

Open source

Ditch authorization-as-a-service and vendor lock-in — Kilpi is free and open source.

And so much more...

Plugins to fit your use case

Why did I build Kilpi?

🐢 Kilpi [/ˈkilpi/] is the Finnish word for shield.

I've built a lot of applications throughout my career.

And I've built authorization into them time after time.

And I've created half-baked abstractions for authorization way too often trying to refactor countless if statements littered throughout my pages, mutations, queries and UI components.

This has made maintenance troublesome, error-prone and time-consuming, when new features are added or especially when the authorization logic requires changing.

Many gray hairs, bugs, and stressful days later, I went looking for a solution.

But there was no solution right for me.

NPM was coming up dry, believe it or not. The few authorization libraries that exist are either too shallow, old, unmaintained or abandoned.

And all the good solutions are paid authorization-as-a-service products intended for much larger applications, not to mention existing authorization systems such as XACML, which are way too much for most web applications.

Kilpi was my solution to the problem.

I was aiming for a good abstraction and a good developer experience to solve my problems.

What started off as just another abstraction eventually became its own package in the monorepo until it evolved into a fully-fledged library.

Turns out, it's a great solution for this! Not only has it made authorization clearer and better in my applications, it has also allowed to change my authentication provider with minimal authorization logic changes.

Kilpi also helps fight security issues listed in the OWASP 2021 Top 10 Security Risks for Web Applications and CWE 2024 Top 25 Most Dangerous Software Weaknesses reports.

Not only was it fun to build and a joy to use to solve my own problems, I also wrote my master's thesis for Aalto University on Kilpi and authorization in the web.

Jussi Nevavuori
Jussi Nevavuori

Author of Kilpi, full-stack software developer & designer, entrepreneur & MSc. (Tech).

Latest articles

Jussi Nevavuori By Jussi Nevavuori · Sunday, October 12th 2025
View all articles
Buy Me A Coffee

Help support development for the price of a coffee. Read more here .

Ready to get started?

Dive into our comprehensive documentation and start implementing Kilpi in your project today.

Read the Docs

You'll have Kilpi up and running in just minutes!