blockintel-gate-sdk 0.3.7 → 0.3.9
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 +2 -0
- package/dist/contracts-KKk945Ox.d.cts +380 -0
- package/dist/contracts-KKk945Ox.d.ts +380 -0
- package/dist/index.cjs +1020 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +392 -298
- package/dist/index.d.ts +392 -298
- package/dist/index.js +1015 -4
- package/dist/index.js.map +1 -1
- package/dist/pilot/index.cjs +2401 -0
- package/dist/pilot/index.cjs.map +1 -0
- package/dist/pilot/index.d.cts +38 -0
- package/dist/pilot/index.d.ts +38 -0
- package/dist/pilot/index.js +2397 -0
- package/dist/pilot/index.js.map +1 -0
- package/package.json +14 -1
package/README.md
CHANGED
|
@@ -13,6 +13,8 @@ npm install @blockintel/gate-sdk
|
|
|
13
13
|
- Node.js >= 18.0.0 (uses global `fetch` API)
|
|
14
14
|
- TypeScript >= 5.0.0 (optional, for type definitions)
|
|
15
15
|
|
|
16
|
+
**Optional – On-prem HSM (PKCS#11):** For `GenericHsmSigner` with a real HSM (Thales nShield, Utimaco, AWS CloudHSM, SoftHSM2, etc.), install the optional dependency: `npm install pkcs11js`. Without it, `Pkcs11SessionImpl` throws at runtime when used; you can still pass a custom `pkcs11Session` to `GenericHsmSigner` for testing or a different PKCS#11 stack.
|
|
17
|
+
|
|
16
18
|
### Hot Path compatibility
|
|
17
19
|
|
|
18
20
|
- **Mode**: Default is `SHADOW` (Hot Path returns ALLOW with reason codes for would-block decisions). Set `mode: 'ENFORCE'` or `GATE_MODE=ENFORCE` for real BLOCK responses.
|
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Metrics Collector for SDK
|
|
3
|
+
*
|
|
4
|
+
* Collects counters and latency metrics for observability.
|
|
5
|
+
*/
|
|
6
|
+
interface Metrics {
|
|
7
|
+
requestsTotal: number;
|
|
8
|
+
allowedTotal: number;
|
|
9
|
+
blockedTotal: number;
|
|
10
|
+
stepupTotal: number;
|
|
11
|
+
timeoutsTotal: number;
|
|
12
|
+
errorsTotal: number;
|
|
13
|
+
circuitBreakerOpenTotal: number;
|
|
14
|
+
wouldBlockTotal: number;
|
|
15
|
+
failOpenTotal: number;
|
|
16
|
+
latencyMs: number[];
|
|
17
|
+
}
|
|
18
|
+
type MetricsHook = (metrics: Metrics) => void | Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Metrics Collector
|
|
21
|
+
*/
|
|
22
|
+
declare class MetricsCollector {
|
|
23
|
+
private requestsTotal;
|
|
24
|
+
private allowedTotal;
|
|
25
|
+
private blockedTotal;
|
|
26
|
+
private stepupTotal;
|
|
27
|
+
private timeoutsTotal;
|
|
28
|
+
private errorsTotal;
|
|
29
|
+
private circuitBreakerOpenTotal;
|
|
30
|
+
private wouldBlockTotal;
|
|
31
|
+
private failOpenTotal;
|
|
32
|
+
private latencyMs;
|
|
33
|
+
private readonly maxSamples;
|
|
34
|
+
private readonly hooks;
|
|
35
|
+
/**
|
|
36
|
+
* Record a request
|
|
37
|
+
*/
|
|
38
|
+
recordRequest(decision: 'ALLOW' | 'BLOCK' | 'REQUIRE_STEP_UP' | 'WOULD_BLOCK' | 'FAIL_OPEN', latencyMs: number): void;
|
|
39
|
+
/**
|
|
40
|
+
* Record a timeout
|
|
41
|
+
*/
|
|
42
|
+
recordTimeout(): void;
|
|
43
|
+
/**
|
|
44
|
+
* Record an error
|
|
45
|
+
*/
|
|
46
|
+
recordError(): void;
|
|
47
|
+
/**
|
|
48
|
+
* Record circuit breaker open
|
|
49
|
+
*/
|
|
50
|
+
recordCircuitBreakerOpen(): void;
|
|
51
|
+
/**
|
|
52
|
+
* Record soft-enforce override (app chose to sign despite BLOCK decision)
|
|
53
|
+
*/
|
|
54
|
+
recordSoftBlockOverride(decision: 'ALLOW' | 'BLOCK'): void;
|
|
55
|
+
/**
|
|
56
|
+
* Get current metrics snapshot
|
|
57
|
+
*/
|
|
58
|
+
getMetrics(): Metrics;
|
|
59
|
+
/**
|
|
60
|
+
* Register a metrics hook (e.g., for Prometheus/OpenTelemetry export)
|
|
61
|
+
*/
|
|
62
|
+
registerHook(hook: MetricsHook): void;
|
|
63
|
+
/**
|
|
64
|
+
* Emit metrics to all registered hooks
|
|
65
|
+
*/
|
|
66
|
+
private emitMetrics;
|
|
67
|
+
/**
|
|
68
|
+
* Reset all metrics
|
|
69
|
+
*/
|
|
70
|
+
reset(): void;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* BlockIntel Gate SDK - Type Contracts
|
|
75
|
+
*
|
|
76
|
+
* Type definitions for Gate Hot Path API v2 contracts.
|
|
77
|
+
* Internal SDK uses camelCase; mapping to/from API snake_case is handled internally.
|
|
78
|
+
*/
|
|
79
|
+
/**
|
|
80
|
+
* Transaction intent structure for evaluate request
|
|
81
|
+
*/
|
|
82
|
+
interface TransactionIntentV2 {
|
|
83
|
+
from: string;
|
|
84
|
+
to: string;
|
|
85
|
+
value?: string;
|
|
86
|
+
data?: string;
|
|
87
|
+
nonce?: number | string;
|
|
88
|
+
gasPrice?: string;
|
|
89
|
+
gasLimit?: string;
|
|
90
|
+
chainId?: number | string;
|
|
91
|
+
[key: string]: unknown;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Signing context metadata
|
|
95
|
+
*/
|
|
96
|
+
interface SigningContext {
|
|
97
|
+
signerId?: string;
|
|
98
|
+
source?: {
|
|
99
|
+
repo?: string;
|
|
100
|
+
workflow?: string;
|
|
101
|
+
environment?: string;
|
|
102
|
+
[key: string]: unknown;
|
|
103
|
+
};
|
|
104
|
+
wallet?: {
|
|
105
|
+
address: string;
|
|
106
|
+
type?: string;
|
|
107
|
+
[key: string]: unknown;
|
|
108
|
+
};
|
|
109
|
+
[key: string]: unknown;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Defense evaluate request (v2)
|
|
113
|
+
*/
|
|
114
|
+
interface DefenseEvaluateRequestV2 {
|
|
115
|
+
txIntent: TransactionIntentV2;
|
|
116
|
+
signingContext?: SigningContext;
|
|
117
|
+
requestId?: string;
|
|
118
|
+
timestampMs?: number;
|
|
119
|
+
/**
|
|
120
|
+
* Enable transaction simulation (optional, defaults to false)
|
|
121
|
+
*
|
|
122
|
+
* When true, Hot Path will simulate the transaction after static policy evaluation.
|
|
123
|
+
* Adds 300-800ms latency but provides additional security checks.
|
|
124
|
+
*/
|
|
125
|
+
simulate?: boolean;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Gate decision types
|
|
129
|
+
*/
|
|
130
|
+
type GateDecision = 'ALLOW' | 'BLOCK' | 'REQUIRE_STEP_UP';
|
|
131
|
+
/**
|
|
132
|
+
* Step-up metadata in evaluate response
|
|
133
|
+
*/
|
|
134
|
+
interface StepUpMetadata {
|
|
135
|
+
requestId: string;
|
|
136
|
+
ttlSeconds?: number;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Defense evaluate response (v2)
|
|
140
|
+
*/
|
|
141
|
+
interface DefenseEvaluateResponseV2 {
|
|
142
|
+
decision: GateDecision;
|
|
143
|
+
reasonCodes: string[];
|
|
144
|
+
policyVersion?: string;
|
|
145
|
+
correlationId?: string;
|
|
146
|
+
decisionId?: string;
|
|
147
|
+
stepUp?: StepUpMetadata;
|
|
148
|
+
/**
|
|
149
|
+
* Decision token (JWS HS256) binding decision to txDigest. Required in ENFORCE/HARD when requireDecisionToken.
|
|
150
|
+
*/
|
|
151
|
+
decisionToken?: string;
|
|
152
|
+
/**
|
|
153
|
+
* Unix seconds when decision token expires.
|
|
154
|
+
*/
|
|
155
|
+
expiresAt?: number;
|
|
156
|
+
/**
|
|
157
|
+
* SHA256(canonicalJson(txBinding)). Must match when signing.
|
|
158
|
+
*/
|
|
159
|
+
txDigest?: string;
|
|
160
|
+
/**
|
|
161
|
+
* Whether the decision was enforced (false in SHADOW mode)
|
|
162
|
+
*/
|
|
163
|
+
enforced?: boolean;
|
|
164
|
+
/**
|
|
165
|
+
* Whether shadow mode would have blocked (true if mode=SHADOW and decision=BLOCK)
|
|
166
|
+
*/
|
|
167
|
+
shadowWouldBlock?: boolean;
|
|
168
|
+
/**
|
|
169
|
+
* Gate mode used for this evaluation
|
|
170
|
+
*/
|
|
171
|
+
mode?: GateMode;
|
|
172
|
+
/**
|
|
173
|
+
* Metadata (evaluation latency, simulation, policy hash for pinning)
|
|
174
|
+
*/
|
|
175
|
+
metadata?: {
|
|
176
|
+
evaluationLatencyMs?: number;
|
|
177
|
+
policyHash?: string;
|
|
178
|
+
snapshotVersion?: number;
|
|
179
|
+
[key: string]: unknown;
|
|
180
|
+
};
|
|
181
|
+
/** True when evaluationMode was FIRE_AND_FORGET (optimistic ALLOW, attestation in background) */
|
|
182
|
+
fireAndForget?: boolean;
|
|
183
|
+
/** Warning message (e.g. SOFT_ENFORCE override) */
|
|
184
|
+
warning?: string;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Step-up status types
|
|
188
|
+
*/
|
|
189
|
+
type GateStepUpStatus = 'PENDING' | 'APPROVED' | 'DENIED' | 'EXPIRED';
|
|
190
|
+
/**
|
|
191
|
+
* Step-up status response
|
|
192
|
+
*/
|
|
193
|
+
interface StepUpStatusResponse {
|
|
194
|
+
status: GateStepUpStatus;
|
|
195
|
+
tenantId: string;
|
|
196
|
+
requestId: string;
|
|
197
|
+
decision?: string;
|
|
198
|
+
reasonCodes?: string[];
|
|
199
|
+
correlationId?: string;
|
|
200
|
+
expiresAtMs?: number;
|
|
201
|
+
ttl?: number;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Final result from awaitStepUpDecision
|
|
205
|
+
*/
|
|
206
|
+
interface StepUpFinalResult {
|
|
207
|
+
status: GateStepUpStatus;
|
|
208
|
+
requestId: string;
|
|
209
|
+
elapsedMs: number;
|
|
210
|
+
decision?: string;
|
|
211
|
+
reasonCodes?: string[];
|
|
212
|
+
correlationId?: string;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Fail-safe mode for SDK (deprecated - use onConnectionFailure instead)
|
|
216
|
+
*/
|
|
217
|
+
type FailSafeMode = 'ALLOW_ON_TIMEOUT' | 'BLOCK_ON_TIMEOUT' | 'BLOCK_ON_ANOMALY';
|
|
218
|
+
/**
|
|
219
|
+
* Gate Mode
|
|
220
|
+
*
|
|
221
|
+
* SHADOW: Evaluate and log, but always allow (monitor-only)
|
|
222
|
+
* SOFT_ENFORCE: Evaluate and return BLOCK decisions but let app override (no throw)
|
|
223
|
+
* ENFORCE: Evaluate and enforce decisions (block if policy violation)
|
|
224
|
+
*/
|
|
225
|
+
type GateMode = 'SHADOW' | 'SOFT_ENFORCE' | 'ENFORCE';
|
|
226
|
+
/**
|
|
227
|
+
* Evaluation mode (attestation pitch: "Gate attests in parallel")
|
|
228
|
+
*
|
|
229
|
+
* BLOCKING: await gate.evaluate() blocks until response (default)
|
|
230
|
+
* FIRE_AND_FORGET: evaluate() returns immediately with optimistic ALLOW; attestation in background
|
|
231
|
+
* PARALLEL: same as BLOCKING; caller can await the returned promise later after doing other work
|
|
232
|
+
*/
|
|
233
|
+
type EvaluationMode = 'BLOCKING' | 'FIRE_AND_FORGET' | 'PARALLEL';
|
|
234
|
+
/**
|
|
235
|
+
* Connection Failure Strategy
|
|
236
|
+
*
|
|
237
|
+
* FAIL_OPEN: Allow transaction if hotpath is unreachable
|
|
238
|
+
* FAIL_CLOSED: Block transaction if hotpath is unreachable (security-first)
|
|
239
|
+
*/
|
|
240
|
+
type ConnectionFailureStrategy = 'FAIL_OPEN' | 'FAIL_CLOSED';
|
|
241
|
+
/**
|
|
242
|
+
* Circuit breaker configuration
|
|
243
|
+
*/
|
|
244
|
+
interface CircuitBreakerConfig {
|
|
245
|
+
tripAfterConsecutiveFailures?: number;
|
|
246
|
+
coolDownMs?: number;
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* SDK client configuration
|
|
250
|
+
*/
|
|
251
|
+
interface GateClientConfig {
|
|
252
|
+
baseUrl: string;
|
|
253
|
+
tenantId: string;
|
|
254
|
+
auth: {
|
|
255
|
+
mode: 'hmac';
|
|
256
|
+
keyId: string;
|
|
257
|
+
secret: string;
|
|
258
|
+
} | {
|
|
259
|
+
mode: 'apiKey';
|
|
260
|
+
apiKey: string;
|
|
261
|
+
};
|
|
262
|
+
timeoutMs?: number;
|
|
263
|
+
userAgent?: string;
|
|
264
|
+
clockSkewMs?: number;
|
|
265
|
+
retries?: number;
|
|
266
|
+
failSafeMode?: FailSafeMode;
|
|
267
|
+
/**
|
|
268
|
+
* Gate mode (default: SHADOW for safety)
|
|
269
|
+
*
|
|
270
|
+
* SHADOW: Monitor-only - evaluate and log, but always allow
|
|
271
|
+
* ENFORCE: Enforce decisions - block if policy violation
|
|
272
|
+
*/
|
|
273
|
+
mode?: GateMode;
|
|
274
|
+
/** Evaluation mode: BLOCKING (default), FIRE_AND_FORGET (return immediately, attest in background), PARALLEL */
|
|
275
|
+
evaluationMode?: EvaluationMode;
|
|
276
|
+
/**
|
|
277
|
+
* Connection failure strategy (default: based on mode)
|
|
278
|
+
*
|
|
279
|
+
* FAIL_OPEN: Allow on connection failure (default in SHADOW mode)
|
|
280
|
+
* FAIL_CLOSED: Block on connection failure (default in ENFORCE mode)
|
|
281
|
+
*/
|
|
282
|
+
onConnectionFailure?: ConnectionFailureStrategy;
|
|
283
|
+
circuitBreaker?: CircuitBreakerConfig;
|
|
284
|
+
enableStepUp?: boolean;
|
|
285
|
+
stepUp?: {
|
|
286
|
+
pollingIntervalMs?: number;
|
|
287
|
+
maxWaitMs?: number;
|
|
288
|
+
treatRequireStepUpAsBlockWhenDisabled?: boolean;
|
|
289
|
+
};
|
|
290
|
+
onMetrics?: (metrics: Metrics) => void | Promise<void>;
|
|
291
|
+
signerId?: string;
|
|
292
|
+
heartbeatRefreshIntervalSeconds?: number;
|
|
293
|
+
/** API key for Control Plane heartbeat endpoint (x-gate-heartbeat-key). Required when not local. Fallback: GATE_HEARTBEAT_KEY env. */
|
|
294
|
+
heartbeatApiKey?: string;
|
|
295
|
+
/** When true or GATE_SDK_DEBUG=1, log sanitized request/response (no secrets, no body values). */
|
|
296
|
+
debug?: boolean;
|
|
297
|
+
/**
|
|
298
|
+
* Break-glass token (optional, for emergency override)
|
|
299
|
+
*
|
|
300
|
+
* JWT token issued by Control Plane for time-bound policy bypass.
|
|
301
|
+
* Only valid if explicitly activated via break-glass endpoint.
|
|
302
|
+
*/
|
|
303
|
+
breakglassToken?: string;
|
|
304
|
+
/**
|
|
305
|
+
* Local development mode - disables auth, heartbeat, and break-glass
|
|
306
|
+
* Set to true when using gate-local emulator
|
|
307
|
+
*/
|
|
308
|
+
local?: boolean;
|
|
309
|
+
/**
|
|
310
|
+
* Enforcement mode (default: SOFT)
|
|
311
|
+
*
|
|
312
|
+
* SOFT: Warns if IAM permission risk detected, but allows initialization
|
|
313
|
+
* HARD: Blocks initialization if IAM permission risk detected (unless override set)
|
|
314
|
+
*/
|
|
315
|
+
enforcementMode?: 'SOFT' | 'HARD';
|
|
316
|
+
/**
|
|
317
|
+
* Allow initialization even if IAM permission risk detected
|
|
318
|
+
*
|
|
319
|
+
* Default: false in HARD mode, true in SOFT mode
|
|
320
|
+
*
|
|
321
|
+
* WARNING: Setting to true in HARD mode defeats the purpose of hard enforcement.
|
|
322
|
+
* Only use during migration periods.
|
|
323
|
+
*/
|
|
324
|
+
allowInsecureKmsSignPermission?: boolean;
|
|
325
|
+
/**
|
|
326
|
+
* Optional: Specific KMS key IDs to check for permission risk
|
|
327
|
+
* If not provided, checks for any kms:Sign permission
|
|
328
|
+
*/
|
|
329
|
+
kmsKeyIds?: string[];
|
|
330
|
+
/**
|
|
331
|
+
* Require decision token before sign (default: true when mode=ENFORCE or enforcementMode=HARD).
|
|
332
|
+
* When true, evaluate() must return decisionToken/txDigest for ALLOW; sign path verifies digest match.
|
|
333
|
+
* Override with GATE_REQUIRE_DECISION_TOKEN env.
|
|
334
|
+
*/
|
|
335
|
+
requireDecisionToken?: boolean;
|
|
336
|
+
/**
|
|
337
|
+
* Optional policy pinning: if set, evaluate response must have matching policyHash (from metadata).
|
|
338
|
+
* Mismatch → treat as BLOCK locally (do not call signer). Defense against Control Plane compromise.
|
|
339
|
+
*/
|
|
340
|
+
expectedPolicyHash?: string;
|
|
341
|
+
/**
|
|
342
|
+
* Optional snapshot version pinning: if set, evaluate response must have matching snapshotVersion (from metadata).
|
|
343
|
+
* Mismatch → treat as BLOCK locally.
|
|
344
|
+
*/
|
|
345
|
+
expectedSnapshotVersion?: number;
|
|
346
|
+
/**
|
|
347
|
+
* Optional: public key (PEM) to verify RS256 decision tokens. When set, ALLOW responses with decisionToken
|
|
348
|
+
* are signature-verified; invalid or wrong-key tokens are treated as BLOCK.
|
|
349
|
+
*/
|
|
350
|
+
decisionTokenPublicKey?: string;
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Post-sign attestation request (zero-latency audit: attest after signing)
|
|
354
|
+
*/
|
|
355
|
+
interface AttestCompletedRequest {
|
|
356
|
+
txIntent: TransactionIntentV2;
|
|
357
|
+
signature: {
|
|
358
|
+
signature: string;
|
|
359
|
+
signerId: string;
|
|
360
|
+
keyId: string;
|
|
361
|
+
algorithm: string;
|
|
362
|
+
};
|
|
363
|
+
signingContext?: SigningContext;
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Post-sign attestation response
|
|
367
|
+
*/
|
|
368
|
+
interface AttestCompletedResponse {
|
|
369
|
+
decision: 'ALLOW' | 'POLICY_VIOLATION_DETECTED';
|
|
370
|
+
decisionId: string;
|
|
371
|
+
correlationId: string;
|
|
372
|
+
reasonCodes: string[];
|
|
373
|
+
attestation: {
|
|
374
|
+
signatureHash: string;
|
|
375
|
+
attestedAt: number;
|
|
376
|
+
attestationToken?: string;
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
export { type AttestCompletedRequest as A, type DefenseEvaluateRequestV2 as D, type EvaluationMode as E, type GateClientConfig as G, MetricsCollector as M, type StepUpStatusResponse as S, type TransactionIntentV2 as T, type DefenseEvaluateResponseV2 as a, type StepUpFinalResult as b, type SigningContext as c, type AttestCompletedResponse as d, type GateDecision as e, type GateMode as f, type StepUpMetadata as g, type GateStepUpStatus as h };
|