indigiarmor 0.1.0

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.
Files changed (47) hide show
  1. package/LICENSE +24 -0
  2. package/README.md +257 -0
  3. package/dist/client.d.ts +117 -0
  4. package/dist/client.d.ts.map +1 -0
  5. package/dist/client.js +359 -0
  6. package/dist/client.js.map +1 -0
  7. package/dist/errors.d.ts +20 -0
  8. package/dist/errors.d.ts.map +1 -0
  9. package/dist/errors.js +39 -0
  10. package/dist/errors.js.map +1 -0
  11. package/dist/guard.d.ts +17 -0
  12. package/dist/guard.d.ts.map +1 -0
  13. package/dist/guard.js +39 -0
  14. package/dist/guard.js.map +1 -0
  15. package/dist/index.d.ts +4 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +3 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/middleware.d.ts +13 -0
  20. package/dist/middleware.d.ts.map +1 -0
  21. package/dist/middleware.js +34 -0
  22. package/dist/middleware.js.map +1 -0
  23. package/dist/next-handler.d.ts +4 -0
  24. package/dist/next-handler.d.ts.map +1 -0
  25. package/dist/next-handler.js +39 -0
  26. package/dist/next-handler.js.map +1 -0
  27. package/dist/protect.d.ts +9 -0
  28. package/dist/protect.d.ts.map +1 -0
  29. package/dist/protect.js +24 -0
  30. package/dist/protect.js.map +1 -0
  31. package/dist/types.d.ts +356 -0
  32. package/dist/types.d.ts.map +1 -0
  33. package/dist/types.js +3 -0
  34. package/dist/types.js.map +1 -0
  35. package/dist/wrap-anthropic.d.ts +5 -0
  36. package/dist/wrap-anthropic.d.ts.map +1 -0
  37. package/dist/wrap-anthropic.js +107 -0
  38. package/dist/wrap-anthropic.js.map +1 -0
  39. package/dist/wrap-gemini.d.ts +5 -0
  40. package/dist/wrap-gemini.d.ts.map +1 -0
  41. package/dist/wrap-gemini.js +122 -0
  42. package/dist/wrap-gemini.js.map +1 -0
  43. package/dist/wrap-openai.d.ts +5 -0
  44. package/dist/wrap-openai.d.ts.map +1 -0
  45. package/dist/wrap-openai.js +106 -0
  46. package/dist/wrap-openai.js.map +1 -0
  47. package/package.json +54 -0
package/LICENSE ADDED
@@ -0,0 +1,24 @@
1
+ Copyright (c) 2024-present IndigiArmor
2
+
3
+ Permission is hereby granted to any person or organization obtaining a copy of
4
+ this software and associated documentation files (the "Software") to use the
5
+ Software solely in connection with an active IndigiArmor subscription or
6
+ authorized evaluation. You may install, copy, and integrate the Software into
7
+ your applications for that purpose.
8
+
9
+ You may NOT:
10
+
11
+ - Redistribute, sublicense, sell, or otherwise transfer the Software as a
12
+ standalone product.
13
+ - Remove or alter any proprietary notices, labels, or marks.
14
+ - Use the Software to build a competing service or product.
15
+ - Reverse-engineer, decompile, or disassemble the Software beyond what is
16
+ permitted by applicable law.
17
+
18
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER
22
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM,
23
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,257 @@
1
+ # IndigiArmor SDK
2
+
3
+ Official JavaScript/TypeScript client for the IndigiArmor API -- real-time prompt scanning for PII, FERPA, Indigenous cultural knowledge, re-identification, and injection attacks.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install indigiarmor
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```typescript
14
+ import { IndigiArmor } from 'indigiarmor';
15
+
16
+ const ia = new IndigiArmor('ia_sk_your_key_here');
17
+
18
+ const result = await ia.scan('Send me John Smith SSN 123-45-6789');
19
+ console.log(result.tier); // 'red'
20
+ console.log(result.action); // 'block'
21
+ ```
22
+
23
+ ## Features
24
+
25
+ - **Prompt scanning** -- detect PII, FERPA violations, cultural knowledge exposure, re-identification risk, and prompt injection before prompts reach an LLM
26
+ - **Response scanning** -- scan LLM output for PII leaks and sensitive data
27
+ - **Document scanning** -- scan extracted text from PDFs, DOCX, and other documents
28
+ - **Human-in-the-loop** -- confirm yellow-tier (flagged) prompts via token-based approval
29
+ - **Policy management** -- create, update, and delete detection policies; apply compliance templates
30
+ - **Allowlisting** -- mark safe terms to suppress false positives
31
+ - **Usage and audit logs** -- query scan statistics and paginated audit history
32
+ - **Webhooks** -- receive real-time notifications on scan events (Professional+)
33
+ - **Teams** -- organize users into teams with scoped access (Professional+)
34
+ - **Custom entities** -- define custom detection patterns and keywords (Enterprise)
35
+ - **Compliance reports** -- generate audit exports and compliance summaries (Education+)
36
+ - **Red team simulation** -- run attack simulations against your current policy (Enterprise)
37
+ - **Convenience layers** -- `guard()`, `protect()`, Express middleware, Next.js handler wrapper, and LLM client wrappers for OpenAI, Anthropic, and Gemini
38
+ - **Zero dependencies** -- works in Node.js 18+, browsers, Deno, Cloudflare Workers, and Edge runtimes
39
+
40
+ ## Convenience Layers
41
+
42
+ Every convenience layer accepts a `yellowStrategy` option that controls how yellow-tier (flagged) results are handled:
43
+
44
+ | Strategy | Behavior |
45
+ |--------------|-----------------------------------------------|
46
+ | `'sanitize'` | Allow, using the sanitized prompt (default) |
47
+ | `'allow'` | Allow, using the original prompt |
48
+ | `'block'` | Reject the prompt |
49
+
50
+ ### `guard()` -- Scan and Decide
51
+
52
+ Scan a prompt and get a simple safe/unsafe decision in one call.
53
+
54
+ ```typescript
55
+ const { safe, prompt, result } = await ia.guard('user input here');
56
+
57
+ if (safe) {
58
+ // `prompt` is the sanitized version when applicable
59
+ await callLLM(prompt);
60
+ } else {
61
+ console.log('Blocked:', result.explanation);
62
+ }
63
+ ```
64
+
65
+ Override the yellow strategy per call:
66
+
67
+ ```typescript
68
+ const { safe } = await ia.guard('user input', { yellowStrategy: 'block' });
69
+ ```
70
+
71
+ ### `protect()` -- Wrap Any Function
72
+
73
+ Scan input, call your function with the safe prompt, and optionally scan the output.
74
+
75
+ ```typescript
76
+ const { output, inputScan, outputScan } = await ia.protect(
77
+ 'user input here',
78
+ async (safePrompt) => {
79
+ return await callLLM(safePrompt);
80
+ },
81
+ { scanOutput: true },
82
+ );
83
+ ```
84
+
85
+ Throws `IndigiArmorError` with code `PROMPT_BLOCKED` if the input is blocked, or `RESPONSE_BLOCKED` if output scanning detects sensitive data.
86
+
87
+ ### `middleware()` -- Express Middleware
88
+
89
+ Drop-in Express middleware that scans request bodies before your route handler runs.
90
+
91
+ ```typescript
92
+ import express from 'express';
93
+
94
+ const app = express();
95
+ app.use(express.json());
96
+
97
+ app.post('/api/chat', ia.middleware({ promptField: 'prompt' }), (req, res) => {
98
+ // req.body.prompt is now sanitized
99
+ // req.scanResult contains the full scan result
100
+ res.json({ reply: 'ok' });
101
+ });
102
+ ```
103
+
104
+ Blocked prompts receive a 400 response with `{ error: 'blocked', explanation, tier }`. Requests without the specified prompt field pass through without scanning.
105
+
106
+ ### `nextHandler()` -- Next.js App Router
107
+
108
+ Wrap a Next.js App Router route handler with automatic prompt scanning.
109
+
110
+ ```typescript
111
+ // app/api/chat/route.ts
112
+ import { IndigiArmor } from 'indigiarmor';
113
+
114
+ const ia = new IndigiArmor(process.env.INDIGIARMOR_API_KEY!);
115
+
116
+ export const POST = ia.nextHandler(
117
+ async (req, scanResult) => {
118
+ const { prompt } = await req.json();
119
+ // prompt is already sanitized in the cloned request body
120
+ return Response.json({ answer: await callLLM(prompt) });
121
+ },
122
+ { promptField: 'prompt' },
123
+ );
124
+ ```
125
+
126
+ Returns a 400 JSON response for blocked prompts. Non-JSON requests and requests without the prompt field pass through. Uses Web standard `Request`/`Response` -- no Next.js dependency required.
127
+
128
+ ### `wrapOpenAI()` -- OpenAI Client Wrapper
129
+
130
+ Proxy-wrap an OpenAI client so every `chat.completions.create()` call is automatically scanned.
131
+
132
+ ```typescript
133
+ import OpenAI from 'openai';
134
+
135
+ const openai = ia.wrapOpenAI(new OpenAI(), {
136
+ yellowStrategy: 'sanitize',
137
+ scanOutput: true,
138
+ });
139
+
140
+ // All user messages are scanned before reaching OpenAI
141
+ const completion = await openai.chat.completions.create({
142
+ model: 'gpt-4o',
143
+ messages: [{ role: 'user', content: 'Hello' }],
144
+ });
145
+ ```
146
+
147
+ Scans each user message individually. Handles both `content: string` and `content: ContentPart[]` formats. Works with OpenAI-compatible providers (Groq, Together, Azure OpenAI).
148
+
149
+ ### `wrapAnthropic()` -- Anthropic Client Wrapper
150
+
151
+ Proxy-wrap an Anthropic client so every `messages.create()` call is scanned, including the top-level `system` parameter.
152
+
153
+ ```typescript
154
+ import Anthropic from '@anthropic-ai/sdk';
155
+
156
+ const anthropic = ia.wrapAnthropic(new Anthropic(), { scanOutput: true });
157
+
158
+ const message = await anthropic.messages.create({
159
+ model: 'claude-sonnet-4-20250514',
160
+ max_tokens: 1024,
161
+ system: 'You are a helpful assistant.',
162
+ messages: [{ role: 'user', content: 'Hello' }],
163
+ });
164
+ ```
165
+
166
+ ### `wrapGemini()` -- Google GenAI Client Wrapper
167
+
168
+ Proxy-wrap a Google GenAI client so every `models.generateContent()` call is scanned, including `config.systemInstruction`.
169
+
170
+ ```typescript
171
+ import { GoogleGenAI } from '@google/genai';
172
+
173
+ const genai = ia.wrapGemini(new GoogleGenAI({ apiKey: '...' }), {
174
+ scanOutput: true,
175
+ });
176
+
177
+ const response = await genai.models.generateContent({
178
+ model: 'gemini-2.5-flash',
179
+ contents: 'Hello',
180
+ });
181
+ ```
182
+
183
+ Handles string contents and `{ role, parts }` arrays.
184
+
185
+ **LLM wrapper limitations:** Output scanning only works with non-streaming responses. Only text content is scanned; images pass through unchanged.
186
+
187
+ ## Error Handling
188
+
189
+ All API errors are thrown as typed subclasses of `IndigiArmorError`:
190
+
191
+ ```typescript
192
+ import {
193
+ IndigiArmorError,
194
+ AuthenticationError,
195
+ RateLimitError,
196
+ ValidationError,
197
+ NotFoundError,
198
+ } from 'indigiarmor';
199
+
200
+ try {
201
+ await ia.scan(prompt);
202
+ } catch (err) {
203
+ if (err instanceof RateLimitError) {
204
+ // err.retryAfter -- seconds until retry (when provided by server)
205
+ console.log(`Rate limited. Retry after ${err.retryAfter}s`);
206
+ } else if (err instanceof AuthenticationError) {
207
+ // Invalid or revoked API key (401)
208
+ } else if (err instanceof ValidationError) {
209
+ // Bad request payload (400)
210
+ } else if (err instanceof NotFoundError) {
211
+ // Resource not found (404)
212
+ } else if (err instanceof IndigiArmorError) {
213
+ // err.code -- machine-readable error code
214
+ // err.status -- HTTP status (0 for network/timeout errors)
215
+ // err.requestId -- server request ID for support
216
+ }
217
+ }
218
+ ```
219
+
220
+ Error codes from convenience layers:
221
+
222
+ | Code | Meaning |
223
+ |--------------------|----------------------------------------------------------------------|
224
+ | `PROMPT_BLOCKED` | Input blocked (red tier, or yellow with `'block'` strategy) |
225
+ | `RESPONSE_BLOCKED` | LLM output failed response scanning |
226
+ | `TIMEOUT` | Request exceeded the configured timeout |
227
+ | `NETWORK_ERROR` | Network-level failure (DNS, connection refused, etc.) |
228
+
229
+ ## Configuration
230
+
231
+ ```typescript
232
+ const ia = new IndigiArmor('ia_sk_...', {
233
+ // Base URL of the IndigiArmor API (default: 'https://indigiarmor.com')
234
+ baseUrl: 'https://indigiarmor.com',
235
+
236
+ // Request timeout in milliseconds (default: 30000)
237
+ timeout: 10_000,
238
+
239
+ // Custom fetch implementation (default: globalThis.fetch)
240
+ fetch: customFetch,
241
+
242
+ // Lifecycle callbacks triggered after each scan() call
243
+ callbacks: {
244
+ onBlock: (result) => console.error('Blocked:', result.explanation),
245
+ onFlag: (result) => console.warn('Flagged:', result.explanation),
246
+ onAllow: (result) => {},
247
+ },
248
+ });
249
+ ```
250
+
251
+ Callbacks are invoked based on the result tier after every `scan()` call. Errors thrown inside callbacks are swallowed and never break the scan flow. Async callbacks are awaited.
252
+
253
+ ## Links
254
+
255
+ - [API Documentation](https://indigiarmor.com/docs/sdk)
256
+ - [Website](https://indigiarmor.com)
257
+ - [GitHub Issues](https://github.com/rschance1/indigiarmor/issues)
@@ -0,0 +1,117 @@
1
+ import type { IndigiArmorOptions, ScanResult, ScanResponseResult, ConfirmResult, DocumentMetadata, Policy, CreatePolicyRequest, UpdatePolicyRequest, PolicyTemplate, CreateFromTemplateRequest, ApiKey, CreateKeyRequest, CreateKeyResult, UsageResult, UsageQuery, AuditLog, AuditQuery, AuditListResult, AllowlistEntry, CreateAllowlistRequest, Webhook, CreateWebhookRequest, UpdateWebhookRequest, Team, CreateTeamRequest, TeamMember, CustomEntity, CreateCustomEntityRequest, UpdateCustomEntityRequest, AuditExportQuery, ComplianceReport, AttackCase, SimulationRunResult, GuardOptions, GuardResult, ProtectOptions, ProtectResult, MiddlewareOptions, NextHandlerOptions, WrapLLMOptions } from './types.js';
2
+ export declare class IndigiArmor {
3
+ private readonly apiKey;
4
+ private readonly baseUrl;
5
+ private readonly fetchFn;
6
+ private readonly timeout;
7
+ private readonly callbacks;
8
+ constructor(apiKey: string, options?: IndigiArmorOptions);
9
+ /** Scan a prompt for risk signals before sending to an LLM. */
10
+ scan(prompt: string): Promise<ScanResult>;
11
+ private invokeCallback;
12
+ /** Scan document content (extracted text from PDF, DOCX, etc.) for risk signals. */
13
+ scanDocument(content: string, documentMetadata?: DocumentMetadata): Promise<ScanResult>;
14
+ /** Scan an LLM response for PII leaks and sensitive data. */
15
+ scanResponse(response: string): Promise<ScanResponseResult>;
16
+ /** Confirm a yellow-tier token (human-in-the-loop approval). */
17
+ confirm(tokenId: string): Promise<ConfirmResult>;
18
+ /** List all policies for your organization. */
19
+ listPolicies(): Promise<Policy[]>;
20
+ /** Create a new detection policy. */
21
+ createPolicy(data: CreatePolicyRequest): Promise<Policy>;
22
+ /** Update an existing policy. */
23
+ updatePolicy(id: string, data: UpdatePolicyRequest): Promise<Policy>;
24
+ /** Delete a policy. */
25
+ deletePolicy(id: string): Promise<void>;
26
+ /** List available compliance policy templates (Education+). */
27
+ listPolicyTemplates(): Promise<PolicyTemplate[]>;
28
+ /** Create a policy from a compliance template (Education+). */
29
+ createPolicyFromTemplate(data: CreateFromTemplateRequest): Promise<Policy>;
30
+ /** List all API keys (hashes are never returned). */
31
+ listKeys(): Promise<ApiKey[]>;
32
+ /** Create a new API key. The raw key is only returned once. */
33
+ createKey(data: CreateKeyRequest): Promise<CreateKeyResult>;
34
+ /** Revoke an API key (soft-delete). */
35
+ revokeKey(id: string): Promise<void>;
36
+ /** Get scan usage statistics, optionally filtered by date range. */
37
+ getUsage(query?: UsageQuery): Promise<UsageResult>;
38
+ /** Query paginated audit logs with optional filters. */
39
+ listAuditLogs(query?: AuditQuery): Promise<AuditListResult>;
40
+ /** Get a single audit log entry by ID. */
41
+ getAuditLog(id: string): Promise<AuditLog>;
42
+ /** List all allowlisted terms for your organization. */
43
+ listAllowlist(): Promise<AllowlistEntry[]>;
44
+ /** Add a term to the allowlist. */
45
+ addAllowlistEntry(data: CreateAllowlistRequest): Promise<AllowlistEntry>;
46
+ /** Remove an allowlist entry. */
47
+ removeAllowlistEntry(id: string): Promise<void>;
48
+ /** List all webhooks. */
49
+ listWebhooks(): Promise<Webhook[]>;
50
+ /** Create a webhook endpoint. */
51
+ createWebhook(data: CreateWebhookRequest): Promise<Webhook>;
52
+ /** Update a webhook. */
53
+ updateWebhook(id: string, data: UpdateWebhookRequest): Promise<Webhook>;
54
+ /** Delete a webhook. */
55
+ deleteWebhook(id: string): Promise<void>;
56
+ /** Send a test event to a webhook. */
57
+ testWebhook(id: string): Promise<{
58
+ success: boolean;
59
+ status?: number;
60
+ }>;
61
+ /** List all teams. */
62
+ listTeams(): Promise<Team[]>;
63
+ /** Create a team. */
64
+ createTeam(data: CreateTeamRequest): Promise<Team>;
65
+ /** Update a team. */
66
+ updateTeam(id: string, data: {
67
+ name: string;
68
+ }): Promise<Team>;
69
+ /** Delete a team. */
70
+ deleteTeam(id: string): Promise<void>;
71
+ /** List team members. */
72
+ listTeamMembers(teamId: string): Promise<TeamMember[]>;
73
+ /** Add a member to a team. */
74
+ addTeamMember(teamId: string, userId: string): Promise<void>;
75
+ /** List custom entity types. */
76
+ listCustomEntities(): Promise<CustomEntity[]>;
77
+ /** Create a custom entity type. */
78
+ createCustomEntity(data: CreateCustomEntityRequest): Promise<CustomEntity>;
79
+ /** Update a custom entity type. */
80
+ updateCustomEntity(id: string, data: UpdateCustomEntityRequest): Promise<CustomEntity>;
81
+ /** Delete a custom entity type. */
82
+ deleteCustomEntity(id: string): Promise<void>;
83
+ /** Export audit logs as JSON. */
84
+ exportAuditLogs(query: AuditExportQuery): Promise<{
85
+ export: {
86
+ logs: AuditLog[];
87
+ total: number;
88
+ };
89
+ }>;
90
+ /** Generate a compliance summary report. */
91
+ getComplianceReport(from: string, to: string): Promise<ComplianceReport>;
92
+ /** Run a red team attack simulation against current policy. */
93
+ runRedTeam(): Promise<SimulationRunResult>;
94
+ /** List available attack cases (without executing). */
95
+ listAttackCases(): Promise<AttackCase[]>;
96
+ /** Simple boolean gate — scan and decide in one call. */
97
+ guard(prompt: string, options?: GuardOptions): Promise<GuardResult>;
98
+ /** Scan input, call function with safe prompt, optionally scan output. */
99
+ protect<T>(prompt: string, fn: (safePrompt: string) => Promise<T>, options?: ProtectOptions): Promise<ProtectResult<T>>;
100
+ /** Express-compatible middleware that scans prompts from request bodies. */
101
+ middleware(options?: MiddlewareOptions): (req: import("./middleware.js").MiddlewareRequest, res: import("./middleware.js").MiddlewareResponse, next: import("./middleware.js").NextFunction) => Promise<void>;
102
+ /** Next.js App Router handler wrapper that scans prompts before processing. */
103
+ nextHandler(handler: (req: Request, scanResult: ScanResult | undefined) => Promise<Response>, options?: NextHandlerOptions): (req: Request) => Promise<Response>;
104
+ /** Proxy-wrap an OpenAI client to auto-scan all chat completions. */
105
+ wrapOpenAI<T extends object>(client: T, options?: WrapLLMOptions): T;
106
+ /** Proxy-wrap an Anthropic client to auto-scan all messages. */
107
+ wrapAnthropic<T extends object>(client: T, options?: WrapLLMOptions): T;
108
+ /** Proxy-wrap a Google GenAI client to auto-scan all generateContent calls. */
109
+ wrapGemini<T extends object>(client: T, options?: WrapLLMOptions): T;
110
+ private get;
111
+ private post;
112
+ private put;
113
+ private del;
114
+ private request;
115
+ private handleError;
116
+ }
117
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}