A bear playing hopscotch

Announcing our new Node.js Client

Vijay Ramamurthy

We’re excited to announce a new major version of our Node.js client. We’ve been hard at work on this new vision for the Oso SDK, centered around these features:

  • Generate TypeScript types from your Polar policy
  • A simplified Fact Management API
  • A powerful Query Builder API

Generate TypeScript types from your Polar policy

You can generate TypeScript types from your Polar policy to make sure your application code is consistent with your policy code. Use the oso-cloud CLI (>= v0.18.6) to generate the types.

$ oso-cloud generate-types typescript \ 
  path/to/policy.polar > path/to/polarTypes.d.ts

Then import the types and use them in your application.

import type { PolarTypes } from "./polarTypes";

const oso = new Oso<PolarTypes>("https://cloud.osohq.com", YOUR_API_KEY);

const alice = { type: “User”, id: “alice” };
const acme = { type: “Org”, id: “123” };

// Type Error - “reed” ≠ “read” 😦
await oso.authorize(alice, “reed”, acme);
// All good 😌
await oso.authorize(alice, “read”, acme);

Simplified Fact Management API

The new batch API replaces the bulk, bulkDelete, and bulkTell APIs. It adds and removes multiple facts in a single transaction:

const bob = { type: "User", id: "bob" };
await oso.batch((tx) => {
  tx.insert(["has_role", bob, "owner", { type: "Org", id: "acme" }]);
  tx.delete(["has_role", bob, "maintainer", { type: "Repository", id: "anvils" }]);
});

Instead of there being many different formats for inserting and deleting facts, the tx.insert and tx.delete methods you use inside a batch resemble the oso.insert and oso.delete methods you use outside of batch. The delete method also now supports wildcards, so you can do things like remove all of a user’s roles across all resources.

// remove all of bob's roles across all resources
await oso.delete(["has_role", { type: "User", id: "bob" }, null, null]);

Powerful Query Builder API

The Query Builder API enables new patterns like adding filters to an allow query instead of adding custom rules to your policy.

const actor = { type: "User", id: "bob" };
const file = typedVar("File");
const folder = { type: "Folder", id: "folder-1" };

// Query for all the files this user can read...
oso
  .buildQuery(["allow", actor, "read", file])
  // ...within the given folder...
  .and(["has_relation", file, "folder", folder])
  // ...returning a list of authorized File IDs
  .evaluate(file);
// => ["123", "789", ...]

In this example the query returns a list of file IDs because we passed the file variable to evaluate. The evaluate method can also return simple values like booleans and complex structures like maps of lists depending on what you pass into it. It can even return wildcards in cases where a user can perform some action on all resources of a given type. This allows the Query Builder to subsume previous APIs like bulkActions and authorizeResources. See here for how it can support any use case your application demands.

Get started with the v2 Node.js client

You can install the v2 Node.js client on npm: npm install oso-cloud. The full docs are here. If you’re upgrading from v1, check out the Migration Guide.

These changes will be coming to the other language SDKs soon. Let us know if you’re interested in trying RC versions!

Want us to remind you?
We'll email you before the event with a friendly reminder.

Write your first policy