@7h3/protocol 0.5.0 → 0.5.2
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 +6 -1317
- package/agentAdapter.d.ts +26 -0
- package/auditLog.d.ts +54 -0
- package/capability.d.ts +67 -0
- package/cborCodec.d.ts +34 -0
- package/conformanceVectors.d.ts +20 -0
- package/encryption.d.ts +85 -0
- package/envelopeCbor.d.ts +33 -0
- package/frameworkAdapters.d.ts +72 -0
- package/gateway.d.ts +53 -0
- package/grpcBinding.d.ts +29 -0
- package/httpBinding.d.ts +50 -0
- package/index.d.ts +39 -0
- package/index.js +3670 -0
- package/keyInfra.d.ts +64 -0
- package/keyRegistry.d.ts +9 -0
- package/keyRotation.d.ts +20 -0
- package/mcpGateway.d.ts +37 -0
- package/mcpTransports.d.ts +62 -0
- package/mcpWrapper.d.ts +83 -0
- package/otel.d.ts +65 -0
- package/package.json +13 -121
- package/policyEnforcer.d.ts +50 -0
- package/policyTelemetryFeedback.d.ts +11 -0
- package/{src/protocol.d.ts → protocol.d.ts} +6 -2
- package/protocolAgent.d.ts +58 -0
- package/protocolBinary.d.ts +8 -0
- package/protocolCapabilities.d.ts +24 -0
- package/protocolReplay.d.ts +35 -0
- package/protocolTransport.d.ts +73 -0
- package/queueBinding.d.ts +43 -0
- package/rateLimiter.d.ts +18 -0
- package/{src/redisClient.ts → redisClient.d.ts} +25 -75
- package/replayStores.d.ts +98 -0
- package/revocation.d.ts +71 -0
- package/routePolicy.d.ts +30 -0
- package/runtimePolicy.d.ts +24 -0
- package/runtimePolicyManager.d.ts +15 -0
- package/runtimePolicyPresets.d.ts +11 -0
- package/signedResponse.d.ts +21 -0
- package/stream.d.ts +59 -0
- package/telemetry.d.ts +79 -0
- package/webhookBinding.d.ts +30 -0
- package/wsBinding.d.ts +52 -0
- package/.dockerignore +0 -19
- package/.github/dependabot.yml +0 -32
- package/.github/workflows/ci.yml +0 -31
- package/.github/workflows/publish.yml +0 -59
- package/.github/workflows/scorecard.yml +0 -37
- package/7h3.example.yaml +0 -125
- package/CHANGELOG.md +0 -152
- package/CONTRIBUTING.md +0 -82
- package/Dockerfile +0 -73
- package/GOVERNANCE.md +0 -62
- package/SECURITY.md +0 -70
- package/bench-results/replay-cache-full-1777891033256.json +0 -10
- package/bench-results/replay-cache-full-1777896317488.json +0 -10
- package/bench-results/replay-cache-full-1777900993184.json +0 -10
- package/bench-results/replay-cache-full-1777901019285.json +0 -10
- package/bench-results/replay-cache-quick-1777870170126.json +0 -10
- package/bench-results/signature-profiles-quick-1775875160079.json +0 -85
- package/bench-results/signature-profiles-quick-1775983539716.json +0 -85
- package/bench-results/signature-profiles-quick-1776237913190.json +0 -85
- package/bench-results/wire-codecs-full-1777891019803.json +0 -93
- package/bench-results/wire-codecs-full-1777896260964.json +0 -93
- package/bench-results/wire-codecs-full-1777901004247.json +0 -93
- package/bench-results/wire-codecs-quick-1775972879056.json +0 -93
- package/bench-results/wire-codecs-quick-1775983541111.json +0 -93
- package/bench-results/wire-codecs-quick-1776237914299.json +0 -93
- package/bench-results/wire-codecs-quick-1777841285236.json +0 -93
- package/bench-results/wire-codecs-quick-1777841321772.json +0 -93
- package/bench-results/wire-codecs-quick-1777841330408.json +0 -93
- package/bench-results/wire-codecs-quick-1777852886082.json +0 -93
- package/bench-results/wire-codecs-quick-1777852988773.json +0 -93
- package/bench-results/wire-codecs-quick-1777870188095.json +0 -93
- package/bench-results/wire-codecs-quick-1777870263918.json +0 -93
- package/bench-results/wire-codecs-quick-1777870455034.json +0 -93
- package/bench-results/wire-codecs-quick-1778816163081.json +0 -93
- package/bench-results/wire-codecs-quick-1778843936130.json +0 -93
- package/bin/7h3.ts +0 -406
- package/conformance/7h3_v0_1.json +0 -77
- package/conformance/7h3_v0_1_binary.json +0 -20
- package/conformance/aip_v0_1_binary.json +0 -20
- package/docker-compose.yaml +0 -77
- package/docs/ADOPTION_PLAN.md +0 -120
- package/docs/AGENTS.md +0 -77
- package/docs/AIP_RFC_v0.1.md +0 -97
- package/docs/AI_DECISION_CARD.md +0 -122
- package/docs/AI_RUNTIME_POLICY.json +0 -126
- package/docs/AI_RUNTIME_POLICY.yaml +0 -110
- package/docs/BACKPRESSURE_TUNING.md +0 -65
- package/docs/BENCHMARK_CLAIM_MATRIX.md +0 -42
- package/docs/BENCHMARK_REPORT_TEMPLATE.md +0 -169
- package/docs/BINARY_CODEC_BENCH.md +0 -23
- package/docs/CLEAN_CLONE_RUNBOOK.md +0 -36
- package/docs/CLOCK_SKEW_POLICY.md +0 -30
- package/docs/DISTRIBUTED_REPLAY.md +0 -142
- package/docs/FUZZ_CAMPAIGN.md +0 -121
- package/docs/GATEWAY.md +0 -195
- package/docs/KEY_MANAGEMENT_POLICY.md +0 -53
- package/docs/KEY_REVOCATION.md +0 -69
- package/docs/MCP_WRAPPER.md +0 -159
- package/docs/MIGRATION_GUIDE.md +0 -40
- package/docs/OPERATORS.md +0 -184
- package/docs/PERF_REGRESSION_POLICY.md +0 -34
- package/docs/PROJECT_EXAMINATION_2026-05-31.md +0 -219
- package/docs/RELEASE_BENCHMARK_REPORT_2026-05-15.md +0 -135
- package/docs/RELEASE_GATE.md +0 -25
- package/docs/RELEASE_NOTES_v0.1.0.md +0 -54
- package/docs/SECURITY_REVIEW_2026-06-05.md +0 -165
- package/docs/TELEMETRY.md +0 -41
- package/docs/THREAT_MODEL.md +0 -89
- package/docs/VERSIONING_POLICY.md +0 -30
- package/docs/assets/banner-github.png +0 -0
- package/docs/assets/banner.png +0 -0
- package/docs/assets/banner.svg +0 -123
- package/eslint.config.js +0 -15
- package/fuzz/ts/harness-decode.ts +0 -136
- package/fuzz/ts/harness-verify.ts +0 -121
- package/fuzz/ts/run.ts +0 -35
- package/mcp-server/README.md +0 -38
- package/mcp-server/package-lock.json +0 -1187
- package/mcp-server/package.json +0 -35
- package/mcp-server/src/index.ts +0 -236
- package/mcp-server/tsconfig.json +0 -14
- package/scripts/aip-framework-quickstart.ts +0 -110
- package/scripts/aip-mcp-gateway.ts +0 -38
- package/scripts/aip-mcp-wrap-demo.ts +0 -72
- package/scripts/aip-quickstart.ts +0 -60
- package/scripts/bench-diff.ts +0 -118
- package/scripts/bench-protocol-e2e.ts +0 -937
- package/scripts/bench-protocol-openloop.ts +0 -1397
- package/scripts/bench-replay-cache.ts +0 -76
- package/scripts/bench-signature-profiles.ts +0 -180
- package/scripts/bench-wire-codecs.ts +0 -161
- package/scripts/build-binary-conformance.ts +0 -36
- package/scripts/build-release-dashboard.ts +0 -175
- package/scripts/canary-rollout.ts +0 -38
- package/scripts/mcpGatewayCli.test.ts +0 -116
- package/scripts/prepare-aip-package.ts +0 -88
- package/scripts/regen-conformance-sigs.ts +0 -18
- package/scripts/release-gate.ts +0 -19
- package/scripts/validate-runtime-policy.ts +0 -18
- package/sdk/browser/index.test.ts +0 -162
- package/sdk/browser/index.ts +0 -257
- package/sdk/browser/package.json +0 -13
- package/sdk/go/cbor.go +0 -551
- package/sdk/go/cbor_test.go +0 -232
- package/sdk/go/encryption.go +0 -280
- package/sdk/go/encryption_test.go +0 -318
- package/sdk/go/go.mod +0 -7
- package/sdk/go/go.sum +0 -4
- package/sdk/go/http.go +0 -135
- package/sdk/go/protocol.go +0 -324
- package/sdk/go/protocol_test.go +0 -334
- package/sdk/go/replay.go +0 -121
- package/sdk/go/replay_test.go +0 -149
- package/sdk/go/webhook.go +0 -136
- package/sdk/pq/package-lock.json +0 -1358
- package/sdk/pq/package.json +0 -42
- package/sdk/pq/src/index.test.ts +0 -143
- package/sdk/pq/src/index.ts +0 -166
- package/sdk/pq/tsconfig.json +0 -14
- package/sdk/pq/vitest.config.ts +0 -7
- package/sdk/python/README.md +0 -18
- package/sdk/python/protocol_7h3/__init__.py +0 -46
- package/sdk/python/protocol_7h3/encryption.py +0 -252
- package/sdk/python/protocol_7h3/http.py +0 -212
- package/sdk/python/protocol_7h3/keys.py +0 -149
- package/sdk/python/protocol_7h3/pq.py +0 -244
- package/sdk/python/protocol_7h3/protocol.py +0 -525
- package/sdk/python/protocol_7h3/queue.py +0 -118
- package/sdk/python/protocol_7h3/replay.py +0 -98
- package/sdk/python/protocol_7h3/webhook.py +0 -116
- package/sdk/python/pyproject.toml +0 -40
- package/sdk/python/tests/test_conformance.py +0 -110
- package/sdk/python/tests/test_encryption.py +0 -206
- package/sdk/python/tests/test_http.py +0 -305
- package/sdk/python/tests/test_keys.py +0 -417
- package/sdk/python/tests/test_queue.py +0 -120
- package/sdk/python/tests/test_webhook.py +0 -345
- package/sdk/rust/Cargo.lock +0 -371
- package/sdk/rust/Cargo.toml +0 -25
- package/sdk/rust/README.md +0 -31
- package/sdk/rust/fuzz/Cargo.toml +0 -29
- package/sdk/rust/fuzz/fuzz_targets/fuzz_canonicalize.rs +0 -46
- package/sdk/rust/fuzz/fuzz_targets/fuzz_decode.rs +0 -11
- package/sdk/rust/src/bin/aip_mcp_gateway.rs +0 -59
- package/sdk/rust/src/http.rs +0 -145
- package/sdk/rust/src/keys.rs +0 -161
- package/sdk/rust/src/lib.rs +0 -688
- package/sdk/rust/src/queue.rs +0 -79
- package/sdk/rust/src/webhook.rs +0 -86
- package/sdk/rust/tests/conformance.rs +0 -148
- package/sdk/rust/tests/gateway.rs +0 -130
- package/sdk/rust/tests/http_webhook_queue.rs +0 -201
- package/sdk/rust/tests/keys.rs +0 -189
- package/sdk/threshold/index.d.ts +0 -68
- package/sdk/threshold/index.d.ts.map +0 -1
- package/sdk/threshold/index.js +0 -254
- package/sdk/threshold/package-lock.json +0 -1361
- package/sdk/threshold/package.json +0 -39
- package/sdk/threshold/src/index.d.ts +0 -68
- package/sdk/threshold/src/index.d.ts.map +0 -1
- package/sdk/threshold/src/index.js +0 -254
- package/sdk/threshold/src/index.test.ts +0 -238
- package/sdk/threshold/src/index.ts +0 -355
- package/sdk/threshold/tsconfig.json +0 -19
- package/sdk/threshold/vitest.config.ts +0 -12
- package/src/agentAdapter.test.ts +0 -48
- package/src/agentAdapter.ts +0 -56
- package/src/auditLog.test.ts +0 -145
- package/src/auditLog.ts +0 -147
- package/src/capability.test.ts +0 -504
- package/src/capability.ts +0 -380
- package/src/cborCodec.test.ts +0 -263
- package/src/cborCodec.ts +0 -339
- package/src/conformance.test.ts +0 -136
- package/src/conformanceVectors.ts +0 -99
- package/src/encryption.test.ts +0 -206
- package/src/encryption.ts +0 -245
- package/src/envelopeCbor.ts +0 -140
- package/src/frameworkAdapters.test.ts +0 -290
- package/src/frameworkAdapters.ts +0 -261
- package/src/gateway.test.ts +0 -343
- package/src/gateway.ts +0 -246
- package/src/grpcBinding.test.ts +0 -211
- package/src/grpcBinding.ts +0 -103
- package/src/httpBinding.test.ts +0 -376
- package/src/httpBinding.ts +0 -189
- package/src/index.ts +0 -39
- package/src/keyInfra.test.ts +0 -278
- package/src/keyInfra.ts +0 -228
- package/src/keyRegistry.ts +0 -59
- package/src/keyRotation.test.ts +0 -78
- package/src/keyRotation.ts +0 -72
- package/src/mcpGateway.test.ts +0 -129
- package/src/mcpGateway.ts +0 -250
- package/src/mcpTransports.test.ts +0 -92
- package/src/mcpTransports.ts +0 -169
- package/src/mcpWrapper.test.ts +0 -179
- package/src/mcpWrapper.ts +0 -206
- package/src/otel.ts +0 -136
- package/src/policyEnforcer.test.ts +0 -99
- package/src/policyEnforcer.ts +0 -169
- package/src/policyTelemetryFeedback.test.ts +0 -25
- package/src/policyTelemetryFeedback.ts +0 -38
- package/src/protocol.bench.ts +0 -37
- package/src/protocol.d.ts.map +0 -1
- package/src/protocol.js +0 -294
- package/src/protocol.test.ts +0 -155
- package/src/protocol.ts +0 -414
- package/src/protocolAgent.test.ts +0 -105
- package/src/protocolAgent.ts +0 -169
- package/src/protocolBinary.test.ts +0 -165
- package/src/protocolBinary.ts +0 -312
- package/src/protocolCapabilities.ts +0 -70
- package/src/protocolFuzz.advanced.test.ts +0 -235
- package/src/protocolFuzz.test.ts +0 -111
- package/src/protocolNegative.test.ts +0 -97
- package/src/protocolReplay.test.ts +0 -71
- package/src/protocolReplay.ts +0 -194
- package/src/protocolTransport.test.ts +0 -556
- package/src/protocolTransport.ts +0 -483
- package/src/queueBinding.test.ts +0 -130
- package/src/queueBinding.ts +0 -102
- package/src/rateLimiter.test.ts +0 -96
- package/src/rateLimiter.ts +0 -46
- package/src/redisIntegration.test.ts +0 -134
- package/src/replayStores.test.ts +0 -273
- package/src/replayStores.ts +0 -215
- package/src/revocation.test.ts +0 -98
- package/src/revocation.ts +0 -0
- package/src/routePolicy.test.ts +0 -87
- package/src/routePolicy.ts +0 -72
- package/src/runtimePolicy.test.ts +0 -49
- package/src/runtimePolicy.ts +0 -81
- package/src/runtimePolicyManager.test.ts +0 -29
- package/src/runtimePolicyManager.ts +0 -50
- package/src/runtimePolicyPresets.ts +0 -43
- package/src/signedResponse.test.ts +0 -111
- package/src/signedResponse.ts +0 -83
- package/src/stream.test.ts +0 -254
- package/src/stream.ts +0 -417
- package/src/telemetry.test.ts +0 -251
- package/src/telemetry.ts +0 -299
- package/src/webhookBinding.test.ts +0 -144
- package/src/webhookBinding.ts +0 -115
- package/src/wsBinding.test.ts +0 -221
- package/src/wsBinding.ts +0 -200
- package/tsconfig.json +0 -15
- package/tsconfig.lib.json +0 -23
- package/vite.lib.config.ts +0 -16
- package/vitest.config.ts +0 -11
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { WireFormat } from './protocolTransport';
|
|
2
|
+
export type AckMode = 'fast' | 'receipt';
|
|
3
|
+
export interface AipCapabilities {
|
|
4
|
+
agent: string;
|
|
5
|
+
capabilities: string[];
|
|
6
|
+
wireFormats: WireFormat[];
|
|
7
|
+
batchMax: number;
|
|
8
|
+
ackModes: AckMode[];
|
|
9
|
+
}
|
|
10
|
+
export interface NegotiatedAipCapabilities {
|
|
11
|
+
wireFormat: WireFormat;
|
|
12
|
+
batchMax: number;
|
|
13
|
+
ackMode: AckMode;
|
|
14
|
+
}
|
|
15
|
+
export declare function createAipCapabilities(input: {
|
|
16
|
+
agent: string;
|
|
17
|
+
capabilities?: string[];
|
|
18
|
+
wireFormats?: WireFormat[];
|
|
19
|
+
batchMax?: number;
|
|
20
|
+
ackModes?: AckMode[];
|
|
21
|
+
}): AipCapabilities;
|
|
22
|
+
export declare function encodeAipCapabilities(capabilities: AipCapabilities): string;
|
|
23
|
+
export declare function parseAipCapabilities(raw: string): AipCapabilities | null;
|
|
24
|
+
export declare function negotiateAipCapabilities(local: AipCapabilities, remote: AipCapabilities): NegotiatedAipCapabilities;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { ProtocolEnvelope } from './protocol';
|
|
2
|
+
export interface ReplayCheckResult {
|
|
3
|
+
ok: boolean;
|
|
4
|
+
reason?: string;
|
|
5
|
+
}
|
|
6
|
+
export interface ReplayCache {
|
|
7
|
+
consume(envelope: ProtocolEnvelope, nowMs?: number): ReplayCheckResult | Promise<ReplayCheckResult>;
|
|
8
|
+
consumeMany?(envelopes: ProtocolEnvelope[], nowMs?: number): ReplayCheckResult[] | Promise<ReplayCheckResult[]>;
|
|
9
|
+
}
|
|
10
|
+
export interface DistributedReplayStore {
|
|
11
|
+
reserve(key: string, expiresAtMs: number, nowMs: number): boolean | Promise<boolean>;
|
|
12
|
+
/** Optional batch reserve; enables single round-trip checks for batched envelopes. */
|
|
13
|
+
reserveMany?(entries: Array<{
|
|
14
|
+
key: string;
|
|
15
|
+
expiresAtMs: number;
|
|
16
|
+
}>, nowMs: number): boolean[] | Promise<boolean[]>;
|
|
17
|
+
}
|
|
18
|
+
export declare class InMemoryReplayCache implements ReplayCache {
|
|
19
|
+
private readonly entries;
|
|
20
|
+
private readonly maxEntries;
|
|
21
|
+
private readonly expiries;
|
|
22
|
+
constructor(maxEntries?: number);
|
|
23
|
+
private makeKey;
|
|
24
|
+
prune(nowMs?: number): void;
|
|
25
|
+
private evictOne;
|
|
26
|
+
consume(envelope: ProtocolEnvelope, nowMs?: number): ReplayCheckResult;
|
|
27
|
+
consumeMany(envelopes: ProtocolEnvelope[], nowMs?: number): ReplayCheckResult[];
|
|
28
|
+
}
|
|
29
|
+
export declare class DistributedReplayCache implements ReplayCache {
|
|
30
|
+
private readonly store;
|
|
31
|
+
constructor(store: DistributedReplayStore);
|
|
32
|
+
private makeKey;
|
|
33
|
+
consume(envelope: ProtocolEnvelope, nowMs?: number): Promise<ReplayCheckResult>;
|
|
34
|
+
consumeMany(envelopes: ProtocolEnvelope[], nowMs?: number): Promise<ReplayCheckResult[]>;
|
|
35
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { type SignatureVerificationMaterial, type IntentKind, type ProtocolDiagnostic, type ProtocolEnvelope } from './protocol';
|
|
2
|
+
import { type ReplayCache } from './protocolReplay';
|
|
3
|
+
export type WireFormat = 'json' | 'compact' | 'binary';
|
|
4
|
+
export type BatchWireFormat = Exclude<WireFormat, 'binary'>;
|
|
5
|
+
export interface ReceiveEnvelopeOptions {
|
|
6
|
+
nowMs?: number;
|
|
7
|
+
requireSignature?: boolean;
|
|
8
|
+
maxClockSkewMs?: number;
|
|
9
|
+
replayCache?: ReplayCache;
|
|
10
|
+
verificationMaterialCache?: VerificationMaterialCache;
|
|
11
|
+
secretResolver?: (keyId: string, sender: string) => string | undefined | Promise<string | undefined>;
|
|
12
|
+
signatureResolver?: (signature: NonNullable<ProtocolEnvelope['signature']>, sender: string) => SignatureVerificationMaterial | undefined | Promise<SignatureVerificationMaterial | undefined>;
|
|
13
|
+
telemetry?: (event: TransportTelemetryEvent) => void | Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
export interface ReceiveEnvelopeBatchOptions extends ReceiveEnvelopeOptions {
|
|
16
|
+
batchConcurrency?: number;
|
|
17
|
+
}
|
|
18
|
+
export interface TransportTelemetryEvent {
|
|
19
|
+
phase: 'decoded' | 'rejected_clock_skew' | 'rejected_validation' | 'rejected_replay' | 'rejected_missing_signature' | 'rejected_missing_material' | 'rejected_bad_signature' | 'batch_summary' | 'accepted';
|
|
20
|
+
nowMs: number;
|
|
21
|
+
sender?: string;
|
|
22
|
+
messageId?: string;
|
|
23
|
+
reason?: string;
|
|
24
|
+
}
|
|
25
|
+
export interface ReceiveEnvelopeResult {
|
|
26
|
+
ok: boolean;
|
|
27
|
+
diagnostics: ProtocolDiagnostic[];
|
|
28
|
+
envelope: ProtocolEnvelope | null;
|
|
29
|
+
}
|
|
30
|
+
export interface VerificationMaterialCache {
|
|
31
|
+
get(key: string, nowMs?: number): SignatureVerificationMaterial | undefined;
|
|
32
|
+
set(key: string, material: SignatureVerificationMaterial, expiresAtMs: number): void;
|
|
33
|
+
delete?(key: string): void;
|
|
34
|
+
}
|
|
35
|
+
export declare class InMemoryVerificationMaterialCache implements VerificationMaterialCache {
|
|
36
|
+
private readonly entries;
|
|
37
|
+
private readonly maxEntries;
|
|
38
|
+
constructor(maxEntries?: number);
|
|
39
|
+
get(key: string, nowMs?: number): SignatureVerificationMaterial | undefined;
|
|
40
|
+
set(key: string, material: SignatureVerificationMaterial, expiresAtMs: number): void;
|
|
41
|
+
delete(key: string): void;
|
|
42
|
+
}
|
|
43
|
+
export type WireEnvelope = string | Uint8Array;
|
|
44
|
+
export declare function decodeEnvelope(raw: WireEnvelope): ReceiveEnvelopeResult;
|
|
45
|
+
export declare function encodeEnvelope(envelope: ProtocolEnvelope, format: 'binary'): Uint8Array;
|
|
46
|
+
export declare function encodeEnvelope(envelope: ProtocolEnvelope, format?: 'json' | 'compact'): string;
|
|
47
|
+
export declare function encodeEnvelope(envelope: ProtocolEnvelope, format: WireFormat): WireEnvelope;
|
|
48
|
+
export declare function encodeEnvelopeBatch(envelopes: ProtocolEnvelope[], format?: BatchWireFormat): string;
|
|
49
|
+
export declare function decodeEnvelopeBatch(raw: string): ReceiveEnvelopeResult[];
|
|
50
|
+
export declare function receiveEnvelope(input: WireEnvelope | ProtocolEnvelope, options?: ReceiveEnvelopeOptions): Promise<ReceiveEnvelopeResult>;
|
|
51
|
+
export declare function receiveEnvelopeBatch(input: string | Array<WireEnvelope | ProtocolEnvelope>, options?: ReceiveEnvelopeBatchOptions): Promise<ReceiveEnvelopeResult[]>;
|
|
52
|
+
export declare class SessionTransport {
|
|
53
|
+
private readonly options;
|
|
54
|
+
constructor(options?: Omit<ReceiveEnvelopeOptions, 'replayCache'> & {
|
|
55
|
+
replayCache?: ReplayCache;
|
|
56
|
+
});
|
|
57
|
+
receive(input: WireEnvelope | ProtocolEnvelope, nowMs?: number): Promise<ReceiveEnvelopeResult>;
|
|
58
|
+
receiveBatch(input: string | Array<WireEnvelope | ProtocolEnvelope>, nowMs?: number): Promise<ReceiveEnvelopeResult[]>;
|
|
59
|
+
}
|
|
60
|
+
export declare function createSignedMessage(input: {
|
|
61
|
+
sender: string;
|
|
62
|
+
recipient?: string;
|
|
63
|
+
intent: IntentKind;
|
|
64
|
+
content: string;
|
|
65
|
+
capability?: string;
|
|
66
|
+
correlationId?: string;
|
|
67
|
+
ttlMs?: number;
|
|
68
|
+
messageId?: string;
|
|
69
|
+
nonce?: string;
|
|
70
|
+
nowMs?: number;
|
|
71
|
+
secret: string;
|
|
72
|
+
keyId?: string;
|
|
73
|
+
}): Promise<ProtocolEnvelope>;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { type ProtocolEnvelope } from './protocol';
|
|
2
|
+
export interface QueueSignOptions {
|
|
3
|
+
privateKey: string;
|
|
4
|
+
sender: string;
|
|
5
|
+
recipient?: string;
|
|
6
|
+
ttlMs?: number;
|
|
7
|
+
keyId?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface QueueVerifyOptions {
|
|
10
|
+
publicKey: string;
|
|
11
|
+
}
|
|
12
|
+
export type SignedEnvelope = ProtocolEnvelope;
|
|
13
|
+
export interface QueueMessage<T> {
|
|
14
|
+
envelope: SignedEnvelope;
|
|
15
|
+
payload: T;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Signs a payload for queue transit (Kafka/SQS/Pub-Sub/RabbitMQ).
|
|
19
|
+
* Returns a JSON string: {"envelope": SignedEnvelope, "payload": T}
|
|
20
|
+
* Default TTL is 1 hour (3 600 000 ms).
|
|
21
|
+
*/
|
|
22
|
+
export declare function signQueueMessage<T>(payload: T, opts: QueueSignOptions): Promise<string>;
|
|
23
|
+
/**
|
|
24
|
+
* Parses a queue message JSON string and verifies the envelope signature.
|
|
25
|
+
* Throws if the message is malformed or the signature is invalid.
|
|
26
|
+
*/
|
|
27
|
+
export declare function verifyQueueMessage<T>(message: string, opts: QueueVerifyOptions): Promise<{
|
|
28
|
+
payload: T;
|
|
29
|
+
envelope: ProtocolEnvelope;
|
|
30
|
+
}>;
|
|
31
|
+
/**
|
|
32
|
+
* Verifies a batch of queue message strings.
|
|
33
|
+
* Never throws — returns per-message success/failure objects.
|
|
34
|
+
*/
|
|
35
|
+
export declare function verifyQueueBatch<T>(messages: string[], opts: QueueVerifyOptions): Promise<Array<{
|
|
36
|
+
ok: true;
|
|
37
|
+
payload: T;
|
|
38
|
+
envelope: ProtocolEnvelope;
|
|
39
|
+
} | {
|
|
40
|
+
ok: false;
|
|
41
|
+
raw: string;
|
|
42
|
+
error: string;
|
|
43
|
+
}>>;
|
package/rateLimiter.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export type RateLimitPolicy = {
|
|
2
|
+
requests: number;
|
|
3
|
+
windowMs: number;
|
|
4
|
+
};
|
|
5
|
+
export type RateLimitResult = {
|
|
6
|
+
allowed: boolean;
|
|
7
|
+
remaining: number;
|
|
8
|
+
resetMs: number;
|
|
9
|
+
};
|
|
10
|
+
declare class SlidingWindowRateLimiter {
|
|
11
|
+
private windows;
|
|
12
|
+
check(key: string, policy: RateLimitPolicy, nowMs?: number): RateLimitResult;
|
|
13
|
+
consume(key: string, policy: RateLimitPolicy, nowMs?: number): RateLimitResult;
|
|
14
|
+
reset(key: string): void;
|
|
15
|
+
clear(): void;
|
|
16
|
+
}
|
|
17
|
+
export declare const globalRateLimiter: SlidingWindowRateLimiter;
|
|
18
|
+
export { SlidingWindowRateLimiter };
|
|
@@ -46,36 +46,27 @@
|
|
|
46
46
|
* denial-of-service vector. Choose the posture that matches your threat model.
|
|
47
47
|
* - See `docs/DISTRIBUTED_REPLAY.md` for full operational guidance.
|
|
48
48
|
*/
|
|
49
|
-
|
|
50
49
|
export interface RedisSetOptions {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
50
|
+
/** Only set when the key does not already exist (Redis `NX`). */
|
|
51
|
+
nx?: boolean;
|
|
52
|
+
/** Expire the key after this many milliseconds (Redis `PX`). */
|
|
53
|
+
pxMs?: number;
|
|
55
54
|
}
|
|
56
|
-
|
|
57
55
|
/** A queued, chainable batch of `set` commands flushed in a single round-trip. */
|
|
58
56
|
export interface RedisPipelineLike {
|
|
59
|
-
|
|
60
|
-
|
|
57
|
+
set(key: string, value: string, options?: RedisSetOptions): RedisPipelineLike;
|
|
58
|
+
exec(): Promise<Array<'OK' | null>>;
|
|
61
59
|
}
|
|
62
|
-
|
|
63
60
|
export interface RedisLikeClient {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
61
|
+
/** Returns `'OK'` when the value was written, or `null` when `NX` prevented it. */
|
|
62
|
+
set(key: string, value: string, options?: RedisSetOptions): Promise<'OK' | null>;
|
|
63
|
+
/** Truthy when the key exists and has not expired. */
|
|
64
|
+
get?(key: string): Promise<string | null>;
|
|
65
|
+
/** Removes a key; returns the number of keys removed. */
|
|
66
|
+
del?(key: string): Promise<number>;
|
|
67
|
+
/** Optional batch pipeline; when present, batch reserves use a single round-trip. */
|
|
68
|
+
pipeline?(): RedisPipelineLike;
|
|
72
69
|
}
|
|
73
|
-
|
|
74
|
-
interface Entry {
|
|
75
|
-
value: string
|
|
76
|
-
expiresAt?: number
|
|
77
|
-
}
|
|
78
|
-
|
|
79
70
|
/**
|
|
80
71
|
* In-memory reference implementation of {@link RedisLikeClient}.
|
|
81
72
|
*
|
|
@@ -85,56 +76,15 @@ interface Entry {
|
|
|
85
76
|
* cross-process guarantees and must not be used as a production replay store
|
|
86
77
|
* for a horizontally scaled deployment.
|
|
87
78
|
*/
|
|
88
|
-
export class InMemoryRedisLikeClient implements RedisLikeClient {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
if (entry.expiresAt !== undefined && entry.expiresAt <= this.now()) {
|
|
100
|
-
this.entries.delete(key)
|
|
101
|
-
return undefined
|
|
102
|
-
}
|
|
103
|
-
return entry
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
async set(key: string, value: string, options: RedisSetOptions = {}): Promise<'OK' | null> {
|
|
107
|
-
if (options.nx && this.live(key)) return null
|
|
108
|
-
const expiresAt = options.pxMs !== undefined ? this.now() + options.pxMs : undefined
|
|
109
|
-
this.entries.set(key, { value, expiresAt })
|
|
110
|
-
return 'OK'
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
async get(key: string): Promise<string | null> {
|
|
114
|
-
return this.live(key)?.value ?? null
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
async del(key: string): Promise<number> {
|
|
118
|
-
const existed = this.live(key) !== undefined
|
|
119
|
-
this.entries.delete(key)
|
|
120
|
-
return existed ? 1 : 0
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
pipeline(): RedisPipelineLike {
|
|
124
|
-
const commands: Array<{ key: string; value: string; options?: RedisSetOptions }> = []
|
|
125
|
-
const pipeline: RedisPipelineLike = {
|
|
126
|
-
set: (key: string, value: string, options?: RedisSetOptions) => {
|
|
127
|
-
commands.push({ key, value, options })
|
|
128
|
-
return pipeline
|
|
129
|
-
},
|
|
130
|
-
exec: async () => {
|
|
131
|
-
const results: Array<'OK' | null> = []
|
|
132
|
-
for (const command of commands) {
|
|
133
|
-
results.push(await this.set(command.key, command.value, command.options))
|
|
134
|
-
}
|
|
135
|
-
return results
|
|
136
|
-
},
|
|
137
|
-
}
|
|
138
|
-
return pipeline
|
|
139
|
-
}
|
|
79
|
+
export declare class InMemoryRedisLikeClient implements RedisLikeClient {
|
|
80
|
+
private readonly entries;
|
|
81
|
+
private readonly now;
|
|
82
|
+
constructor(options?: {
|
|
83
|
+
now?: () => number;
|
|
84
|
+
});
|
|
85
|
+
private live;
|
|
86
|
+
set(key: string, value: string, options?: RedisSetOptions): Promise<'OK' | null>;
|
|
87
|
+
get(key: string): Promise<string | null>;
|
|
88
|
+
del(key: string): Promise<number>;
|
|
89
|
+
pipeline(): RedisPipelineLike;
|
|
140
90
|
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import type { DistributedReplayStore } from './protocolReplay';
|
|
2
|
+
import { type RedisLikeClient } from './redisClient';
|
|
3
|
+
/**
|
|
4
|
+
* Minimal Redis client surface required by RedisReplayStore.
|
|
5
|
+
*
|
|
6
|
+
* Distinct from the internal RedisLikeClient: this interface uses a `quit()`
|
|
7
|
+
* lifecycle method and does not require pipeline support, making it easy to
|
|
8
|
+
* adapt any Redis client (ioredis, node-redis, Upstash, etc.) without coupling
|
|
9
|
+
* to the internal pipeline abstraction.
|
|
10
|
+
*/
|
|
11
|
+
export interface RedisClientLike {
|
|
12
|
+
set(key: string, value: string, opts?: {
|
|
13
|
+
nx?: boolean;
|
|
14
|
+
px?: number;
|
|
15
|
+
}): Promise<string | null>;
|
|
16
|
+
get(key: string): Promise<string | null>;
|
|
17
|
+
del(key: string): Promise<number | any>;
|
|
18
|
+
quit(): Promise<any>;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Gateway-facing replay store interface.
|
|
22
|
+
*
|
|
23
|
+
* `check()` atomically marks a key as seen and returns whether it was already
|
|
24
|
+
* present: `false` = fresh (first time seen), `true` = replay (already seen).
|
|
25
|
+
*/
|
|
26
|
+
export interface ReplayStore {
|
|
27
|
+
check(key: string, ttlMs: number): Promise<boolean>;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Redis-backed implementation of {@link ReplayStore}.
|
|
31
|
+
*
|
|
32
|
+
* Uses SET … NX PX for an atomic "set if not exists with TTL" operation.
|
|
33
|
+
* The operation is single-round-trip and safe under concurrent access from
|
|
34
|
+
* multiple gateway instances.
|
|
35
|
+
*/
|
|
36
|
+
export declare class RedisReplayStore implements ReplayStore {
|
|
37
|
+
private readonly keyPrefix;
|
|
38
|
+
private readonly client;
|
|
39
|
+
constructor(opts?: {
|
|
40
|
+
redisUrl?: string;
|
|
41
|
+
keyPrefix?: string;
|
|
42
|
+
client?: RedisClientLike;
|
|
43
|
+
});
|
|
44
|
+
/**
|
|
45
|
+
* Returns `false` if the key is fresh (first time seen — key was set in Redis),
|
|
46
|
+
* or `true` if the key is a replay (key already existed — SET NX returned null).
|
|
47
|
+
*/
|
|
48
|
+
check(key: string, ttlMs: number): Promise<boolean>;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Cluster-aware replay store that wraps multiple {@link RedisReplayStore}
|
|
52
|
+
* instances — one per Redis shard / node.
|
|
53
|
+
*
|
|
54
|
+
* A message is treated as a replay if ANY node has already seen the nonce.
|
|
55
|
+
* All nodes are checked in parallel via Promise.all.
|
|
56
|
+
*/
|
|
57
|
+
export declare class ClusterRedisReplayStore implements ReplayStore {
|
|
58
|
+
private readonly nodes;
|
|
59
|
+
constructor(nodes: RedisReplayStore[]);
|
|
60
|
+
check(key: string, ttlMs: number): Promise<boolean>;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Convenience factory that creates a {@link RedisReplayStore} from a URL
|
|
64
|
+
* or options object.
|
|
65
|
+
*/
|
|
66
|
+
export declare function createRedisReplayStore(clientOrOpts: RedisLikeClient | {
|
|
67
|
+
redisUrl?: string;
|
|
68
|
+
keyPrefix?: string;
|
|
69
|
+
client?: RedisClientLike;
|
|
70
|
+
}, options?: RedisReplayStoreOptions): DistributedReplayStore;
|
|
71
|
+
/**
|
|
72
|
+
* Creates a {@link ClusterRedisReplayStore} from an array of Redis URLs.
|
|
73
|
+
* Each URL is used to create an independent {@link RedisReplayStore} node.
|
|
74
|
+
*/
|
|
75
|
+
export declare function createClusterReplayStore(redisUrls: string[]): ClusterRedisReplayStore;
|
|
76
|
+
/**
|
|
77
|
+
* What to do when the Redis client throws (network blip, server down).
|
|
78
|
+
*
|
|
79
|
+
* - `fallback` (default): degrade to a local in-memory store so traffic keeps
|
|
80
|
+
* flowing with single-node replay protection still in force. Quality +
|
|
81
|
+
* reliability + scalability: Redis is never a fleet-wide kill switch.
|
|
82
|
+
* - `reject`: fail closed — deny the message because uniqueness cannot be confirmed.
|
|
83
|
+
* - `allow`: fail open — accept the message (skip the check) to maximise uptime.
|
|
84
|
+
*/
|
|
85
|
+
export type ReplayErrorBehavior = 'fallback' | 'reject' | 'allow';
|
|
86
|
+
export interface RedisReplayStoreOptions {
|
|
87
|
+
/** Key namespace in Redis. Default `aip:replay:`. */
|
|
88
|
+
keyPrefix?: string;
|
|
89
|
+
/** Behavior when the Redis client throws. Default `fallback`. */
|
|
90
|
+
errorBehavior?: ReplayErrorBehavior;
|
|
91
|
+
/** Local store used when `errorBehavior` is `fallback`. Defaults to an in-memory-backed store. */
|
|
92
|
+
fallback?: DistributedReplayStore;
|
|
93
|
+
/** Observability hook fired whenever a Redis error forces degraded handling. */
|
|
94
|
+
onDegraded?: (error: unknown, context: {
|
|
95
|
+
key: string;
|
|
96
|
+
behavior: ReplayErrorBehavior;
|
|
97
|
+
}) => void;
|
|
98
|
+
}
|
package/revocation.d.ts
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { ProtocolEnvelope, SignatureVerificationMaterial } from './protocol';
|
|
2
|
+
import type { RedisLikeClient } from './redisClient';
|
|
3
|
+
/**
|
|
4
|
+
* A shared key-revocation list consulted on the verification hot path.
|
|
5
|
+
*
|
|
6
|
+
* `RollingKeyring` enforces revocation in-process; a `RevocationStore` makes a
|
|
7
|
+
* revocation effective fleet-wide: revoke a `(sender, keyId)` on one node and
|
|
8
|
+
* every node that consults the same store rejects it.
|
|
9
|
+
*/
|
|
10
|
+
export interface RevocationStore {
|
|
11
|
+
isRevoked(sender: string, keyId: string, nowMs?: number): boolean | Promise<boolean>;
|
|
12
|
+
revoke(sender: string, keyId: string, options?: {
|
|
13
|
+
untilMs?: number;
|
|
14
|
+
}): void | Promise<void>;
|
|
15
|
+
}
|
|
16
|
+
/** Single-process revocation list (tests, local dev, single-node deployments). */
|
|
17
|
+
export declare class InMemoryRevocationStore implements RevocationStore {
|
|
18
|
+
/** keyId map value: revoked-until timestamp, or `Infinity` for permanent. */
|
|
19
|
+
private readonly revoked;
|
|
20
|
+
private readonly now;
|
|
21
|
+
constructor(options?: {
|
|
22
|
+
now?: () => number;
|
|
23
|
+
});
|
|
24
|
+
private makeKey;
|
|
25
|
+
isRevoked(sender: string, keyId: string, nowMs?: number): boolean;
|
|
26
|
+
revoke(sender: string, keyId: string, options?: {
|
|
27
|
+
untilMs?: number;
|
|
28
|
+
}): void;
|
|
29
|
+
}
|
|
30
|
+
/** Behavior when the Redis client throws while checking revocation. */
|
|
31
|
+
export type RevocationErrorBehavior = 'reject' | 'allow';
|
|
32
|
+
export interface RedisRevocationStoreOptions {
|
|
33
|
+
/** Key namespace in Redis. Default `aip:revoked:`. */
|
|
34
|
+
keyPrefix?: string;
|
|
35
|
+
/**
|
|
36
|
+
* Behavior when the Redis client throws.
|
|
37
|
+
* - `reject` (default): fail closed — treat the key as revoked. A revoked key
|
|
38
|
+
* is a compromised key; never accept on uncertainty.
|
|
39
|
+
* - `allow`: treat the key as not revoked (favor availability).
|
|
40
|
+
*/
|
|
41
|
+
errorBehavior?: RevocationErrorBehavior;
|
|
42
|
+
/** Local cache freshness window in ms for `isRevoked` reads. Default 5000. */
|
|
43
|
+
cacheTtlMs?: number;
|
|
44
|
+
/** Observability hook fired whenever a Redis error forces degraded handling. */
|
|
45
|
+
onDegraded?: (error: unknown, context: {
|
|
46
|
+
sender: string;
|
|
47
|
+
keyId: string;
|
|
48
|
+
}) => void;
|
|
49
|
+
/** Clock override (testing). */
|
|
50
|
+
now?: () => number;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Creates a Redis-backed {@link RevocationStore}.
|
|
54
|
+
*
|
|
55
|
+
* Reads are served from a short-lived local cache so the verification hot path
|
|
56
|
+
* does not hit Redis on every message; known revocations therefore keep
|
|
57
|
+
* enforcing even through a brief Redis outage.
|
|
58
|
+
*/
|
|
59
|
+
export declare function createRedisRevocationStore(client: Pick<RedisLikeClient, 'set' | 'get' | 'del'>, options?: RedisRevocationStoreOptions): RevocationStore;
|
|
60
|
+
type SignatureResolver = (signature: NonNullable<ProtocolEnvelope['signature']>, sender: string) => SignatureVerificationMaterial | undefined | Promise<SignatureVerificationMaterial | undefined>;
|
|
61
|
+
/**
|
|
62
|
+
* Wraps a signature resolver so that a revoked `(sender, keyId)` resolves to no
|
|
63
|
+
* material — which makes signature verification fail and the envelope is rejected.
|
|
64
|
+
*
|
|
65
|
+
* Compose over `createKeyringSignatureResolver` (or any resolver) and pass the
|
|
66
|
+
* result as the transport `signatureResolver`.
|
|
67
|
+
*/
|
|
68
|
+
export declare function withRevocationCheck(resolver: SignatureResolver, store: RevocationStore, options?: {
|
|
69
|
+
nowMsProvider?: () => number;
|
|
70
|
+
}): SignatureResolver;
|
|
71
|
+
export {};
|
package/routePolicy.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export type PolicyRequirement = 'ed25519' | 'hmac' | 'any' | 'none';
|
|
2
|
+
export interface RoutePolicy {
|
|
3
|
+
path: string;
|
|
4
|
+
require: PolicyRequirement;
|
|
5
|
+
rateLimit?: {
|
|
6
|
+
requests: number;
|
|
7
|
+
windowMs: number;
|
|
8
|
+
};
|
|
9
|
+
allowedSenders?: string[];
|
|
10
|
+
signResponse?: boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Translate a glob pattern to a RegExp.
|
|
14
|
+
* Supported:
|
|
15
|
+
* - exact: '/health'
|
|
16
|
+
* - '?' → any single non-slash char
|
|
17
|
+
* - '*' → any chars within a single segment (no slash)
|
|
18
|
+
* - '**' → any chars at any depth (including slashes)
|
|
19
|
+
*/
|
|
20
|
+
export declare function matchGlob(pattern: string, path: string): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Find the first matching policy for a given path.
|
|
23
|
+
* Returns null if no policy matches.
|
|
24
|
+
*/
|
|
25
|
+
export declare function matchPolicy(policies: RoutePolicy[], path: string): RoutePolicy | null;
|
|
26
|
+
/**
|
|
27
|
+
* Check whether a sender is permitted by a policy.
|
|
28
|
+
* If allowedSenders is not set, all senders are allowed.
|
|
29
|
+
*/
|
|
30
|
+
export declare function isAllowedSender(policy: RoutePolicy, sender: string): boolean;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface RuntimePolicy {
|
|
2
|
+
version: string;
|
|
3
|
+
name: string;
|
|
4
|
+
status: string;
|
|
5
|
+
owner?: string;
|
|
6
|
+
updated_at?: string;
|
|
7
|
+
hard_invariants?: Record<string, unknown>;
|
|
8
|
+
slo_defaults?: Record<string, unknown>;
|
|
9
|
+
mode_selection?: Record<string, unknown>;
|
|
10
|
+
guardrails?: Record<string, unknown>;
|
|
11
|
+
tuning?: Record<string, unknown>;
|
|
12
|
+
adaptive_flow?: Record<string, unknown>;
|
|
13
|
+
benchmark_policy?: Record<string, unknown>;
|
|
14
|
+
runtime_decision_tree?: unknown[];
|
|
15
|
+
operator_handoff_required_fields?: string[];
|
|
16
|
+
[key: string]: unknown;
|
|
17
|
+
}
|
|
18
|
+
export interface LoadRuntimePolicyOptions {
|
|
19
|
+
path?: string;
|
|
20
|
+
readTextFile?: (filePath: string) => Promise<string>;
|
|
21
|
+
}
|
|
22
|
+
export declare function validateRuntimePolicy(value: unknown): RuntimePolicy;
|
|
23
|
+
export declare function parseRuntimePolicyJson(jsonText: string): RuntimePolicy;
|
|
24
|
+
export declare function loadRuntimePolicy(options?: LoadRuntimePolicyOptions): Promise<RuntimePolicy>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type BootstrapRuntimePolicyEnforcerOptions, type PolicyEnforcer } from './policyEnforcer';
|
|
2
|
+
import type { RuntimePolicy } from './runtimePolicy';
|
|
3
|
+
export interface RuntimePolicySnapshot {
|
|
4
|
+
policy: RuntimePolicy;
|
|
5
|
+
enforcer: PolicyEnforcer;
|
|
6
|
+
loadedAtMs: number;
|
|
7
|
+
}
|
|
8
|
+
export declare class RuntimePolicyManager {
|
|
9
|
+
private snapshot;
|
|
10
|
+
private readonly options;
|
|
11
|
+
constructor(options?: BootstrapRuntimePolicyEnforcerOptions);
|
|
12
|
+
loadInitial(): Promise<RuntimePolicySnapshot>;
|
|
13
|
+
current(): RuntimePolicySnapshot;
|
|
14
|
+
refresh(): Promise<RuntimePolicySnapshot>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { RuntimeMode } from './policyEnforcer';
|
|
2
|
+
export type RuntimeEnvironment = 'dev' | 'staging' | 'prod';
|
|
3
|
+
export interface RuntimeTuningPreset {
|
|
4
|
+
environment: RuntimeEnvironment;
|
|
5
|
+
mode: RuntimeMode;
|
|
6
|
+
poolSize: number;
|
|
7
|
+
batchSize: number;
|
|
8
|
+
inflightCap: number;
|
|
9
|
+
retryMaxAttempts: number;
|
|
10
|
+
}
|
|
11
|
+
export declare function getRuntimeTuningPreset(environment: RuntimeEnvironment): RuntimeTuningPreset;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type ProtocolEnvelope } from './protocol';
|
|
2
|
+
export declare const RESPONSE_HEADER = "x-7h3-response";
|
|
3
|
+
export declare function signResponse(body: string, opts: {
|
|
4
|
+
privateKey: string;
|
|
5
|
+
sender: string;
|
|
6
|
+
recipient?: string;
|
|
7
|
+
correlationId?: string;
|
|
8
|
+
ttlMs?: number;
|
|
9
|
+
}): Promise<{
|
|
10
|
+
headers: {
|
|
11
|
+
'x-7h3-response': string;
|
|
12
|
+
};
|
|
13
|
+
}>;
|
|
14
|
+
export declare function verifyResponse(body: string, headers: Record<string, string | string[] | undefined>, opts: {
|
|
15
|
+
publicKey: string;
|
|
16
|
+
maxAgeMs?: number;
|
|
17
|
+
}): Promise<{
|
|
18
|
+
ok: boolean;
|
|
19
|
+
envelope?: ProtocolEnvelope;
|
|
20
|
+
reason?: string;
|
|
21
|
+
}>;
|
package/stream.d.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
export interface StreamChunk {
|
|
2
|
+
i: number;
|
|
3
|
+
d: string;
|
|
4
|
+
h: string;
|
|
5
|
+
f: boolean;
|
|
6
|
+
sig?: string;
|
|
7
|
+
kid?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface StreamSignerOpts {
|
|
10
|
+
privateKey: string;
|
|
11
|
+
sender: string;
|
|
12
|
+
nonce?: string;
|
|
13
|
+
keyId?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface StreamVerifierOpts {
|
|
16
|
+
publicKey: string;
|
|
17
|
+
maxChunks?: number;
|
|
18
|
+
}
|
|
19
|
+
export type StreamVerifyResult = {
|
|
20
|
+
ok: true;
|
|
21
|
+
totalBytes: number;
|
|
22
|
+
chunkCount: number;
|
|
23
|
+
} | {
|
|
24
|
+
ok: false;
|
|
25
|
+
reason: string;
|
|
26
|
+
chunkIndex?: number;
|
|
27
|
+
};
|
|
28
|
+
export declare const STREAM_HEADER = "x-7h3-stream";
|
|
29
|
+
export declare class SignedStreamWriter {
|
|
30
|
+
private readonly opts;
|
|
31
|
+
private seq;
|
|
32
|
+
private readonly accum;
|
|
33
|
+
private hmacKeyPromise;
|
|
34
|
+
constructor(opts: StreamSignerOpts);
|
|
35
|
+
get nonce(): string;
|
|
36
|
+
private getHmacKey;
|
|
37
|
+
private computeChunkHmac;
|
|
38
|
+
writeChunk(data: string): Promise<StreamChunk>;
|
|
39
|
+
finalize(): Promise<StreamChunk>;
|
|
40
|
+
}
|
|
41
|
+
export declare class SignedStreamReader {
|
|
42
|
+
private readonly opts;
|
|
43
|
+
private expectedSeq;
|
|
44
|
+
private readonly accum;
|
|
45
|
+
private totalBytes;
|
|
46
|
+
private done;
|
|
47
|
+
constructor(opts: StreamVerifierOpts);
|
|
48
|
+
receiveChunk(chunk: StreamChunk): Promise<{
|
|
49
|
+
ok: boolean;
|
|
50
|
+
reason?: string;
|
|
51
|
+
}>;
|
|
52
|
+
finalize(finalChunk: StreamChunk): Promise<StreamVerifyResult>;
|
|
53
|
+
}
|
|
54
|
+
export declare function createSignedStream(opts: StreamSignerOpts): SignedStreamWriter;
|
|
55
|
+
export declare function createStreamVerifier(opts: StreamVerifierOpts): SignedStreamReader;
|
|
56
|
+
export declare function signStream(chunks: AsyncIterable<string> | string[], opts: StreamSignerOpts): Promise<StreamChunk[]>;
|
|
57
|
+
export declare function verifyStream(chunks: StreamChunk[], opts: StreamVerifierOpts): Promise<StreamVerifyResult>;
|
|
58
|
+
export declare function encodeStreamChunk(chunk: StreamChunk): string;
|
|
59
|
+
export declare function decodeStreamChunk(raw: string): StreamChunk;
|