Written for the security-aware engineer or CISO evaluating Kinetic Gain Embedded. If your job is to decide whether this SDK survives your threat model, this is the document. Cryptographic invariants, trust boundaries, key-management responsibilities, and the failure modes we expect you to plan around — including the ones where KGE does nothing useful at all. If we can't be honest about what we don't protect, we can't be trusted on what we do.
KGE sits inside your application process, between your application logic and the AI tools you call. The trust model is asymmetric: we trust your application code (you wrote it); we do not trust the AI tool (it's a third-party black box); your customer trusts the audit stream (because they can verify it cryptographically) but not your raw database.
Your application process — the Node 20+ server that imports kinetic-gain-embedded. Honest-but-bounded: assumed to run unmodified SDK code, with the production private key, against your real customer record store.
The vendor-signed Decision Card document — issued by your customer, fetched over HTTPS, parsed, structurally validated.
The configured sink — NDJSON file / HTTPS endpoint / in-memory / your custom — assumed to honor "append once, never modify."
The AI tool — LLM, vector DB, embedding model. May leak inputs into training data, log to its own backend, or be prompt-injected. KGE strips sensitive fields BEFORE the tool sees the payload.
Network paths to the AI tool — TLS protects the wire; KGE does not assume your TLS configuration is correct, but it cannot enforce it.
Future versions of your own application — a year from now, you might add a feature that bypasses applyVaultContract. The audit chain catches the change because the redaction list won't match what the rule says it should.
If you observe a violation of any of these four, that is a security bug regardless of "fitness for purpose" arguments. Report privately per SECURITY.md.
Changing any field of any prior audit event MUST make verifyChain() return failure at the modified event. SHA-256 over canonical JSON; prev_hash threads back to a genesis of 64 zeros. Length-extension, canonical-form ambiguity, or hash collision = bug.
Every audit event carries decision_card_ref + redaction_applied. The redaction list MUST reflect exactly what applyVaultContract did to the payload at emit time. An event whose redaction list lies about what was actually transformed is a bug.
If signing is enabled, the embedded signature.value MUST verify against signature.public_key over canonicalize(event - {signature}). Mismatches between the TypeScript SDK and the Python / Go / Rust verifiers in the broader Suite are bugs in whichever side diverged from the spec.
If a Decision Card declares a field as tokenize / mask / hash / drop, the field MUST be transformed before applyVaultContract returns. Returning the raw value of a tokenize-targeted field is the highest-severity class of bug this SDK can have.
| Primitive | Library | Why |
|---|---|---|
SHA-256 | node:crypto (built-in) | Hash chain over canonical JSON; deterministic token derivation when no external vault tokenizer is wired. |
ed25519 | node:crypto (built-in) | Optional signatures on audit events. EdDSA over Curve25519; small (64-byte sig), fast, deterministic, no nonce-reuse foot-gun. |
UUID v7 | own impl in src/uuid.ts | Time-ordered event IDs. Allows chronological sort without a separate timestamp column. RFC 9562. |
Canonical JSON | own impl in src/canonicalize.ts | Deterministic byte representation. Sorted keys recursively, arrays preserved in order, no non-ASCII escaping (matches the Python/Go verifiers). |
Zero runtime dependencies. We use Node's built-in node:crypto for everything. No homegrown crypto. The own-impl items (UUID v7 + canonical JSON) are spec-driven and have test vectors agreeing with at least two external implementations.
| Threat | What KGE does |
|---|---|
| AI tool exfiltrates raw PII / PHI / SPI from a prompt | Prevented at the source. applyVaultContract transforms the record before the AI tool sees it. The tool gets tokens / masks / hashes — not the raw values. (Provided you actually call applyVaultContract.) |
| Insider edits historical audit events to cover up an access | Detected at verify time. verifyChain recomputes every hash; any in-place edit breaks the chain at the modified event. The verifier names the exact index. |
| Vendor's compliance team claims the audit log is genuine; auditor needs to verify | Replay-verifiable end to end. Auditor on the other side of the trust boundary recomputes hashes + ed25519 signatures from canonical JSON. Same hashes = same events. Byte-for-byte interop with the Python and Go verifiers. |
| Buyer changes the Decision Card; old audit events should still validate against the old card | Each event carries decision_card_ref in force at emit time. A new card doesn't invalidate old events; an auditor fetches the historic card by ref to verify the redactions were correct then. |
| Decision Card itself is forged or substituted | Out of scope for KGE; in scope for the buyer's signing process. If the buyer publishes their Decision Card with their own ed25519 signature at a stable URL, downstream verifiers can detect substitution. KGE accepts the card and binds to it; the buyer's signing infrastructure defends the card. |
| Network exfil from the embedding application to a non-listed destination | Not in scope. KGE is a library, not a network policy enforcer. Use egress controls (e.g., Privatelink, allow-listed firewall, Squid) outside KGE. |
| RCE / code injection in the embedding application gives an attacker process-level access | Not in scope. If your Node server is owned, the attacker can bypass applyVaultContract before it runs. KGE assumes the embedding process is honest-but-bounded. |
| Side-channel: timing differences in vault-contract operations leak which fields were transformed | Partial mitigation. SHA-256 + ed25519 are constant-time-ish on modern hardware; the JSON canonicalization is not. We do not claim side-channel resistance. If your threat model includes a co-located attacker measuring CPU time, you need additional layers. |
If you enable ed25519 signing, you provide the private key. KGE takes a Node KeyObject you've already loaded. We don't generate, store, rotate, or transmit private keys.
openssl genpkey -algorithm ed25519 on an isolated host).https://your-org.example/.well-known/keys/2026.json./.well-known/<path>.json with a published SPKI-DER base64 string; you implement that.This is the honest list. We do not:
Three classes of failure where KGE behavior is well-defined:
And one class where KGE behavior is intentionally bounded:
If you've found a way to violate one of the four invariants — or any other security issue — please report privately:
Email: miz@kineticgain.com
Repository policy: kinetic-gain-embedded/SECURITY.md
Apex coordinated disclosure: /.well-known/security.txt
We acknowledge within 72 hours. Default fix-and-disclose timeline is 90 days, shortened if exploitation is observed in the wild. Credit in the fix release is offered by default; you can decline.
Reference scaffolding for audit evidence — not a HIPAA / FERPA / SOC 2 / GDPR / ISO 27001 / NIST AI RMF / EU AI Act / ISO 42001 compliant or certified product. Compliance posture depends on the embedder's full control environment and external attestation specific to each regulatory regime.