hallpass-client
v0.6.2
Published
Check with hallpass whether a user may do something before your AI agent does it for them.
Maintainers
Readme
hallpass-client
The Node.js and TypeScript client for hallpass: before your AI agent acts for a user, ask the system that owns the resource whether that user may do it.
npm install hallpass-clientIt is on npm. Its version matches the hallpass
release, so in a project pin the one you run (npm install [email protected]). From 0.4.1 on,
the hallpass release workflow publishes it with npm provenance.
It needs a running hallpass server: the ghcr.io/roee-hersh/hallpass image, the Helm chart, or
pip install hallpass and hallpass serve -config hallpass.yaml (hallpass itself is a Python
package; in Python you can also run its engine in-process, with no server). The client has no
dependencies; it uses Node's built-in fetch (Node 18.17 or later). It ships as an ES module with
type declarations. Its source is in
hallpass-ts.
import { AsyncLocalStorage } from "node:async_hooks";
import { Hallpass, guarded } from "hallpass-client";
const hp = new Hallpass(); // HALLPASS_URL and HALLPASS_API_KEY from the environment
const currentUser = new AsyncLocalStorage<string>();
const deleteIssue = guarded(hp, "jira-main", "DELETE_ISSUES", "issue:{key}", { user: currentUser, fresh: true })(
async ({ key }: { key: string }) => {
await jira.deleteIssue(key); // the agent's own credential, only after hallpass said allow
return `deleted ${key}`;
},
);
// per request or session, from your auth:
await currentUser.run(req.user.email, () => generateText({ model, tools, prompt }));- The model never picks the user. It comes from
user: a string, a zero-argument function, or anAsyncLocalStorageyour application enters. Auserkey in the tool's arguments is ignored. - It fails closed.
deny,unknownand hallpass being unreachable all reject withPermissionDeniedbefore the body runs. Passdenyto return a message to the model instead. - One package covers every framework. The wrapped function takes one object of arguments, which is what the Vercel AI SDK, the MCP SDK and most agent frameworks pass to a tool.
Without a wrapper:
const d = await hp.check("[email protected]", "jira-main", "DELETE_ISSUES", "issue:PAY-123");
d.decision, d.reason; // "deny", "denied: ..."
await hp.require(...); // rejects with PermissionDenied unless allowFramework examples: examples/agent-ts. The guide: docs/guides/agent-tools.md.
