Socket
Book a DemoInstallSign in
Socket

kilpi

Package Overview
Dependencies
Maintainers
0
Versions
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install
Package was removed
Sorry, it seems this package was removed from the registry

kilpi

**WARNING: THIS LIBRARY IS IN ALPHA -- A WORK IN PROGRESS -- USAGE AT YOUR OWN RISK**

0.1.0
unpublished
latest
Source
npmnpm
Version published
Weekly downloads
0
Maintainers
0
Weekly downloads
 
Created
Source

WARNING: THIS LIBRARY IS IN ALPHA -- A WORK IN PROGRESS -- USAGE AT YOUR OWN RISK

Until version 1.0.0, the API is subject to breaking changes without a major version bump. This is not meant for production use by external users yet. Rather it is an internal project that is being developed in the open.

Fine-grained authorization

Why do you need fine-grained authorization?

Does your application have organizations which consist of multiple members with different roles optionally across different teams that access multiple projects that may be shared between organizations or external teams or singular members where who can read a document in a project depends on whether it is published or a draft but still application admins should be able access them?

Or do you just have to limit some content to authenticated users only?

Either way, use this as your solid fine-grained authorization framework.

Rolling your own authorization will most likely always end up in a mess of spaghetti, once you realize how complex it is to create a scalable, maintainable, developer-friendly authentication framework that also provides a good user experience. Or even worse, you have complex authorization checks littered across your components, server endpoints, pages, and CSS.

Features

✅ Framework-agnostic (Can be made to work with any stack with plugins)

✅ Authentication-agnostic (Bring your own authentication solution)

✅ Server-first authorization rules (All rules are evaluated on the server as they should be)

✅ Client-only usable

✅ Asynchronous authorization rules (Fetch data while evaluating rule)

✅ Client-side utilities (Queries permission from server with batching and caching)

✅ Protecting queries

✅ Role-based access control (RBAC) support

✅ Attribute-based access control (ABAC) support

✅ Subject narrowing

Opinions

Server-first

All authorization checks are done server first. This is done for several reasons:

  • Security -- you can not trust the client to do authorization checks.
  • Allows for asynchronous rules that fetch data if required.
  • Simpler programming model due to restrictions.
  • Smaller client-bundle as your entire authorization logic stays on the server.

There is nothing stopping you from using this in a client-only application -- but what are you protecting if you don't have a server? Alternatively, to alter the UI client-side you can use the kilpi/client package to query the server for permission to show pieces of UI.

Queries vs Mutations

The project considers different strategies for protecting queries and mutations:

Mutations

For mutations, the project keeps it simple. Whether you are writing HTTP endpoints, tRPC procedures or GraphQL mutations, you can always just call await Kilpi.protect(...) to protect your mutation.

Queries

For queries, we provide the const myQuery = Kilpi.createQuery(queryFn, protectorFn) wrapper function. It ensures that no matter where you access your data, you can always be confident that no data ever leaks. This is due to it exposing three functions:

  • myQuery() for accessing the queryFn() directly as-is, when you need the data but it won't be exposed to the user (e.g. in a mutation).
  • myQuery.safe() for accessing the data or returning null for unauthorized.
  • myQuery.protect() for accessing the data or throwing for unauthorized. You can throw a redirect, unauthorized / forbidden error, or a plain error - define your own behaviour with e.g. Kilpi.onProtect(() => redirect(...)) on a per-page level.

This way, when creating a page, you don't have to remember every piece of data the page will access and attempt to protect each query separately.

// Before
function DashboardPage(params) {
  await protect("user:read", params.userId)
	const user = await getUser();
	let documents = await getUserDocuments();
	try {
		await Promise.all(documents.map(doc => protect("document:read", doc)))
	} catch {
		// Unauhtorized to read some document
		documents = [];
	}
}

// After
function DashboardPage(params) {
	const user = await getUser.protect();
	const documents = await getUserDocuments.safe() ?? [];
}

Rules-as-code

Defining the rules have been left as an exercise to the reader. Whether you check the user's permissions, membership, subscription, role, authentication status or date of birth, rules allow to compose any custom logic to permit operations.

Supported scenarios

✅ Authenticated vs. non-authenticated users

✅ Freemium vs. Premium users

✅ Role-based access control in organizations

✅ And much more complicated scenarios...

Supported frameworks

✅ React

✅ Next.js

Todo

Better plugin system

  • Server and Client plugins
  • Improved plugin API
  • Pass Kilpi instance and types to plugins automatically (client must be created separately first)
  • React-client and React-server to plugins (Server and client plugins respectively)

Smarter queries

  • React-query like query cache
  • Client-side fetch permission dedpuing

Open-source

  • Contributing guide
  • Documentation (See below)
  • Tests
  • Publish to NPM
  • CI/CD to npm

In-place rules

// In-place rules API for one-off rules
await Kilpi.protect(
	(Rule) => (
		Rule
			.subject(subject => subject ? subject : false) // Ensure subject exists
			.create<Booking>((subject, booking) => {
				return subject.user.id === booking.userId
			})
	),
	myBooking
)

// Instead of (for one-offs)
await Kilpi.protect("Bookings:read", myBooking) 

Documentation

  • Usage
    • Setup server
    • Setup client
  • Writing rules
    • Two patterns
      • Provide full resource to rule.
      • Provide resource ID to rule and fetch during check.
    • Authed vs Public
    • Freemium vs Premium
    • Organization RBAC
    • Complex organization ABAC document access
  • Opinions
  • React / Next.js usage
    • Server-side usages
      • Page
      • Component
        • Hide component / Show alt state
      • Query
      • Mutation
    • Client-side usages
      • Hide component / Show alt state
  • Writing new plugins
    • Server
    • Client

Install

  • Clone repo.
  • Install dependencies with bun install.
  • Run tests with bun test.
  • Build with bun run build (or bun run watch:build).

License

MIT

Keywords

bun

FAQs

Package last updated on 09 Jan 2025

Did you know?

Socket

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.

Install

Related posts

SocketSocket SOC 2 Logo

Product

About

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.

  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc

U.S. Patent No. 12,346,443 & 12,314,394. Other pending.