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

@tuent/sentinel

v0.1.7

Published

AI agent behavioral security monitoring SDK

Downloads

905

Readme

@tuent/sentinel

Policy enforcement, behavioral detection, and a signed audit trail for Claude Code. Sentinel enforces your policy on every Claude Code tool call before it runs, watches for behavior that deviates from the agent's norm, and records every decision to a per-project, cryptographically signed trail you can verify end to end.

For teams adopting Claude Code that need enforceable guardrails on what the agent can do, an eye on how it's behaving, and a tamper-evident record they can hand to a reviewer.

What you get

Prevent — policy enforced before execution. Every Claude Code tool call is checked against your .sentinel.yaml and allowed or denied before it runs, not flagged afterward. Out of the box the policy protects credential stores, private keys, cloud configs, and system directories; a network allowlist gates tool-level requests; and repeated violations escalate the agent normal → restricted → quarantined at thresholds you set — one command restores it.

Detect — a behavioral baseline per agent. Sentinel learns each agent's normal pattern of work and surfaces deviations from it in its reports — an anomaly layer on top of the static rules, for the novel behavior a fixed list won't catch. It informs; it doesn't block.

Prove — a signed, verifiable record of every tool call. Every decision — allowed or denied — is appended to a per-project, hash-chained, Ed25519-signed trail anchored by a signed manifest. sentinel --verify-audit re-walks the whole chain and checks every signature, so you can prove after the fact which tool calls ran and which Sentinel stopped. This is the strongest guarantee Sentinel makes: even an action Sentinel can't prevent, it can detect and prove.

Quick start

npm install @tuent/sentinel
npx sentinel init claude-code

init writes a starter .sentinel.yaml to your project, installs the Claude Code hook, and merges a hook entry into your project settings. The gateway daemon auto-starts the next time Claude Code runs — no build step, no separate service to manage. Requires Node.js ≥ 20.

Working with a specific stack? npx sentinel init claude-code --workload=google-workspace (or microsoft-365) starts you from a policy whose network allowlist already includes that stack's API hosts. Workloads differ only in the network allowlist — the file and action rules are identical — so it's a convenient starting policy, not a separate security mode.

In practice

  • A blocked secret read, recorded. The agent tries to read a private key; Sentinel denies it before the read and writes a signed unauthorized_target decision. The agent keeps working — and you have proof it was stopped.
  • A network request held to your allowlist. A tool-level fetch to a host you didn't list is denied, with a message naming allow.networkHosts and how to add it. Add the host and it's allowed — that allow is in the trail too.
  • A deviation surfaced. Once an agent has an established baseline, sentinel --report flags when its current behavior diverges from that norm — a prompt to look, not an automatic block.
  • Verify the record end to end. sentinel --verify-audit --agent=<id> walks the hash chain and checks every Ed25519 signature, reporting each decision as allowed or denied. Hand the output to whoever needs to trust the run.

Policy

.sentinel.yaml is the single policy file init writes. The parts you'll tune:

policy:
  allow:
    actions: [file_read, file_write, tool_invocation, network_request, command_exec]
    targets:            # advisory for file/tool actions — logged if outside, not blocked
      - "src/**"
      - "test/**"
      - "**/*.md"
    networkHosts:       # a tool-level network_request is DENIED unless the host is listed
      - "api.anthropic.com"
      - "github.com"
      - "registry.npmjs.org"
  forbid:
    targets:            # hard deny; the generated policy ships a default floor for credential
      - "secrets/**"    # stores, private keys, cloud configs, and system directories —
      - "/etc/**"       # extend it with your own
enforcement:
  restrictAfter: 3      # restrict the agent after this many policy violations
  quarantineAfter: 5    # quarantine after this many
  • forbid.targets — hard deny; a match blocks the action. The generated policy already protects credential stores, private keys, cloud configs, and system directories; add your own.
  • allow.targetsadvisory for file/tool actions: a read or write outside it is logged as a scope_violation but still runs (Sentinel governs the agent's tool calls; it does not sandbox the filesystem). Make it a hard deny with scopeBoundary: enforce.
  • allow.networkHosts — a tool-level network_request (WebFetch/WebSearch) to an unlisted host is denied. Network made from inside a Bash command (curl, wget) is not gated here by default — see egressScreen.
  • enforcement.* — escalation thresholds plus the opt-in modes below.

Enforcement options

All optional, under enforcement:. Defaults change the agent's behavior as little as possible — the one exception is askOnDestructive, on by default because it restores a confirmation prompt the hook would otherwise suppress.

| Field | Values | Default | What it does | | --- | --- | --- | --- | | restrictAfter / quarantineAfter | integer | 3 / 5 | Escalate normal → restricted → quarantined after this many violations. | | scopeBoundary | advisory | enforce | advisory | enforce denies out-of-scope file reads/writes (file/tool actions; Bash is not scope-checked). | | egressScreen | off | warn | enforce | off | Screens shell network commands against allow.networkHosts; detection-first (logs interpreter/obfuscated egress rather than blocking it). | | askOnDestructive | off | on | on | Routes a curated set of irreversible-destructive shell commands (literal args) to Claude Code's confirmation prompt. | | unknownTools | warn | deny | warn | Disposition for unrecognized tool names. warn allows-and-logs; deny blocks, with allowUnknownTools: [<names>] as the escape hatch. |

What each option does and does not guarantee is detailed in SECURITY_MODEL.md.

Scope & security model

Sentinel is a guardrail with a verifiable record, not a sandbox. What that means precisely:

  • Tamper-evident, not tamper-proof. The trail is hash-chained and signed, so tampering or a deleted entry is detectable and provable — not prevented. The value is proof.
  • Cooperative, at the tool-call boundary. Enforcement happens where Claude Code asks to run a tool, via its hook — not at the OS. It enforces policy on a cooperative agent doing normal work; it is not adversarial containment.
  • Same-host ceiling. Sentinel runs on the same machine as the agent, so a process determined to route around it on that host can (network from inside a Bash one-liner; killing the daemon). That's where the signed trail is the backstop — you can still detect and prove what happened. For prevention against a hostile process, pair Sentinel with OS/network-level isolation.
  • Behavioral detection is observational. The baseline layer surfaces anomalies in reports; it does not block on them. Treat it as a signal to investigate, not an enforcement control.

Full threat model — what's defended, what's out of scope by design, and current limitations — is in SECURITY_MODEL.md.

If something's unexpectedly blocked

  • A network host is blocked. The deny message names allow.networkHosts — add the host there and re-run.
  • A file read or write is blocked or flagged out-of-scope. Check forbid.targets (hard deny) and allow.targets (advisory by default; see scopeBoundary), and widen the relevant list.
  • The agent is restricted or quarantined. Repeated violations escalate it. Restore it with sentinel release --agent=<id> — run it from a separate terminal if the agent's own Bash is blocked.

Turning it off / uninstalling

To turn Sentinel off in a project, remove its hooks:

sentinel disable claude-code

Claude Code then runs without Sentinel. This only removes Sentinel's hook entries from .claude/settings.local.json (your own hooks are preserved); the state in ~/.dahlia (audit trails, signing keys) is left in place — delete it manually for a full cleanup. Re-enable with sentinel init claude-code.

Uninstall in this order. Run sentinel disable claude-code before npm uninstall. If you uninstall the package while the hooks are still wired, Claude Code keeps invoking the now-orphaned hook — and with the gateway gone it fail-closes, blocking high-sensitivity tools (Bash/Write/Edit). The sentinel command is gone at that point, so recover manually: delete the Sentinel hook entries (the ones running node ~/.dahlia/cc-hook.mjs …) from .claude/settings.local.json, and remove ~/.dahlia/cc-hook.mjs.

License

Apache-2.0