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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@kybernesis/arp-pdp

v0.3.0

Published

ARP Policy Decision Point — wraps @cedar-policy/cedar-wasm, adds ARP's @obligation annotation semantics.

Readme

@kybernesis/arp-pdp

Policy Decision Point. Thin wrapper around @cedar-policy/cedar-wasm that adds ARP's @obligation annotation semantics.

Use

import { createPdp } from '@kybernesis/arp-pdp';
import schemaJson from '@kybernesis/arp-spec/cedar-schema.json' with { type: 'json' };

const pdp = createPdp(JSON.stringify(schemaJson));

const decision = pdp.evaluate({
  cedarPolicies: [
    'permit (principal == Agent::"did:web:ghost.agent", action == Action::"read", resource in Project::"alpha");',
  ],
  obligationPolicies: [
    `@obligation("rate_limit")
     @obligation_params({ "max_requests_per_hour": 60 })
     permit (principal, action, resource in Project::"alpha");`,
  ],
  principal: { type: 'Agent', id: 'did:web:ghost.agent' },
  action: 'read',
  resource: {
    type: 'Document',
    id: 'alpha/q2',
    parents: [{ type: 'Project', id: 'alpha' }],
  },
  context: { /* time, spend, vcs, ... */ },
});
// → { decision: 'allow', obligations: [...], policies_fired: [...], reasons: [] }

Decision semantics

Matches ARP-policy-examples.md §10 exactly:

  1. Deny by default.
  2. Any matching permit flips to allow.
  3. Any matching forbid flips back to deny (forbid wins over permit).
  4. On allow, evaluate obligation policies. Each obligation policy that fires contributes { type, params } to the obligation list.

obligationPolicies are not evaluated when the decision is deny.

Obligation annotations

ARP extends Cedar with two annotations:

@obligation("redact_fields")
@obligation_params({ "fields": ["client.name", "client.email"] })
permit (principal == Agent::"did:web:ghost.agent", action == Action::"read", resource in Project::"alpha");

@obligation_params(...) accepts:

  • A JSON-object literal (with bare keys + single-quoted strings tolerated)
  • A JSON string — @obligation_params("{\"fields\":[...]}")

Both forms are stripped before handing the policy to Cedar so the upstream parser never sees the non-standard syntax.

Context value conventions

Cedar's runtime type system is long | boolean | string | set | record — there are no native floats and no native timestamps. The ARP PDP adapts the context.* vocabulary from docs/ARP-policy-examples.md accordingly, and every upstream consumer (scope-catalog compiler, adapters, owner-app consent renderer, reference agents) MUST use the same representations:

| Vocabulary from the doc | On the wire (PDP input + policy body) | |---|---| | quoted_price_usd | quoted_price_cents (integer) | | spend_last_24h_usd | spend_last_24h_cents (integer) | | spend_last_30d_usd | spend_last_30d_cents (integer) | | spend_all_time_usd | spend_all_time_cents (integer) | | time.now | time.now_ms (epoch milliseconds, integer) | | connection.expires_at | connection.expires_at_ms (epoch milliseconds, integer) | | connection.created_at | connection.created_at_ms (epoch milliseconds, integer) |

Money in cents prevents floating-point drift on cap comparisons; epoch milliseconds give us ordered integer comparisons without parsing ISO strings inside Cedar. The doc's narrative float/ISO syntax is illustrative, not normative — Cedar policies compiled by the scope-catalog compiler already follow this convention, and adapters that synthesise ad-hoc policies must follow it too.

If Cedar later adds a decimal or timestamp type, we migrate by rewriting the scope templates and updating this table; the rest of the stack is unchanged because it only ever reads the integer fields.

Design notes

  • Each input policy gets an auto-assigned @id("p_<n>") / @id("o_<n>") if it doesn't already have one; policies_fired returns those IDs.
  • isAuthorized is called without enableRequestValidation in v0. Phase 5 can toggle strict schema enforcement once reference agents' contexts are stable.
  • Cedar WASM must be imported per-call; the library memoises the engine internally, so repeated calls are cheap.