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/dist/index.cjs CHANGED
@@ -20,237 +20,22 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
- CitadelClient: () => CitadelClient,
23
+ Citadel_0: () => Citadel_0,
24
24
  evaluatePolicies: () => evaluatePolicies,
25
- scanPayloadSemantics: () => scanPayloadSemantics,
26
- wrapTool: () => wrapTool,
27
- wrapToolWithReview: () => wrapToolWithReview
25
+ guardTool: () => guardTool
28
26
  });
29
27
  module.exports = __toCommonJS(index_exports);
30
28
 
31
- // src/sdk/client.ts
32
- var CitadelClient = class {
33
- baseUrl;
34
- agentToken;
35
- environment;
36
- defaultSessionId;
37
- constructor(config) {
38
- this.baseUrl = config.baseUrl.replace(/\/+$/, "");
39
- this.agentToken = config.agentToken;
40
- this.environment = config.environment;
41
- this.defaultSessionId = config.defaultSessionId;
42
- }
43
- async check(action, params = {}, options = {}) {
44
- const url = `${this.baseUrl}/api/v1/check`;
45
- const sessionId = options.sessionId ?? this.defaultSessionId ?? `sess_${Math.random().toString(36).slice(2, 11)}`;
46
- const response = await fetch(url, {
47
- method: "POST",
48
- headers: {
49
- "Content-Type": "application/json",
50
- Authorization: `Bearer ${this.agentToken}`
51
- },
52
- body: JSON.stringify({
53
- action,
54
- params,
55
- sessionId,
56
- environment: options.environment ?? this.environment,
57
- metadata: options.metadata
58
- })
59
- });
60
- if (!response.ok) {
61
- const errorBody = await response.json().catch(() => ({}));
62
- const errorMessage = typeof errorBody.error === "string" ? errorBody.error : `Citadel gateway error: ${response.status} ${response.statusText}`;
63
- throw new Error(errorMessage);
64
- }
65
- return await response.json();
66
- }
67
- async isAllowed(action, params = {}, options = {}) {
68
- const result = await this.check(action, params, options);
69
- return result.verdict.decision === "ALLOW";
70
- }
71
- async guard(action, params, callback, options = {}) {
72
- const result = await this.check(action, params, options);
73
- if (result.verdict.decision !== "ALLOW") {
74
- throw new Error(
75
- `Action '${action}' blocked by Citadel: ${result.verdict.reason}`
76
- );
77
- }
78
- return await callback();
79
- }
80
- async getReviewStatus(auditLogId) {
81
- const url = `${this.baseUrl}/api/v1/review/status?auditLogId=${encodeURIComponent(
82
- auditLogId
83
- )}`;
84
- const response = await fetch(url);
85
- if (!response.ok) {
86
- const errorBody = await response.json().catch(() => ({}));
87
- const errorMessage = typeof errorBody.error === "string" ? errorBody.error : `Review status error: ${response.status}`;
88
- throw new Error(errorMessage);
89
- }
90
- return await response.json();
91
- }
92
- async pollReview(auditLogId, options = {}) {
93
- const timeoutMs = options.timeoutMs ?? 6e4;
94
- const intervalMs = options.intervalMs ?? 2e3;
95
- const deadline = Date.now() + timeoutMs;
96
- while (Date.now() < deadline) {
97
- const status = await this.getReviewStatus(auditLogId);
98
- if (status.decision !== "REVIEW") {
99
- return status;
100
- }
101
- await new Promise((resolve) => setTimeout(resolve, intervalMs));
102
- }
103
- throw new Error(
104
- `Review timed out after ${timeoutMs}ms for auditLogId: ${auditLogId}`
105
- );
106
- }
107
- async guardWithReview(action, params, callback, options = {}) {
108
- const result = await this.check(action, params, options);
109
- if (result.verdict.decision === "ALLOW") {
110
- return await callback();
111
- }
112
- if (result.verdict.decision === "BLOCK") {
113
- throw new Error(
114
- `Action '${action}' blocked by Citadel: ${result.verdict.reason}`
115
- );
116
- }
117
- if (options.onReviewPending) {
118
- options.onReviewPending(result.auditLogId);
119
- }
120
- const reviewed = await this.pollReview(result.auditLogId, {
121
- timeoutMs: options.timeoutMs,
122
- intervalMs: options.pollIntervalMs
123
- });
124
- if (reviewed.decision === "ALLOW") {
125
- return await callback();
126
- }
127
- throw new Error(
128
- `Action '${action}' rejected during human review: ${reviewed.reviewComment ?? "Rejected"}`
129
- );
130
- }
131
- };
132
-
133
- // src/sdk/tools.ts
134
- function wrapTool(client, tool) {
135
- return {
136
- ...tool,
137
- execute: async (args) => {
138
- return await client.guard(
139
- tool.name,
140
- args,
141
- () => tool.execute(args),
142
- tool.options
143
- );
144
- }
145
- };
146
- }
147
- function wrapToolWithReview(client, tool, reviewOptions) {
148
- return {
149
- ...tool,
150
- execute: async (args) => {
151
- return await client.guardWithReview(
152
- tool.name,
153
- args,
154
- () => tool.execute(args),
155
- {
156
- ...tool.options,
157
- ...reviewOptions
158
- }
159
- );
160
- }
161
- };
162
- }
163
-
164
- // src/engine/semantic.ts
165
- var INJECTION_PATTERNS = [
166
- {
167
- regex: /(?:ignore|disregard|forget|bypass|override)\s+(?:all\s+)?(?:previous|prior|existing|above)\s+(?:instructions|rules|guidelines|directions|constraints)/i,
168
- description: "Direct prompt instruction override",
169
- score: 95
170
- },
171
- {
172
- regex: /(?:you\s+are\s+now|act\s+as|roleplay\s+as)\s+(?:an?\s+)?(?:unfiltered|unrestricted|jailbroken|evil|dan|developer\s+mode)/i,
173
- description: "Adversarial persona / DAN jailbreak attempt",
174
- score: 90
175
- },
176
- {
177
- regex: /(?:reveal|output|print|display|leak)\s+(?:the\s+)?(?:system\s+prompt|initial\s+prompt|core\s+instructions|developer\s+instructions)/i,
178
- description: "System prompt extraction attempt",
179
- score: 85
180
- },
181
- {
182
- regex: /(?:\[INST\]|\[\/INST\]|<<SYS>>|<\/SYS>|<\|im_start\|>|<\|im_end\|>)/i,
183
- description: "Model token delimiter injection",
184
- score: 90
185
- }
186
- ];
187
- var CREDENTIAL_PATTERNS = [
188
- {
189
- regex: /(?:sk-[a-zA-Z0-9-_]{20,}|ghp_[a-zA-Z0-9]{36}|gho_[a-zA-Z0-9]{36})/i,
190
- description: "Exposed API token (OpenAI / GitHub)",
191
- score: 95
192
- },
193
- {
194
- regex: /AKIA[0-9A-Z]{16}/,
195
- description: "AWS Access Key ID",
196
- score: 90
197
- },
198
- {
199
- regex: /-----BEGIN (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----/,
200
- description: "Exposed Private Key block",
201
- score: 99
202
- }
203
- ];
204
- function extractStrings(obj) {
205
- const strings = [];
206
- function recurse(value) {
207
- if (typeof value === "string") {
208
- strings.push(value);
209
- } else if (Array.isArray(value)) {
210
- for (const item of value) recurse(item);
211
- } else if (value !== null && typeof value === "object") {
212
- for (const val of Object.values(value)) {
213
- recurse(val);
214
- }
215
- }
216
- }
217
- recurse(obj);
218
- return strings;
219
- }
220
- function scanPayloadSemantics(params) {
221
- const stringsToScan = extractStrings(params);
222
- const threats = [];
223
- for (const text of stringsToScan) {
224
- for (const rule of INJECTION_PATTERNS) {
225
- if (rule.regex.test(text)) {
226
- threats.push({
227
- type: "PROMPT_INJECTION",
228
- confidence: rule.score / 100,
229
- reason: rule.description,
230
- matchedPattern: rule.regex.source
231
- });
232
- }
233
- }
234
- for (const rule of CREDENTIAL_PATTERNS) {
235
- if (rule.regex.test(text)) {
236
- threats.push({
237
- type: "CREDENTIAL_LEAK",
238
- confidence: rule.score / 100,
239
- reason: rule.description,
240
- matchedPattern: rule.regex.source
241
- });
242
- }
243
- }
29
+ // src/engine/match.ts
30
+ var regexCache = /* @__PURE__ */ new Map();
31
+ function getCompiledRegex(pattern) {
32
+ let re = regexCache.get(pattern);
33
+ if (!re) {
34
+ re = new RegExp(pattern);
35
+ regexCache.set(pattern, re);
244
36
  }
245
- const maxScore = threats.length > 0 ? Math.max(...threats.map((t) => t.confidence * 100)) : 0;
246
- return {
247
- flagged: threats.length > 0,
248
- threats,
249
- maxRiskScore: Math.round(maxScore)
250
- };
37
+ return re;
251
38
  }
252
-
253
- // src/engine/match.ts
254
39
  function extractField(obj, path) {
255
40
  const parts = path.split(".");
256
41
  let current = obj;
@@ -292,7 +77,7 @@ function evaluateCondition(actual, operator, target) {
292
77
  return false;
293
78
  }
294
79
  try {
295
- return new RegExp(target).test(actual);
80
+ return getCompiledRegex(target).test(actual);
296
81
  } catch {
297
82
  return false;
298
83
  }
@@ -305,8 +90,7 @@ function matchesActionPattern(pattern, action) {
305
90
  return true;
306
91
  }
307
92
  if (pattern.endsWith("*")) {
308
- const prefix = pattern.slice(0, -1);
309
- return action.startsWith(prefix);
93
+ return action.startsWith(pattern.slice(0, -1));
310
94
  }
311
95
  return false;
312
96
  }
@@ -314,37 +98,35 @@ function evaluateRule(payload, rule) {
314
98
  const targetObject = {
315
99
  action: payload.action,
316
100
  params: payload.params,
317
- context: payload.context,
318
- timestamp: payload.timestamp,
101
+ context: payload.context ?? {},
319
102
  metadata: payload.metadata ?? {}
320
103
  };
321
104
  const actualValue = extractField(targetObject, rule.field);
322
105
  return evaluateCondition(actualValue, rule.operator, rule.value);
323
106
  }
324
- function calculateRisk(decision, matchedCount, semanticScore = 0) {
107
+ function calculateRisk(decision, matchedCount) {
325
108
  if (decision === "BLOCK") {
326
- return { riskScore: Math.max(95, semanticScore), riskLevel: "CRITICAL" };
109
+ return { riskScore: 95, riskLevel: "CRITICAL" };
327
110
  }
328
111
  if (decision === "REVIEW") {
329
- return { riskScore: Math.max(65, semanticScore), riskLevel: "HIGH" };
112
+ return { riskScore: 65, riskLevel: "HIGH" };
330
113
  }
331
114
  if (matchedCount > 0) {
332
115
  return { riskScore: 25, riskLevel: "MEDIUM" };
333
116
  }
334
117
  return { riskScore: 5, riskLevel: "LOW" };
335
118
  }
336
- function evaluatePolicies(payload, policies) {
337
- const startTime = Date.now();
119
+ function evaluatePolicies(payload, sortedPolicies) {
120
+ const startTime = performance.now();
338
121
  const traces = [];
339
- const activePolicies = policies.filter((p) => p.isActive && p.tenantId === payload.context.tenantId).sort((a, b) => b.priority - a.priority);
340
122
  let finalDecision = "ALLOW";
341
- let primaryReason = "No blocking or review policies triggered";
342
- let pipeline = "DETERMINISTIC";
343
- for (const policy of activePolicies) {
344
- if (!matchesActionPattern(policy.actionPattern, payload.action)) {
123
+ let primaryReason = "All security policies satisfied";
124
+ for (let i = 0; i < sortedPolicies.length; i++) {
125
+ const policy = sortedPolicies[i];
126
+ if (!policy.isActive || !matchesActionPattern(policy.actionPattern, payload.action)) {
345
127
  continue;
346
128
  }
347
- const rulesMatched = policy.rules.length > 0 && policy.rules.every((rule) => evaluateRule(payload, rule));
129
+ const rulesMatched = policy.rules.length === 0 || policy.rules.every((rule) => evaluateRule(payload, rule));
348
130
  if (rulesMatched) {
349
131
  traces.push({
350
132
  policyId: policy.id,
@@ -363,36 +145,139 @@ function evaluatePolicies(payload, policies) {
363
145
  }
364
146
  }
365
147
  }
366
- let semanticScore = 0;
367
- if (finalDecision !== "BLOCK") {
368
- const semanticResult = scanPayloadSemantics(payload.params);
369
- if (semanticResult.flagged) {
370
- pipeline = traces.length > 0 ? "HYBRID" : "AI_GUARD";
371
- semanticScore = semanticResult.maxRiskScore;
372
- finalDecision = "BLOCK";
373
- const threatReasons = semanticResult.threats.map((t) => t.reason).join(", ");
374
- primaryReason = `AI Guard blocked threat: ${threatReasons}`;
375
- }
376
- }
377
- const { riskScore, riskLevel } = calculateRisk(finalDecision, traces.length, semanticScore);
378
- const latencyMs = Date.now() - startTime;
148
+ const { riskScore, riskLevel } = calculateRisk(finalDecision, traces.length);
149
+ const latencyMs = Number((performance.now() - startTime).toFixed(3));
379
150
  return {
380
151
  verdictId: `vrd_${Math.random().toString(36).slice(2, 11)}`,
381
152
  decision: finalDecision,
382
153
  reason: primaryReason,
383
154
  riskScore,
384
155
  riskLevel,
385
- evaluationPipeline: pipeline,
386
156
  matchedPolicies: traces,
387
- executedAt: startTime,
157
+ executedAt: Date.now(),
388
158
  latencyMs
389
159
  };
390
160
  }
161
+
162
+ // src/sdk/client.ts
163
+ var Citadel_0 = class {
164
+ baseUrl;
165
+ agentToken;
166
+ environment;
167
+ defaultSessionId;
168
+ policies = [];
169
+ telemetryQueue = [];
170
+ batchSize;
171
+ flushTimer = null;
172
+ constructor(config) {
173
+ this.baseUrl = config.baseUrl.replace(/\/+$/, "");
174
+ this.agentToken = config.agentToken;
175
+ this.environment = config.environment ?? "production";
176
+ this.defaultSessionId = config.defaultSessionId;
177
+ this.batchSize = config.batchSize ?? 50;
178
+ if (config.policies) {
179
+ this.setPolicies(config.policies);
180
+ }
181
+ const interval = config.flushIntervalMs ?? 3e3;
182
+ this.flushTimer = setInterval(() => {
183
+ void this.flush();
184
+ }, interval);
185
+ if (typeof this.flushTimer === "object" && "unref" in this.flushTimer) {
186
+ this.flushTimer.unref();
187
+ }
188
+ }
189
+ setPolicies(policies) {
190
+ this.policies = [...policies].sort((a, b) => b.priority - a.priority);
191
+ }
192
+ async syncPolicies() {
193
+ const res = await fetch(`${this.baseUrl}/api/v1/policies`, {
194
+ headers: { Authorization: `Bearer ${this.agentToken}` }
195
+ });
196
+ if (res.ok) {
197
+ const data = await res.json();
198
+ const list = Array.isArray(data) ? data : data?.policies ?? [];
199
+ this.setPolicies(list);
200
+ }
201
+ }
202
+ check(action, params = {}, options = {}) {
203
+ const payload = {
204
+ action,
205
+ params,
206
+ context: {
207
+ sessionId: options.sessionId ?? this.defaultSessionId,
208
+ environment: options.environment ?? this.environment
209
+ },
210
+ metadata: options.metadata
211
+ };
212
+ const verdict = evaluatePolicies(payload, this.policies);
213
+ this.telemetryQueue.push({
214
+ traceId: verdict.verdictId,
215
+ action,
216
+ params,
217
+ verdict,
218
+ sessionId: payload.context?.sessionId,
219
+ environment: payload.context?.environment ?? this.environment,
220
+ timestamp: verdict.executedAt
221
+ });
222
+ if (this.telemetryQueue.length >= this.batchSize) {
223
+ void this.flush();
224
+ }
225
+ return verdict;
226
+ }
227
+ isAllowed(action, params = {}, options = {}) {
228
+ return this.check(action, params, options).decision === "ALLOW";
229
+ }
230
+ guard(action, params, callback, options = {}) {
231
+ const verdict = this.check(action, params, options);
232
+ if (verdict.decision === "BLOCK") {
233
+ throw new Error(`Action '${action}' blocked by Citadel 0: ${verdict.reason}`);
234
+ }
235
+ if (verdict.decision === "REVIEW") {
236
+ throw new Error(`Action '${action}' halted: requires human review`);
237
+ }
238
+ return callback();
239
+ }
240
+ async flush() {
241
+ if (this.telemetryQueue.length === 0) {
242
+ return;
243
+ }
244
+ const batch = this.telemetryQueue.splice(0, this.batchSize);
245
+ try {
246
+ await fetch(`${this.baseUrl}/api/v1/telemetry`, {
247
+ method: "POST",
248
+ headers: {
249
+ "Content-Type": "application/json",
250
+ Authorization: `Bearer ${this.agentToken}`
251
+ },
252
+ body: JSON.stringify({ traces: batch })
253
+ });
254
+ } catch {
255
+ this.telemetryQueue.unshift(...batch);
256
+ }
257
+ }
258
+ destroy() {
259
+ if (this.flushTimer) {
260
+ clearInterval(this.flushTimer);
261
+ this.flushTimer = null;
262
+ }
263
+ void this.flush();
264
+ }
265
+ };
266
+
267
+ // src/sdk/tools.ts
268
+ function guardTool(client, action, fn, options) {
269
+ return async (args) => {
270
+ return client.guard(
271
+ action,
272
+ args,
273
+ () => fn(args),
274
+ options
275
+ );
276
+ };
277
+ }
391
278
  // Annotate the CommonJS export names for ESM import in node:
392
279
  0 && (module.exports = {
393
- CitadelClient,
280
+ Citadel_0,
394
281
  evaluatePolicies,
395
- scanPayloadSemantics,
396
- wrapTool,
397
- wrapToolWithReview
282
+ guardTool
398
283
  });
package/dist/index.d.cts CHANGED
@@ -1,20 +1,5 @@
1
1
  type Decision = 'ALLOW' | 'BLOCK' | 'REVIEW';
2
2
  type RiskLevel = 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL';
3
- type PolicyEffect = 'ALLOW' | 'BLOCK' | 'REVIEW';
4
- interface SecurityContext {
5
- tenantId: string;
6
- agentId: string;
7
- sessionId: string;
8
- environment: 'production' | 'staging' | 'development';
9
- clientIp?: string;
10
- }
11
- interface ActionPayload {
12
- context: SecurityContext;
13
- action: string;
14
- params: Record<string, unknown>;
15
- timestamp: number;
16
- metadata?: Record<string, unknown>;
17
- }
18
3
  type PolicyConditionOperator = 'EQUALS' | 'NOT_EQUALS' | 'GREATER_THAN' | 'LESS_THAN' | 'IN' | 'NOT_IN' | 'CONTAINS' | 'REGEX_MATCH';
19
4
  interface PolicyRule {
20
5
  field: string;
@@ -23,20 +8,28 @@ interface PolicyRule {
23
8
  }
24
9
  interface SecurityPolicy {
25
10
  id: string;
26
- tenantId: string;
27
11
  name: string;
28
- description?: string;
29
12
  actionPattern: string;
30
- rules: PolicyRule[];
31
- effect: PolicyEffect;
13
+ effect: Decision;
32
14
  priority: number;
33
15
  isActive: boolean;
16
+ rules: PolicyRule[];
17
+ }
18
+ interface ActionPayload {
19
+ action: string;
20
+ params: Record<string, unknown>;
21
+ context?: {
22
+ tenantId?: string;
23
+ sessionId?: string;
24
+ environment?: string;
25
+ };
26
+ metadata?: Record<string, unknown>;
34
27
  }
35
28
  interface PolicyEvaluationTrace {
36
29
  policyId: string;
37
30
  policyName: string;
38
31
  matched: boolean;
39
- effect: PolicyEffect;
32
+ effect: Decision;
40
33
  }
41
34
  interface SecurityVerdict {
42
35
  verdictId: string;
@@ -44,108 +37,58 @@ interface SecurityVerdict {
44
37
  reason: string;
45
38
  riskScore: number;
46
39
  riskLevel: RiskLevel;
47
- evaluationPipeline: 'DETERMINISTIC' | 'AI_GUARD' | 'HYBRID';
48
40
  matchedPolicies: PolicyEvaluationTrace[];
49
41
  executedAt: number;
50
42
  latencyMs: number;
51
43
  }
52
- interface AuditLogEntry {
53
- id: string;
54
- tenantId: string;
55
- agentId: string;
56
- sessionId: string;
44
+ interface TelemetryTrace {
45
+ traceId: string;
57
46
  action: string;
58
47
  params: Record<string, unknown>;
59
48
  verdict: SecurityVerdict;
60
- reviewedBy?: string;
61
- reviewComment?: string;
62
- createdAt: number;
49
+ sessionId?: string;
50
+ environment: string;
51
+ timestamp: number;
63
52
  }
64
53
 
65
- interface CitadelClientConfig {
54
+ declare function evaluatePolicies(payload: ActionPayload, sortedPolicies: SecurityPolicy[]): SecurityVerdict;
55
+
56
+ interface Citadel_0_Config {
66
57
  baseUrl: string;
67
58
  agentToken: string;
68
59
  environment?: 'production' | 'staging' | 'development';
69
60
  defaultSessionId?: string;
61
+ policies?: SecurityPolicy[];
62
+ flushIntervalMs?: number;
63
+ batchSize?: number;
70
64
  }
71
65
  interface CheckOptions {
72
66
  sessionId?: string;
73
67
  environment?: 'production' | 'staging' | 'development';
74
68
  metadata?: Record<string, unknown>;
75
69
  }
76
- interface CheckResult {
77
- verdict: SecurityVerdict;
78
- auditLogId: string;
79
- }
80
- interface ReviewStatus {
81
- auditLogId: string;
82
- decision: 'ALLOW' | 'BLOCK' | 'REVIEW';
83
- reviewedBy?: string;
84
- reviewComment?: string;
85
- action: string;
86
- params: unknown;
87
- riskScore: number;
88
- riskLevel: string;
89
- createdAt: number;
90
- }
91
- interface GuardWithReviewOptions extends CheckOptions {
92
- timeoutMs?: number;
93
- pollIntervalMs?: number;
94
- onReviewPending?: (auditLogId: string) => void;
95
- }
96
- declare class CitadelClient {
70
+ declare class Citadel_0 {
97
71
  private readonly baseUrl;
98
72
  private readonly agentToken;
99
- private readonly environment?;
73
+ private readonly environment;
100
74
  private readonly defaultSessionId?;
101
- constructor(config: CitadelClientConfig);
102
- check(action: string, params?: Record<string, unknown>, options?: CheckOptions): Promise<CheckResult>;
103
- isAllowed(action: string, params?: Record<string, unknown>, options?: CheckOptions): Promise<boolean>;
104
- guard<T>(action: string, params: Record<string, unknown>, callback: () => Promise<T> | T, options?: CheckOptions): Promise<T>;
105
- getReviewStatus(auditLogId: string): Promise<ReviewStatus>;
106
- pollReview(auditLogId: string, options?: {
107
- timeoutMs?: number;
108
- intervalMs?: number;
109
- }): Promise<ReviewStatus>;
110
- guardWithReview<T>(action: string, params: Record<string, unknown>, callback: () => Promise<T> | T, options?: GuardWithReviewOptions): Promise<T>;
75
+ private policies;
76
+ private telemetryQueue;
77
+ private readonly batchSize;
78
+ private flushTimer;
79
+ constructor(config: Citadel_0_Config);
80
+ setPolicies(policies: SecurityPolicy[]): void;
81
+ syncPolicies(): Promise<void>;
82
+ check(action: string, params?: Record<string, unknown>, options?: CheckOptions): SecurityVerdict;
83
+ isAllowed(action: string, params?: Record<string, unknown>, options?: CheckOptions): boolean;
84
+ guard<T>(action: string, params: Record<string, unknown>, callback: () => Promise<T> | T, options?: CheckOptions): Promise<T> | T;
85
+ flush(): Promise<void>;
86
+ destroy(): void;
111
87
  }
112
88
 
113
- interface GuardedToolDefinition<TArgs = any, TResult = any> {
114
- name: string;
115
- description?: string;
116
- execute: (args: TArgs) => Promise<TResult> | TResult;
117
- options?: CheckOptions;
118
- }
119
- declare function wrapTool<TArgs extends Record<string, unknown>, TResult>(client: CitadelClient, tool: GuardedToolDefinition<TArgs, TResult>): {
120
- execute: (args: TArgs) => Promise<TResult>;
121
- name: string;
122
- description?: string;
123
- options?: CheckOptions;
124
- };
125
- declare function wrapToolWithReview<TArgs extends Record<string, unknown>, TResult>(client: CitadelClient, tool: GuardedToolDefinition<TArgs, TResult>, reviewOptions?: {
126
- timeoutMs?: number;
127
- pollIntervalMs?: number;
128
- onReviewPending?: (auditLogId: string) => void;
129
- }): {
130
- execute: (args: TArgs) => Promise<TResult>;
131
- name: string;
132
- description?: string;
133
- options?: CheckOptions;
134
- };
135
-
136
- interface ThreatDetection {
137
- type: 'PROMPT_INJECTION' | 'JAILBREAK_ATTEMPT' | 'CREDENTIAL_LEAK';
138
- confidence: number;
139
- reason: string;
140
- matchedPattern: string;
89
+ interface GuardedToolOptions extends CheckOptions {
90
+ actionName?: string;
141
91
  }
142
- interface SemanticScanResult {
143
- flagged: boolean;
144
- threats: ThreatDetection[];
145
- maxRiskScore: number;
146
- }
147
- declare function scanPayloadSemantics(params: Record<string, unknown>): SemanticScanResult;
148
-
149
- declare function evaluatePolicies(payload: ActionPayload, policies: SecurityPolicy[]): SecurityVerdict;
92
+ declare function guardTool<TArgs extends Record<string, unknown>, TResult>(client: Citadel_0, action: string, fn: (args: TArgs) => Promise<TResult> | TResult, options?: CheckOptions): (args: TArgs) => Promise<TResult>;
150
93
 
151
- export { type ActionPayload, type AuditLogEntry, type CheckOptions, type CheckResult, CitadelClient, type CitadelClientConfig, type Decision, type GuardWithReviewOptions, type GuardedToolDefinition, type PolicyConditionOperator, type PolicyEffect, type PolicyEvaluationTrace, type PolicyRule, type ReviewStatus, type RiskLevel, type SecurityContext, type SecurityPolicy, type SecurityVerdict, type SemanticScanResult, type ThreatDetection, evaluatePolicies, scanPayloadSemantics, wrapTool, wrapToolWithReview };
94
+ export { type ActionPayload, type CheckOptions, Citadel_0, type Citadel_0_Config, type Decision, type GuardedToolOptions, type PolicyConditionOperator, type PolicyEvaluationTrace, type PolicyRule, type RiskLevel, type SecurityPolicy, type SecurityVerdict, type TelemetryTrace, evaluatePolicies, guardTool };