@tuent/sentinel 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -26
- package/SECURITY_MODEL.md +231 -0
- package/dist/Sentinel-QHMQ67W3.js +10 -0
- package/dist/chunk-B5QKJHSV.js +32 -0
- package/dist/{chunk-Z3PWIJKT.js → chunk-IYC5E7RL.js} +99 -422
- package/dist/{chunk-CUJKNIKT.js → chunk-LATQNIRW.js} +33 -1
- package/dist/{chunk-QFRDEISP.js → chunk-NS6ZLMDK.js} +6 -6
- package/dist/{chunk-6MHWJATS.js → chunk-QHE56MEO.js} +510 -18
- package/dist/{chunk-3U3PKD4N.js → chunk-WPTJBRX5.js} +2 -2
- package/dist/cli.js +30 -30
- package/dist/gateway/index.d.ts +14 -0
- package/dist/gateway/index.js +3 -2
- package/dist/gatewayDaemon.js +3 -2
- package/dist/index.js +4 -4
- package/dist/pidManager-DOGVN6ZT.js +23 -0
- package/package.json +3 -2
- package/dist/Sentinel-JLQL3YRD.js +0 -10
- package/dist/pidManager-ZYC7SICM.js +0 -15
package/README.md
CHANGED
|
@@ -1,19 +1,24 @@
|
|
|
1
1
|
# @tuent/sentinel
|
|
2
2
|
|
|
3
|
-
Runtime security for Claude Code
|
|
3
|
+
**Runtime security for Claude Code.** Sentinel checks your policy on every Claude Code tool call — _before_ it runs — and writes every decision to a signed, tamper-evident audit trail. Install it, point it at your project, and Claude Code operates inside guardrails you control.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Sentinel is purpose-built for Claude Code. Rather than loosely wrapping a general-purpose "agent platform," it hooks Claude Code's own tool-call lifecycle directly — enforcement happens at the exact point where the agent decides to act.
|
|
6
|
+
|
|
7
|
+
## What you get
|
|
8
|
+
|
|
9
|
+
- **Enforcement before execution** — every tool call is evaluated against your policy and allowed or denied before it runs, not flagged after the fact.
|
|
10
|
+
- **A signed audit trail** — every decision appended to a hash-chained, Ed25519-signed trail anchored by a signed manifest, verifiable end to end.
|
|
11
|
+
- **Automatic escalation** — repeated violations move the agent normal → restricted → quarantined at thresholds you set, and one command restores it.
|
|
12
|
+
- **Behavioral baseline** — a per-workspace baseline surfaces deviation signals as advisory context.
|
|
6
13
|
|
|
7
14
|
## How it works
|
|
8
15
|
|
|
9
|
-
`init` installs a hook into Claude Code's PreToolUse lifecycle. Each tool call is routed to a local gateway daemon, evaluated against your policy, and allowed or denied before execution
|
|
16
|
+
`init` installs a hook into Claude Code's PreToolUse lifecycle. Each tool call is routed to a local gateway daemon, evaluated against your policy, and allowed or denied before execution — then recorded to the signed trail.
|
|
10
17
|
|
|
11
18
|
```
|
|
12
19
|
Claude Code tool call → PreToolUse hook → gateway daemon → policy decision → signed audit
|
|
13
20
|
```
|
|
14
21
|
|
|
15
|
-
Enforcement is cooperative: it depends on Claude Code invoking the hook. Sentinel is not a sandbox and does not contain a hostile agent that bypasses the hook.
|
|
16
|
-
|
|
17
22
|
## Install
|
|
18
23
|
|
|
19
24
|
```sh
|
|
@@ -21,9 +26,7 @@ npm install @tuent/sentinel
|
|
|
21
26
|
npx sentinel init claude-code
|
|
22
27
|
```
|
|
23
28
|
|
|
24
|
-
`init` writes a `.sentinel.yaml` policy into your project, sets up the gateway hook, and merges a hook entry into `.claude/settings.local.json`. No
|
|
25
|
-
|
|
26
|
-
Requires Node.js ≥ 20. ESM-only.
|
|
29
|
+
`init` writes a `.sentinel.yaml` policy into your project, sets up the gateway hook, and merges a hook entry into `.claude/settings.local.json`. No build step — the gateway ships as a runnable daemon. Requires Node.js ≥ 20 (ESM-only).
|
|
27
30
|
|
|
28
31
|
## Policy
|
|
29
32
|
|
|
@@ -64,32 +67,25 @@ As policy violations accumulate, the agent escalates through modes: normal → r
|
|
|
64
67
|
|
|
65
68
|
## Audit trail
|
|
66
69
|
|
|
67
|
-
Every decision is appended to a hash-chained trail and signed with Ed25519, anchored by a signed manifest.
|
|
70
|
+
Every decision is appended to a hash-chained trail and signed with Ed25519, anchored by a signed manifest. Run `sentinel --verify-audit` to validate the chain and every entry signature.
|
|
68
71
|
|
|
69
|
-
|
|
72
|
+
## Behavioral analytics
|
|
70
73
|
|
|
71
|
-
|
|
72
|
-
- Signature determinism currently relies on V8's JSON key ordering. Verifying on another engine (Bun, Deno) is not yet supported and may report false invalids.
|
|
73
|
-
- The trail is stored in plaintext. It is tamper-evident, not tamper-proof: a compromised same-host process can alter it, and the signed manifest is designed to detect that, not prevent it.
|
|
74
|
+
Sentinel maintains a per-workspace behavioral baseline and surfaces session-level deviation signals as advisory context. These are observational and do not block tool calls; the richer signals require a matured workspace baseline.
|
|
74
75
|
|
|
75
|
-
##
|
|
76
|
+
## If a tool call is unexpectedly blocked
|
|
76
77
|
|
|
77
|
-
Sentinel
|
|
78
|
+
Sentinel matches forbidden targets conservatively, which can occasionally deny a benign command that only _references_ a sensitive filename — for example, searching your code with `grep` for `.env`. Plain mentions under safe commands (`echo`, comments) pass through. If a false positive restricts or quarantines the agent, restore it in one step:
|
|
78
79
|
|
|
79
|
-
|
|
80
|
+
```sh
|
|
81
|
+
sentinel release
|
|
82
|
+
```
|
|
80
83
|
|
|
81
|
-
|
|
82
|
-
- In log-adapter mode it does not block in real time (it observes, with latency).
|
|
83
|
-
- It does not prevent log tampering by a compromised same-host process.
|
|
84
|
-
- It does not detect encrypted or obfuscated exfiltration.
|
|
85
|
-
- It does not defend against multi-agent coordinated activity.
|
|
86
|
-
- It does not resolve symlinks in target paths.
|
|
87
|
-
- Workspace identity is a non-cryptographic 32-bit hash. It distinguishes local workspaces; it is not collision-resistant.
|
|
84
|
+
This records the change in the audit trail. Don't edit the mode state file by hand — that desyncs the trail from the live state.
|
|
88
85
|
|
|
89
|
-
##
|
|
86
|
+
## Security model
|
|
90
87
|
|
|
91
|
-
-
|
|
92
|
-
- On a cold start, the first tool call of a fresh session waits up to ~5 seconds for the daemon to warm up. If it is not ready, Sentinel applies its tiered fallback: high-sensitivity tools are denied, lower-sensitivity tools are allowed through.
|
|
88
|
+
Sentinel's enforcement is **cooperative** — it works by intercepting Claude Code's tool-call hook — and the audit trail is **tamper-evident**, not tamper-proof. For the full threat model — what Sentinel defends against, what's out of scope by design, and current v0.1.0 limitations — see [SECURITY_MODEL.md](./SECURITY_MODEL.md).
|
|
93
89
|
|
|
94
90
|
## License
|
|
95
91
|
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
# Sentinel Security Model
|
|
2
|
+
|
|
3
|
+
## What Sentinel Protects Against
|
|
4
|
+
|
|
5
|
+
### Pre-Execution Enforcement
|
|
6
|
+
|
|
7
|
+
When using `wrap()` or `wrapTool()`, Sentinel validates every action before the agent executes it. HIGH and CRITICAL severity actions are blocked -- the agent's execution function never runs. The dangerous file is never read, the unauthorized API is never called, the forbidden command is never executed.
|
|
8
|
+
|
|
9
|
+
This is the strongest integration mode. The agent code passes its intended action and an execute function to Sentinel. If the action violates the role definition or targets a high-sensitivity resource, Sentinel returns `{ blocked: true }` and the execute function is never invoked. LOW and MEDIUM findings are informational -- the action still executes, and the finding is returned alongside the result for logging.
|
|
10
|
+
|
|
11
|
+
### Role Violations
|
|
12
|
+
|
|
13
|
+
Agents are bound to a defined set of allowed actions. If an agent with `allowedActions: ["file_read", "file_write"]` attempts a `command_exec` or `database_query`, Sentinel produces a **HIGH** `role_violation` finding immediately.
|
|
14
|
+
|
|
15
|
+
### Unauthorized Target Access
|
|
16
|
+
|
|
17
|
+
Targets are checked against glob patterns in two layers:
|
|
18
|
+
|
|
19
|
+
1. **Forbidden patterns** (checked first) -- any match produces a **HIGH** `unauthorized_target`
|
|
20
|
+
2. **Allowed patterns** (checked second) -- access outside allowed scope produces a **MEDIUM** `scope_violation`
|
|
21
|
+
|
|
22
|
+
Pattern matching uses `**` (any path) and `*` (single segment). Examples:
|
|
23
|
+
|
|
24
|
+
- `**/.env` matches `.env` at any depth
|
|
25
|
+
- `**/.ssh/**` matches anything inside any `.ssh` directory
|
|
26
|
+
- `src/**` matches all files under `src/`
|
|
27
|
+
|
|
28
|
+
### Behavioral Anomalies
|
|
29
|
+
|
|
30
|
+
After a baseline is computed from historical sessions, the DeviationDetector checks every new session for:
|
|
31
|
+
|
|
32
|
+
- **Volume spikes** -- event count exceeds 3x the baseline average
|
|
33
|
+
- **Unusual targets** -- more than 50% of accessed files are outside the agent's typical target set
|
|
34
|
+
- **Weight anomaly** -- session engagement exceeds baseline normal range + 0.3 threshold
|
|
35
|
+
- **Category shifts** -- activity type represents less than 5% of baseline behavior
|
|
36
|
+
- **Activity drops** -- session event count drops 75%+ below baseline average (possible log suppression)
|
|
37
|
+
- **Activity gaps** -- agent silence exceeds 2-3x the longest observed gap in the baseline period
|
|
38
|
+
- **Convergence escalation** -- when 3+ MEDIUM findings occur in one session, the first is escalated to HIGH
|
|
39
|
+
|
|
40
|
+
### High-Sensitivity Target Access
|
|
41
|
+
|
|
42
|
+
The TargetSensitivityScorer assigns risk scores (0.0-1.0) to every target based on built-in pattern rules. Scores are multiplied by action type (writes are 1.3x, command execution is 1.5x). When the effective score reaches 0.9+, findings are escalated to **CRITICAL**.
|
|
43
|
+
|
|
44
|
+
Built-in sensitivity categories:
|
|
45
|
+
|
|
46
|
+
- **Credentials** (1.0): `.ssh/`, `.env`, `.aws/`, `secrets/`, `id_rsa*`, `.pem`, `shadow`
|
|
47
|
+
- **System** (0.7-0.9): `/etc/`, `passwd`
|
|
48
|
+
- **PII** (0.8-0.85): `users/`, `customers/`, `payments/`
|
|
49
|
+
- **Database** (0.75-0.8): `database/`, `.sqlite`, `.db`
|
|
50
|
+
- **Config** (0.5-0.75): `config/`, `config/production*`
|
|
51
|
+
- **Source** (0.1-0.45): `src/`, `tests/`, `docs/`, `.git/`
|
|
52
|
+
- **Default** (0.15): anything not matching a specific rule
|
|
53
|
+
|
|
54
|
+
Custom rules can be injected via the `TargetSensitivityScorer` constructor, overriding built-in patterns.
|
|
55
|
+
|
|
56
|
+
### Temporal Anomalies
|
|
57
|
+
|
|
58
|
+
Agents can have an `expectedSchedule` with allowed days and hours (UTC). Activity outside the schedule produces a **MEDIUM** `temporal_anomaly`. The DeviationDetector independently checks against the baseline's typical active hours and days.
|
|
59
|
+
|
|
60
|
+
### Path Traversal Attempts
|
|
61
|
+
|
|
62
|
+
All target paths are normalized with `path.normalize()` before pattern matching. This resolves `../` and `./` sequences, preventing bypass attempts like:
|
|
63
|
+
|
|
64
|
+
- `src/../.env` is normalized to `.env` before checking against `**/.env`
|
|
65
|
+
- `project/subdir/../../.ssh/id_rsa` is normalized to `.ssh/id_rsa`
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## What Sentinel Does NOT Protect Against
|
|
70
|
+
|
|
71
|
+
### Prompt Injection
|
|
72
|
+
|
|
73
|
+
Sentinel monitors agent **actions**, not agent **prompts**. It cannot detect or prevent prompt injection attacks directly. However, if a prompt injection causes an agent to perform a forbidden action (e.g., reading `.env`), that action **will** be caught by role validation.
|
|
74
|
+
|
|
75
|
+
### Real-Time Blocking in Log Adapter Mode
|
|
76
|
+
|
|
77
|
+
When using the LogAdapter (file-tailing mode), events are detected after they occur with a polling delay (default ~2 seconds). This mode is observation-only -- it cannot block actions.
|
|
78
|
+
|
|
79
|
+
For real-time pre-execution enforcement, use one of:
|
|
80
|
+
|
|
81
|
+
- **`sentinel.wrap()` / `sentinel.wrapTool()`** (recommended) -- synchronous enforcement, actions blocked before execution
|
|
82
|
+
- **`sentinel.check()`** -- manual pre-execution gate in your agent orchestrator
|
|
83
|
+
- **WebhookReceiver** in synchronous mode (agent sends event before executing)
|
|
84
|
+
|
|
85
|
+
### Log Tampering by Compromised Agents
|
|
86
|
+
|
|
87
|
+
If an AI agent and Sentinel run on the same host and the agent has write access to the filesystem, a compromised agent could theoretically modify its own log files or audit trail. **Mitigation:** Run Sentinel on a separate host and ingest events via the webhook adapter.
|
|
88
|
+
|
|
89
|
+
### Encrypted or Obfuscated Data Exfiltration
|
|
90
|
+
|
|
91
|
+
Sentinel sees which targets an agent accesses and what actions it performs. It does not inspect the content of data being read or transmitted. An agent reading a sensitive file and encoding its contents into an innocuous-looking API call would be partially detected (the file read is logged) but the exfiltration channel may not be flagged.
|
|
92
|
+
|
|
93
|
+
### Multi-Agent Coordinated Attacks
|
|
94
|
+
|
|
95
|
+
Each agent is monitored independently by default. The `CorrelationDetector` provides basic cross-agent pattern detection (e.g., read-then-exfiltrate chains), but sophisticated coordinated attacks where each agent stays within its own role may evade detection.
|
|
96
|
+
|
|
97
|
+
### Symlink Resolution
|
|
98
|
+
|
|
99
|
+
RoleValidator operates on path strings, not the filesystem. A symlink named `src/safe-link` pointing to `/etc/shadow` would pass the `src/**` allowed pattern check. Sentinel cannot resolve symlinks without filesystem access on the target host.
|
|
100
|
+
|
|
101
|
+
### Concurrent Audit-Trail Writers (No Inter-Process Lock)
|
|
102
|
+
|
|
103
|
+
The audit trail is designed for a **single writer** -- the gateway daemon. There is no inter-process write lock. Running concurrent writer processes against one trail can fork the hash chain, so a `verify-audit` failure can indicate benign concurrency rather than tampering.
|
|
104
|
+
|
|
105
|
+
### Cross-Engine Signature Verification
|
|
106
|
+
|
|
107
|
+
Ed25519 signature determinism currently relies on **V8's JSON key ordering** when serializing the signed payload. Verifying on another JavaScript engine (Bun, Deno) is not supported and may report false invalids.
|
|
108
|
+
|
|
109
|
+
### Workspace Identity Collisions
|
|
110
|
+
|
|
111
|
+
Workspace identity is a **32-bit FNV-1a hash** of the workspace root. It is non-cryptographic and not collision-resistant; it distinguishes local workspaces but is not a security boundary.
|
|
112
|
+
|
|
113
|
+
### Conservative Matching / False Positives
|
|
114
|
+
|
|
115
|
+
Target matching is deliberately conservative: a command that only _references_ a forbidden filename — for instance, a `grep` whose pattern or path is `.env` — can be denied even though it never opens the file. Because each denial counts toward the escalation ladder, a run of such false positives can move the agent to `restricted` or `quarantined`. Plain mentions under safe verbs (`echo`, `printf`) and in comments are not flagged. When a false positive does restrict or quarantine the agent, recover with `sentinel release`, which records the change in the audit trail. Tune policies to widen the allow set where this proves noisy.
|
|
116
|
+
|
|
117
|
+
### Cold-Start Window
|
|
118
|
+
|
|
119
|
+
On a cold start, the first tool call of a fresh session waits up to **~5 seconds** for the gateway daemon to warm up. If the daemon is not ready, the hook applies its **tiered fallback** rather than failing closed uniformly: high-sensitivity tools (e.g. `Bash`, `Write`, `Edit`, `WebFetch`) are **denied**, while lower-sensitivity tools (e.g. `Read`, `Glob`, `Grep`, `WebSearch`) are **allowed** through. MCP and unknown tools default to the high (deny) tier.
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## Trust Model
|
|
124
|
+
|
|
125
|
+
### Recommended Production Deployment
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
+------------------+ HTTPS/webhook +-------------------+
|
|
129
|
+
| AI Agent Host | -----------------------------> | Sentinel Host |
|
|
130
|
+
| | POST /api/sentinel/events | |
|
|
131
|
+
| Agent runtime | | WebhookReceiver |
|
|
132
|
+
| sends events | | RoleValidator |
|
|
133
|
+
| before/after | | AuditTrail |
|
|
134
|
+
| each action | | AlertManager |
|
|
135
|
+
+------------------+ +-------------------+
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
- Sentinel runs on a separate host the agent cannot access
|
|
139
|
+
- Events are pushed via authenticated webhook (API key in Authorization header)
|
|
140
|
+
- Audit trail is on the Sentinel host, inaccessible to the agent
|
|
141
|
+
- Alerts dispatch to external systems (Slack webhook, PagerDuty, etc.)
|
|
142
|
+
|
|
143
|
+
### Development Deployment
|
|
144
|
+
|
|
145
|
+
```
|
|
146
|
+
+----------------------------------------------+
|
|
147
|
+
| Same Host |
|
|
148
|
+
| |
|
|
149
|
+
| Agent runtime ---> activity.log |
|
|
150
|
+
| | |
|
|
151
|
+
| LogAdapter (polls) |
|
|
152
|
+
| | |
|
|
153
|
+
| SentinelRunner |
|
|
154
|
+
| AuditTrail |
|
|
155
|
+
+----------------------------------------------+
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
- Sentinel watches the agent's log file via LogAdapter
|
|
159
|
+
- Simpler setup but agent could tamper with its own logs
|
|
160
|
+
- Suitable for development and testing
|
|
161
|
+
|
|
162
|
+
### Audit Trail Integrity
|
|
163
|
+
|
|
164
|
+
- Append-only: entries are only written, never modified or deleted programmatically
|
|
165
|
+
- Per-agent: each agent has its own `audit.log` file
|
|
166
|
+
- Rotation: files rotate at 10 MB, keeping 3 archives (audit.log.1, .2, .3)
|
|
167
|
+
- All entries include timestamps and are queryable by time range and severity
|
|
168
|
+
|
|
169
|
+
### Data Storage
|
|
170
|
+
|
|
171
|
+
- All data is local to the Sentinel host filesystem
|
|
172
|
+
- No cloud services, no external databases, no network dependencies
|
|
173
|
+
- Storage location is configurable via `agentsDir` constructor parameter
|
|
174
|
+
- Default: `~/.dahlia/agents/`
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## Severity Levels
|
|
179
|
+
|
|
180
|
+
| Severity | Meaning | Triggers Alert? | Response |
|
|
181
|
+
| ------------ | ------------------------------ | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
|
|
182
|
+
| **LOW** | Notable but expected variation | No (unless configured) | Log for review. Weight anomalies, off-day activity. |
|
|
183
|
+
| **MEDIUM** | Warrants monitoring | Configurable | Single deviation signal. Volume spike, unusual targets, category shift, off-hours. Escalates to HIGH when 3+ converge in one session. |
|
|
184
|
+
| **HIGH** | Requires investigation | Yes | Role violation, forbidden target access, escalated convergence. |
|
|
185
|
+
| **CRITICAL** | Immediate response required | Yes | Target sensitivity effective score >= 0.9. Credential access, system file writes. |
|
|
186
|
+
|
|
187
|
+
### Escalation Rules
|
|
188
|
+
|
|
189
|
+
- MEDIUM findings escalate to HIGH when 3+ MEDIUM findings occur in a single session (convergence escalation)
|
|
190
|
+
- HIGH findings are escalated to CRITICAL by the TargetSensitivityScorer when the effective score (sensitivity x action multiplier) reaches 0.9+
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## Detection Capabilities
|
|
195
|
+
|
|
196
|
+
| Threat | Detection Method | Component | Expected Severity |
|
|
197
|
+
| --------------------------------------------- | -------------------------------------------- | -------------------------- | --------------------------------------------- |
|
|
198
|
+
| SSH key access (`~/.ssh/id_rsa`) | Target sensitivity (1.0) | RoleValidator + Scorer | CRITICAL |
|
|
199
|
+
| `.env` file read | Target sensitivity (1.0) | RoleValidator + Scorer | CRITICAL |
|
|
200
|
+
| AWS credential access (`~/.aws/credentials`) | Target sensitivity (1.0) | RoleValidator + Scorer | CRITICAL |
|
|
201
|
+
| Kubernetes config access (`~/.kube/config`) | Target sensitivity (0.95) | RoleValidator + Scorer | CRITICAL |
|
|
202
|
+
| Write to `~/.ssh/authorized_keys` (backdoor) | Target sensitivity (1.0 x 1.3 write) | RoleValidator + Scorer | CRITICAL |
|
|
203
|
+
| `/etc/passwd` read | Target sensitivity (0.9) + forbidden pattern | RoleValidator + Scorer | CRITICAL |
|
|
204
|
+
| System config write (`/etc/nginx/nginx.conf`) | Target sensitivity (0.7 x 1.3 write = 0.91) | RoleValidator + Scorer | CRITICAL |
|
|
205
|
+
| Payment data access (`payments/`) | Target sensitivity (0.85) | DeviationDetector + Scorer | HIGH |
|
|
206
|
+
| Database query by file-only agent | Action not in allowedActions | RoleValidator | HIGH |
|
|
207
|
+
| Shell command by code-writer agent | Action not in allowedActions | RoleValidator | HIGH |
|
|
208
|
+
| 3x baseline event volume | Event count exceeds threshold | DeviationDetector | MEDIUM (escalates to HIGH with other signals) |
|
|
209
|
+
| >50% novel target files in session | Target set comparison | DeviationDetector | MEDIUM |
|
|
210
|
+
| Activity outside expected hours | Schedule check (UTC) | RoleValidator | MEDIUM |
|
|
211
|
+
| Weekend activity when weekday-only | Schedule check (UTC) | RoleValidator | MEDIUM |
|
|
212
|
+
| Path traversal (`src/../.env`) | Path normalization + pattern match | RoleValidator | HIGH/CRITICAL (depends on target) |
|
|
213
|
+
| Category shift (rare action type) | Baseline action distribution | DeviationDetector | MEDIUM |
|
|
214
|
+
| Access outside allowed scope | Allowed target pattern miss | RoleValidator | MEDIUM |
|
|
215
|
+
| Multiple converging anomalies (3+) | Finding count in session | DeviationDetector | MEDIUM escalated to HIGH |
|
|
216
|
+
| Activity drop (75%+ fewer events) | Event count vs baseline average | DeviationDetector | MEDIUM (HIGH at 90%+ drop) |
|
|
217
|
+
| Extended agent silence (2-3x max gap) | Time since last event vs baseline gaps | DeviationDetector | LOW (MEDIUM at 3x+) |
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## Finding Types
|
|
222
|
+
|
|
223
|
+
| Type | Source | Description |
|
|
224
|
+
| --------------------- | -------------------------------- | ----------------------------------------------------------------------------------------- |
|
|
225
|
+
| `role_violation` | RoleValidator | Agent performed an action not in its `allowedActions` list |
|
|
226
|
+
| `unauthorized_target` | RoleValidator, DeviationDetector | Agent accessed a target matching `forbiddenTargetPatterns` or scoring high on sensitivity |
|
|
227
|
+
| `scope_violation` | RoleValidator | Agent accessed a target outside its `allowedTargetPatterns` |
|
|
228
|
+
| `temporal_anomaly` | RoleValidator, DeviationDetector | Activity outside expected schedule or baseline typical hours/days |
|
|
229
|
+
| `volume_spike` | DeviationDetector | Session event count exceeds baseline average by 3x+ |
|
|
230
|
+
| `access_pattern` | DeviationDetector | Unusual target distribution, weight anomaly, or category shift |
|
|
231
|
+
| `behavioral_absence` | DeviationDetector | Significant activity drop (75%+ below baseline) or extended silence (2-3x max gap) |
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// src/workspaceIdentity.ts
|
|
2
|
+
var AGENT_PREFIX = "claude-code";
|
|
3
|
+
function fnv1a32Hex(s) {
|
|
4
|
+
let h = 2166136261;
|
|
5
|
+
for (let i = 0; i < s.length; i++) {
|
|
6
|
+
h ^= s.charCodeAt(i);
|
|
7
|
+
h = Math.imul(h, 16777619);
|
|
8
|
+
}
|
|
9
|
+
return (h >>> 0).toString(16).padStart(8, "0");
|
|
10
|
+
}
|
|
11
|
+
function lastSegment(path) {
|
|
12
|
+
const parts = path.split("/").filter(Boolean);
|
|
13
|
+
return parts.length > 0 ? parts[parts.length - 1] : "";
|
|
14
|
+
}
|
|
15
|
+
function slugify(s) {
|
|
16
|
+
return s.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "");
|
|
17
|
+
}
|
|
18
|
+
function normalizeRoot(root) {
|
|
19
|
+
if (root === "" || root === "/") return root;
|
|
20
|
+
return root.replace(/\/+$/, "") || "/";
|
|
21
|
+
}
|
|
22
|
+
function deriveAgentId(workspaceRoot) {
|
|
23
|
+
const root = normalizeRoot(workspaceRoot);
|
|
24
|
+
const slug = slugify(lastSegment(root)) || "root";
|
|
25
|
+
const hash = fnv1a32Hex(root);
|
|
26
|
+
return `${AGENT_PREFIX}@${slug}-${hash}`;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export {
|
|
30
|
+
deriveAgentId
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=chunk-B5QKJHSV.js.map
|