@ciphyrshq/sdk 2.6.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.
package/README.md ADDED
@@ -0,0 +1,194 @@
1
+ # @ciphyrshq/sdk
2
+
3
+ Official JavaScript/TypeScript SDK for the [Ciphyrs PII Shield](https://ciphyrs.com) API. Mask and restore sensitive data (PII) in LLM prompts with a single function call.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @ciphyrshq/sdk
9
+ ```
10
+
11
+ Requires Node.js 18+ (uses native `fetch`).
12
+
13
+ ## Quick Start
14
+
15
+ ```js
16
+ import { CiphyrsClient } from '@ciphyrshq/sdk'
17
+
18
+ const client = new CiphyrsClient({ apiKey: 'cyp_live_...' })
19
+
20
+ // Mask PII before sending to an LLM
21
+ const { maskedText, sessionId } = await client.mask(
22
+ 'Contact John at john@acme.com or +91-9876543210'
23
+ )
24
+ // => "Contact [PERSON_1] at [EMAIL_ADDRESS_1] or [PHONE_NUMBER_1]"
25
+
26
+ // After getting the LLM response, restore original values
27
+ const { restoredText } = await client.restore(maskedResponse, sessionId)
28
+ ```
29
+
30
+ ## One-Shot Protect (recommended)
31
+
32
+ `protect()` wraps **mask → LLM call → restore** in a single call so you
33
+ can't accidentally ship `[PERSON_1]` to your end users:
34
+
35
+ ```js
36
+ const result = await client.scan.protect(userMessage, async (masked) => {
37
+ const r = await openai.chat.completions.create({
38
+ model: 'gpt-4o',
39
+ messages: [{ role: 'user', content: masked }],
40
+ })
41
+ return r.choices[0].message.content
42
+ })
43
+
44
+ res.send(result.output) // "Hello John, ..." — never "[PERSON_1]"
45
+ ```
46
+
47
+ ## Active Blocking with the Guard (V58)
48
+
49
+ Block prompt-injection / jailbreak / PII-leak attempts inline before they
50
+ reach your LLM. **<50ms p95 latency**, 5 detection layers (regex,
51
+ threat-intel, multilingual, custom rules, canaries):
52
+
53
+ ```js
54
+ // Option 1 — manual check
55
+ const guard = await client.guard.check({
56
+ input: userMessage,
57
+ agentName: 'support-bot',
58
+ userId: req.user.id,
59
+ })
60
+ if (guard.decision === 'block') {
61
+ return res.status(400).send({ error: guard.reason })
62
+ }
63
+
64
+ // Option 2 — wrap the whole LLM call
65
+ const result = await client.guard.wrap(userMessage, async (input) => {
66
+ return (await openai.chat.completions.create({
67
+ model: 'gpt-4o',
68
+ messages: [{ role: 'user', content: input }],
69
+ })).choices[0].message.content
70
+ })
71
+ if (result.blocked) return res.status(400).send({ error: result.reason })
72
+ res.send(result.output)
73
+ ```
74
+
75
+ ## Security Operations (V55-V59)
76
+
77
+ ```js
78
+ // List recent attack detections
79
+ const { detections } = await client.security.listDetections({ days: 7, severity: 'high' })
80
+
81
+ // Create a honeypot canary token (zero-FP exfiltration alarm)
82
+ const { canary, token } = await client.security.createCanary({
83
+ name: 'fake admin api key',
84
+ scope: 'output',
85
+ })
86
+ // → save `token` and plant it in test data; if it ever appears in prod
87
+ // output you get an instant critical alert.
88
+
89
+ // Generate an SOC 2 / compliance prod report
90
+ const { report } = await client.reports.generateProd({
91
+ title: 'Q4 2026 SOC 2 Evidence',
92
+ rangeStart: '2026-10-01',
93
+ rangeEnd: '2026-12-31',
94
+ sections: ['security_incidents', 'pii_detections', 'performance', 'cost'],
95
+ })
96
+ const pdf = await client.reports.downloadProdPdf(report.id)
97
+ fs.writeFileSync('soc2-evidence.pdf', pdf)
98
+
99
+ // Share with auditors (no Ciphyrs login required)
100
+ const { share_url_path } = await client.reports.share(report.id, 30)
101
+ ```
102
+
103
+ ## Async Scanning
104
+
105
+ For large texts or batch workflows, use async scanning:
106
+
107
+ ```js
108
+ const { jobId, sessionId } = await client.maskAsync(longDocument, {
109
+ source: 'RAG',
110
+ surface: 'api',
111
+ })
112
+
113
+ // Poll until complete (auto-polls every 500ms)
114
+ const result = await client.waitForJob(jobId, { timeoutMs: 30_000 })
115
+ console.log(result.maskedText)
116
+ ```
117
+
118
+ ## API Key Management
119
+
120
+ ```js
121
+ // Requires JWT token (dashboard auth)
122
+ const client = new CiphyrsClient({ token: jwtToken })
123
+
124
+ const { apiKey, key } = await client.createKey({ name: 'Production', scopes: ['scan'] })
125
+ const { apiKeys } = await client.auth.listApiKeys()
126
+ await client.auth.revokeApiKey(key.id)
127
+ ```
128
+
129
+ ## Dashboard Metrics
130
+
131
+ ```js
132
+ const client = new CiphyrsClient({ token: jwtToken })
133
+
134
+ const summary = await client.metrics.summary()
135
+ const ts = await client.metrics.timeseries({ range: '30d' })
136
+ const entities = await client.metrics.byEntity()
137
+ const latency = await client.metrics.latencyPercentiles()
138
+ const heatmap = await client.metrics.peakHours()
139
+ const report = await client.metrics.complianceReport({ from: '2026-01-01', to: '2026-03-31' })
140
+ ```
141
+
142
+ ## Configuration
143
+
144
+ | Option | Default | Description |
145
+ |-----------|----------------------------|--------------------------------------|
146
+ | `apiKey` | - | API key (`cyp_live_...`) for scans |
147
+ | `token` | - | JWT for dashboard/management APIs |
148
+ | `baseUrl` | `https://www.ciphyrs.com` | Gateway URL (VPC/on-prem override) |
149
+ | `dashUrl` | `https://www.ciphyrs.com` | Dashboard API URL |
150
+ | `timeout` | `10000` | Request timeout in ms |
151
+
152
+ ## Error Handling
153
+
154
+ All errors extend `CiphyrsError`:
155
+
156
+ ```js
157
+ import { CiphyrsRateLimitError, CiphyrsAuthError } from '@ciphyrshq/sdk'
158
+
159
+ try {
160
+ await client.mask(text)
161
+ } catch (err) {
162
+ if (err instanceof CiphyrsRateLimitError) {
163
+ // err.retryAfter — seconds until retry is safe
164
+ }
165
+ if (err instanceof CiphyrsAuthError) {
166
+ // Invalid or expired API key / token
167
+ }
168
+ }
169
+ ```
170
+
171
+ | Error Class | HTTP Status | When |
172
+ |--------------------------|-------------|---------------------------------|
173
+ | `CiphyrsAuthError` | 401 | Invalid/expired credentials |
174
+ | `CiphyrsPermissionError`| 403 | Insufficient role/scopes |
175
+ | `CiphyrsNotFoundError` | 404 | Resource not found |
176
+ | `CiphyrsRateLimitError` | 429 | Rate limit exceeded |
177
+ | `CiphyrsTimeoutError` | - | Request timed out |
178
+ | `CiphyrsJobTimeoutError`| - | Async job polling timed out |
179
+
180
+ ## Auto-Retry
181
+
182
+ The SDK automatically retries on transient errors (429, 500, 502, 503, 504) with exponential backoff. Up to 3 retries with a 500ms base delay. Respects `Retry-After` headers.
183
+
184
+ ## TypeScript
185
+
186
+ Full type definitions included via `types.d.ts`. Import types directly:
187
+
188
+ ```ts
189
+ import type { MaskResult, RestoreResult, CiphyrsClientOptions } from '@ciphyrshq/sdk'
190
+ ```
191
+
192
+ ## License
193
+
194
+ MIT
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@ciphyrshq/sdk",
3
+ "version": "2.6.0",
4
+ "description": "Official JavaScript / TypeScript SDK for the Ciphyrs PII Shield API",
5
+ "type": "module",
6
+ "main": "./src/index.js",
7
+ "types": "./types.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./src/index.js",
11
+ "types": "./types.d.ts"
12
+ },
13
+ "./tracer": "./src/tracer.js",
14
+ "./secret-detector": "./src/secret-detector.js",
15
+ "./eval-runner": "./src/eval-runner.js"
16
+ },
17
+ "files": ["src", "types.d.ts"],
18
+ "keywords": ["pii", "privacy", "masking", "llm", "ciphyrs", "gdpr", "dpdp", "sdk"],
19
+ "license": "MIT",
20
+ "engines": { "node": ">=18" },
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "https://github.com/praveen190/Ciphyrs.git",
24
+ "directory": "packages/sdk"
25
+ },
26
+ "homepage": "https://ciphyrs.com",
27
+ "scripts": {
28
+ "test": "node --test src/**/*.test.js"
29
+ }
30
+ }