npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@styra/opa

v0.4.2

Published

The Styra-supported driver to connect to Open Policy Agent (OPA) and Enterprise OPA deployments.

Downloads

719

Readme

OPA Typescript SDK

The Styra-supported driver to connect to Open Policy Agent (OPA) and Enterprise OPA deployments.

License NPM Version

The documentation for this SDK lives at https://docs.styra.com/sdk, with reference documentation available at https://styrainc.github.io/opa-typescript

You can use the Styra OPA SDK to connect to Open Policy Agent and Enterprise OPA deployments.

SDK Installation

NPM

npm add @styra/opa

Yarn

yarn add @styra/opa

Requirements

For supported JavaScript runtimes, please consult RUNTIMES.md.

SDK Example Usage (high-level)

All the code examples that follow assume that the high-level SDK module has been imported, and that an OPA instance was created:

import { OPAClient } from "@styra/opa";

const serverURL = "http://opa-host:8181";
const path = "authz/allow";
const opa = new OPAClient(serverURL);

Simple query

For a simple boolean response without input, use the SDK as follows:

const allowed = await opa.evaluate(path);
console.log(allowed ? "allowed!" : "denied!");

Note that allowed will be of type any. You can change that by providing type parameters to evaluate:

const allowed = await opa.evaluate<never, boolean>(path);

The first parameter is the type of input passed into evaluate; we don't have any in this example, so you can use anything for it (any, unknown, or never).

POST /v1/data/authz/allow
Content-Type: application/json

{}

Input

Input is provided as a second (optional) argument to evaluate:

const input = { user: "alice" };
const allowed = await opa.evaluate(path, input);
console.log(allowed ? "allowed!" : "denied!");

For providing types, use

interface myInput {
  user: string;
}
const input: myInput = { user: "alice" };
const allowed = await opa.evaluate<myInput, boolean>(path, input);
console.log(allowed ? "allowed!" : "denied!");
POST /v1/data/authz/allow
Content-Type: application/json

{ "input": { "user": "alice" } }

Result Types

When the result of the policy evaluation is more complex, you can pass its type to evaluate and get a typed result:

interface myInput {
  user: string;
}
interface myResult {
  authorized: boolean;
  details: string[];
}
const input: myInput = { user: "alice" };
const result = await opa.evaluate<myInput, myResult>(path, input);
console.log(result.evaluated ? "allowed!" : "denied!");

Input Transformations

If you pass in an arbitrary object as input, it'll be stringified (JSON.stringify):

class A {
  // With these names, JSON.stringify() returns the right thing.
  name: string;
  list: any[];

  constructor(name: string, list: any[]) {
    this.name = name;
    this.list = list;
  }
}
const inp = new A("alice", [1, 2, true]);
const allowed = await opa.evaluate<myInput, boolean>(path, inp);
console.log(allowed ? "allowed!" : "denied!");

You can control the input that's constructed from an object by implementing ToInput:

class A implements ToInput {
  // With these names, JSON.stringify() doesn't return the right thing.
  private n: string;
  private l: any[];

  constructor(name: string, list: any[]) {
    this.n = name;
    this.l = list;
  }

  toInput(): Input {
    return { name: this.n, list: this.l };
  }
}
const inp = new A("alice", [1, 2, true]);
const allowed = await opa.evaluate<myInput, boolean>(path, inp);
console.log(allowed ? "allowed!" : "denied!");
POST /v1/data/authz/allow
Content-Type: application/json

{ "input": { "name": "alice", "list": [ 1, 2, true ] } }

Result Transformations

If the result format of the policy evaluation does not match what you want it to be, you can provide a third argument, a function that transforms the API result.

Assuming that the policy evaluates to

{
  "allowed": true,
  "details": ["property-a is OK", "property-B is OK"]
}

you can turn it into a boolean result like this:

const allowed = await opa.evaluate<any, boolean>(
  path,
  undefined,
  (r?: Result) => (r as Record<string, any>)["allowed"] ?? false,
);
console.log(allowed ? "allowed!" : "denied!");

Example Projects

Express

In the StyraInc/styra-demo-tickethub repository, you'll find a NodeJS backend service that is using @styra/opa:

router.get("/tickets/:id", [param("id").isInt().toInt()], async (req, res) => {
  const {
    params: { id },
  } = req;
  await authz.evaluated(path, { action: "get", id }, req);

  const ticket = await prisma.tickets.findUniqueOrThrow({
    where: { id },
    ...includeCustomers,
  });
  return res.status(OK).json(toTicket(ticket));
});

NestJS

In StyraInc/opa-typescript-example-nestjs, we have an decorator-based API authorization example using @styra/opa:

@Controller('cats')
@AuthzQuery('cats/allow')
@AuthzStatic({ resource: 'cat' })
export class CatsController {
  constructor(private catsService: CatsService) {}

  @Post()
  @Authz(({ body: { name } }) => ({ name, action: 'create' }))
  async create(@Body() createCatDto: CreateCatDto) {
    this.catsService.create(createCatDto);
  }

  @Get(':name')
  @AuthzQuery('cats') // For illustration, we're querying the package extent
  @Decision((r) => r.allow)
  @Authz(({ params: { name } }) => ({
    name,
    action: 'get',
  }))
  async findByName(@Param('name') name: string): Promise<Cat> {
    return this.catsService.findByName(name);
  }
}

Please refer to the repository's README.md for more details.

Note: For low-level SDK usage, see the sections below.


OPA OpenAPI SDK (low-level)

Available Resources and Operations

OpaApiClient SDK

Development

Maturity

This SDK is in beta, and there may be breaking changes between versions without a major version update. Therefore, we recommend pinning usage to a specific package version. This way, you can install the same version each time without breaking changes unless you are intentionally looking for the latest version.