citadel0 1.0.0 → 1.0.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 +188 -75
- package/dist/index.cjs +145 -260
- package/dist/index.d.cts +42 -99
- package/dist/index.d.ts +42 -99
- package/dist/index.js +144 -257
- package/package.json +1 -1
- package/LICENSE +0 -21
package/README.md
CHANGED
|
@@ -1,124 +1,237 @@
|
|
|
1
1
|
# Citadel 0
|
|
2
2
|
|
|
3
|
-
Programmatic security gateway and policy engine for AI agents
|
|
3
|
+
Programmatic security gateway and deterministic policy evaluation engine for AI agents and tool-call pipelines.
|
|
4
4
|
|
|
5
|
-
Citadel 0 inspects
|
|
5
|
+
Citadel 0 intercepts, inspects, and validates AI agent actions and tool arguments before execution. It provides sub-millisecond in-memory rule evaluation, wildcard action matching, nested parameter traversal, risk scoring, automated telemetry batching, and function wrapping.
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## Highlights
|
|
10
10
|
|
|
11
|
-
- **
|
|
12
|
-
- **
|
|
13
|
-
- **
|
|
14
|
-
- **
|
|
15
|
-
- **
|
|
16
|
-
- **
|
|
11
|
+
- **Deterministic Evaluation**: Evaluates action payloads locally in-memory with sub-millisecond execution latency.
|
|
12
|
+
- **Zero Runtime Dependencies**: Built with native runtime primitives and `fetch`—no external runtime dependencies required.
|
|
13
|
+
- **Hierarchical Policy Precedence**: Prioritizes policies by numeric priority, short-circuiting on critical block conditions.
|
|
14
|
+
- **Deep Dot-Path Extraction**: Safely traverses nested objects across action parameters, context, and metadata.
|
|
15
|
+
- **Cached Pattern Matching**: Supports wildcard action routing and cached regular expression condition evaluations.
|
|
16
|
+
- **Background Telemetry**: Non-blocking, auto-batching telemetry queue with Node.js unreferenced timers that do not hold event loops open.
|
|
17
|
+
- **Dual Bundle**: Ships ESM and CommonJS builds with full TypeScript declarations.
|
|
17
18
|
|
|
18
19
|
---
|
|
19
20
|
|
|
20
21
|
## Installation
|
|
21
22
|
|
|
22
|
-
|
|
23
|
+
~~~bash
|
|
23
24
|
npm install citadel0
|
|
24
|
-
|
|
25
|
+
~~~
|
|
25
26
|
|
|
26
|
-
|
|
27
|
+
~~~bash
|
|
27
28
|
pnpm add citadel0
|
|
28
|
-
|
|
29
|
+
~~~
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Core Concepts
|
|
34
|
+
|
|
35
|
+
### Evaluation Verdicts & Risk Scoring
|
|
36
|
+
|
|
37
|
+
Every policy evaluation returns a `SecurityVerdict` containing a deterministic decision and calculated risk score:
|
|
38
|
+
|
|
39
|
+
| Verdict | Risk Level | Score | Description |
|
|
40
|
+
|---|---|---|---|
|
|
41
|
+
| **`ALLOW`** | `LOW` | `5` | Payload passed all policies with zero rule violations. |
|
|
42
|
+
| **`ALLOW`** | `MEDIUM` | `25` | Payload passed evaluation with non-blocking informational rule matches. |
|
|
43
|
+
| **`REVIEW`** | `HIGH` | `65` | Action flagged for operator sign-off; halted before execution. |
|
|
44
|
+
| **`BLOCK`** | `CRITICAL` | `95` | Disallowed execution signature detected; rejected immediately. |
|
|
45
|
+
|
|
46
|
+
### Supported Condition Operators
|
|
47
|
+
|
|
48
|
+
Rules can be configured with the following condition operators against any dotted field path:
|
|
49
|
+
|
|
50
|
+
- `EQUALS` / `NOT_EQUALS`: Strict equality checks.
|
|
51
|
+
- `GREATER_THAN` / `LESS_THAN`: Numeric threshold comparisons.
|
|
52
|
+
- `IN` / `NOT_IN`: Array inclusion checks.
|
|
53
|
+
- `CONTAINS`: Substring matching for strings, element inclusion for arrays.
|
|
54
|
+
- `REGEX_MATCH`: Regular expression pattern matching with compiled regex caching.
|
|
29
55
|
|
|
30
56
|
---
|
|
31
57
|
|
|
32
58
|
## Usage
|
|
33
59
|
|
|
34
|
-
###
|
|
60
|
+
### 1. Wrapping Tool Functions (Recommended)
|
|
61
|
+
|
|
62
|
+
Use `guardTool` to wrap execution functions. If a policy blocks the action or flags it for review, an error is thrown before your function is invoked:
|
|
35
63
|
|
|
36
|
-
|
|
37
|
-
import {
|
|
64
|
+
~~~typescript
|
|
65
|
+
import { Citadel_0, guardTool } from 'citadel0';
|
|
38
66
|
|
|
39
|
-
const
|
|
40
|
-
baseUrl: '
|
|
41
|
-
agentToken: process.env.
|
|
67
|
+
const citadel0 = new Citadel_0({
|
|
68
|
+
baseUrl: 'https://api.example.com',
|
|
69
|
+
agentToken: process.env.CITADEL0_AGENT_TOKEN!,
|
|
42
70
|
});
|
|
43
|
-
```
|
|
44
71
|
|
|
45
|
-
|
|
72
|
+
// Synchronize remote policies from gateway
|
|
73
|
+
await citadel0.syncPolicies();
|
|
46
74
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
})
|
|
75
|
+
const executeBash = guardTool(
|
|
76
|
+
citadel0,
|
|
77
|
+
'bash.exec',
|
|
78
|
+
async (args: { command: string }) => {
|
|
79
|
+
return runSystemProcess(args.command);
|
|
80
|
+
}
|
|
81
|
+
);
|
|
51
82
|
|
|
52
|
-
if
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
```
|
|
83
|
+
// Runs normally if allowed; throws Error if BLOCK or REVIEW
|
|
84
|
+
await executeBash({ command: 'ls -la' });
|
|
85
|
+
~~~
|
|
56
86
|
|
|
57
|
-
###
|
|
87
|
+
### 2. Standalone / Offline Evaluation
|
|
58
88
|
|
|
59
|
-
|
|
60
|
-
import { CitadelClient, wrapTool } from 'citadel0';
|
|
89
|
+
Initialize `Citadel_0` with local static policies without requiring network access:
|
|
61
90
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
agentToken: process.env.CITADEL_AGENT_TOKEN!,
|
|
65
|
-
});
|
|
91
|
+
~~~typescript
|
|
92
|
+
import { Citadel_0, SecurityPolicy } from 'citadel0';
|
|
66
93
|
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
94
|
+
const policies: SecurityPolicy[] = [
|
|
95
|
+
{
|
|
96
|
+
id: 'pol_block_destructive_bash',
|
|
97
|
+
name: 'Block Destructive Commands',
|
|
98
|
+
actionPattern: 'bash.*',
|
|
99
|
+
effect: 'BLOCK',
|
|
100
|
+
priority: 100,
|
|
101
|
+
isActive: true,
|
|
102
|
+
rules: [
|
|
103
|
+
{
|
|
104
|
+
field: 'params.command',
|
|
105
|
+
operator: 'REGEX_MATCH',
|
|
106
|
+
value: 'rm -rf|mkfs|dd|chmod 777',
|
|
107
|
+
},
|
|
108
|
+
],
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
id: 'pol_review_high_spend',
|
|
112
|
+
name: 'Review Large Transactions',
|
|
113
|
+
actionPattern: 'stripe.transfer',
|
|
114
|
+
effect: 'REVIEW',
|
|
115
|
+
priority: 50,
|
|
116
|
+
isActive: true,
|
|
117
|
+
rules: [
|
|
118
|
+
{
|
|
119
|
+
field: 'params.amount',
|
|
120
|
+
operator: 'GREATER_THAN',
|
|
121
|
+
value: 1000,
|
|
122
|
+
},
|
|
123
|
+
],
|
|
71
124
|
},
|
|
125
|
+
];
|
|
126
|
+
|
|
127
|
+
const citadel0 = new Citadel_0({
|
|
128
|
+
baseUrl: 'https://api.example.com',
|
|
129
|
+
agentToken: 'c0_live_token',
|
|
130
|
+
policies,
|
|
72
131
|
});
|
|
73
132
|
|
|
74
|
-
const
|
|
75
|
-
|
|
133
|
+
const verdict = citadel0.check('bash.exec', {
|
|
134
|
+
command: 'rm -rf /',
|
|
135
|
+
});
|
|
76
136
|
|
|
77
|
-
|
|
137
|
+
console.log(verdict.decision); // 'BLOCK'
|
|
138
|
+
console.log(verdict.riskScore); // 95
|
|
139
|
+
console.log(verdict.reason); // 'Blocked by policy: Block Destructive Commands'
|
|
140
|
+
~~~
|
|
78
141
|
|
|
79
|
-
|
|
80
|
-
import { CitadelClient, wrapToolWithReview } from 'citadel0';
|
|
142
|
+
### 3. Context & Session Metadata
|
|
81
143
|
|
|
82
|
-
|
|
83
|
-
baseUrl: '[https://energetic-starfish-637.convex.site](https://energetic-starfish-637.convex.site)',
|
|
84
|
-
agentToken: process.env.CITADEL_AGENT_TOKEN!,
|
|
85
|
-
});
|
|
144
|
+
Attach session IDs, runtime environment overrides, and custom metadata for policy inspection:
|
|
86
145
|
|
|
87
|
-
|
|
88
|
-
|
|
146
|
+
~~~typescript
|
|
147
|
+
const verdict = citadel0.check(
|
|
148
|
+
'db.drop_collection',
|
|
149
|
+
{ collection: 'customers' },
|
|
89
150
|
{
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
},
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
timeoutMs: 60000,
|
|
97
|
-
pollIntervalMs: 2000,
|
|
98
|
-
onReviewPending: (auditLogId) => {
|
|
99
|
-
console.log(`Pending approval: ${auditLogId}`);
|
|
100
|
-
},
|
|
151
|
+
sessionId: 'sess_user_981',
|
|
152
|
+
environment: 'production',
|
|
153
|
+
metadata: { initiatorRole: 'support_agent' },
|
|
101
154
|
}
|
|
102
155
|
);
|
|
156
|
+
~~~
|
|
157
|
+
|
|
158
|
+
### 4. Direct Engine Evaluation
|
|
103
159
|
|
|
104
|
-
|
|
105
|
-
|
|
160
|
+
Invoke the evaluation engine directly as a pure function:
|
|
161
|
+
|
|
162
|
+
~~~typescript
|
|
163
|
+
import { evaluatePolicies, ActionPayload, SecurityPolicy } from 'citadel0';
|
|
164
|
+
|
|
165
|
+
const payload: ActionPayload = {
|
|
166
|
+
action: 'file.delete',
|
|
167
|
+
params: { path: '/etc/hosts' },
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
const verdict = evaluatePolicies(payload, policies);
|
|
171
|
+
~~~
|
|
106
172
|
|
|
107
173
|
---
|
|
108
174
|
|
|
109
175
|
## API Reference
|
|
110
176
|
|
|
111
|
-
### `
|
|
177
|
+
### `Citadel_0`
|
|
178
|
+
|
|
179
|
+
#### Configuration (`Citadel_0_Config`)
|
|
112
180
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
181
|
+
| Option | Type | Default | Description |
|
|
182
|
+
|---|---|---|---|
|
|
183
|
+
| `baseUrl` | `string` | *required* | Base URL of the gateway endpoint. |
|
|
184
|
+
| `agentToken` | `string` | *required* | Authentication Bearer token. |
|
|
185
|
+
| `environment` | `'production' \| 'staging' \| 'development'` | `'production'` | Runtime environment tag. |
|
|
186
|
+
| `defaultSessionId` | `string` | `undefined` | Fallback session identifier for actions. |
|
|
187
|
+
| `policies` | `SecurityPolicy[]` | `[]` | In-memory initial policies list. |
|
|
188
|
+
| `flushIntervalMs` | `number` | `3000` | Background telemetry flush interval. |
|
|
189
|
+
| `batchSize` | `number` | `50` | Maximum queue length before auto-flush. |
|
|
190
|
+
|
|
191
|
+
#### Methods
|
|
192
|
+
|
|
193
|
+
- `check(action, params?, options?)`: Evaluates policies against the action payload, enqueues telemetry, and returns a `SecurityVerdict`.
|
|
194
|
+
- `isAllowed(action, params?, options?)`: Returns `true` if evaluation decision equals `ALLOW`.
|
|
195
|
+
- `guard(action, params, callback, options?)`: Executes `callback` if allowed; throws an error if blocked or flagged for review.
|
|
196
|
+
- `setPolicies(policies)`: Sets and re-sorts local policies by priority descending.
|
|
197
|
+
- `syncPolicies()`: Fetches active policies from `GET /api/v1/policies`. Supports both raw arrays and wrapped response objects.
|
|
198
|
+
- `flush()`: Flushes batched telemetry traces to `POST /api/v1/telemetry`.
|
|
199
|
+
- `destroy()`: Clears the background timer and executes a final telemetry flush.
|
|
200
|
+
|
|
201
|
+
### Options & Verdict Types
|
|
202
|
+
|
|
203
|
+
#### `CheckOptions`
|
|
204
|
+
|
|
205
|
+
~~~typescript
|
|
206
|
+
interface CheckOptions {
|
|
207
|
+
sessionId?: string;
|
|
208
|
+
environment?: 'production' | 'staging' | 'development';
|
|
209
|
+
metadata?: Record<string, unknown>;
|
|
210
|
+
}
|
|
211
|
+
~~~
|
|
212
|
+
|
|
213
|
+
#### `SecurityVerdict`
|
|
214
|
+
|
|
215
|
+
~~~typescript
|
|
216
|
+
interface SecurityVerdict {
|
|
217
|
+
verdictId: string;
|
|
218
|
+
decision: 'ALLOW' | 'BLOCK' | 'REVIEW';
|
|
219
|
+
reason: string;
|
|
220
|
+
riskScore: number;
|
|
221
|
+
riskLevel: 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL';
|
|
222
|
+
latencyMs: number;
|
|
223
|
+
matchedPolicies: Array<{
|
|
224
|
+
policyId: string;
|
|
225
|
+
policyName: string;
|
|
226
|
+
matched: boolean;
|
|
227
|
+
effect: 'ALLOW' | 'BLOCK' | 'REVIEW';
|
|
228
|
+
}>;
|
|
229
|
+
executedAt: number;
|
|
230
|
+
}
|
|
231
|
+
~~~
|
|
232
|
+
|
|
233
|
+
---
|
|
118
234
|
|
|
119
|
-
|
|
235
|
+
## License
|
|
120
236
|
|
|
121
|
-
|
|
122
|
-
- `wrapToolWithReview(client, toolDefinition, options)`: Guards an execution function with review polling.
|
|
123
|
-
- `scanPayloadSemantics(params)`: Runs offline heuristic threat scanning against input parameters.
|
|
124
|
-
- `evaluatePolicies(payload, policies)`: Runs local deterministic and semantic engine directly.
|
|
237
|
+
MIT
|