@takk/gaptime is a stable (1.0.0) library and CLI for bi-temporal knowledge-graph memory. We take security reports seriously and aim to acknowledge each one within two business days.
Each published version follows strict SemVer (see SPEC.md section 11 and .github/RELEASING.md). Only the latest minor of the current major receives security patches; an older major receives critical-CVE fixes for 6 months after the next major lands.
| Package | Supported |
|---|---|
@takk/gaptime |
current latest dist-tag |
Do not file public GitHub issues for security problems. Send reports to davcavalcante@proton.me (preferred) or say@takk.ag (Takk relay), with the subject line beginning [SECURITY].
Include, at minimum:
- Affected version (
npm ls @takk/gaptime). - Reproduction steps or a minimal proof of concept.
- Impact assessment (what an attacker can achieve).
- Any suggested mitigation.
PGP or signed reports are welcome but not required. If you need an out-of-band channel, ask in the first message and we will propose one.
- Acknowledgement within 2 business days.
- Triage and severity assignment within 7 days.
- Fix targeted for the next release; critical issues ship as an out-of-band patch on the affected minor.
- Coordinated disclosure: the reporter is credited in the changelog and advisory unless they request anonymity.
- Credential handling: there is none, and any appearance of it is a bug. GapTime never handles API keys, by product invariant. The
KvLikeand bridge interfaces receive ready client objects; any path that causes a connection string, token, or key to be read, stored, logged, or persisted by this package is in scope and treated as a vulnerability. - Host hook safety. A throwing or rejecting host hook (
Extractor,VectorIndex,GraphStore) must never crash the host process or abort a write half-way, and a fact must always be audited even when a hook fails. Any path where a faulty hook corrupts the store, leaves an unaudited fact, or escapes as an unhandled rejection is in scope. - The serve bridge.
gaptime servebinds loopback by default and refuses non-loopback hosts without a token; the bearer comparison is constant-time; POST bodies are gated by content type (415) and a 1 MB cap (413); CORS headers are emitted only when both--tokenand--cors-originare configured. Tokenless instances additionally validate the Host header as the DNS-rebinding defense: any request whose hostname (port stripped, IPv6 brackets tolerated) is not loopback (localhost,127.0.0.1,::1) is answered 403forbidden host, and/healthzis host-checked too; with a token configured the bearer is the gate and the Host header is not consulted. Any bypass of these gates (auth bypass, timing oracle on the token, body-cap evasion, Host-validation bypass in tokenless mode, CORS leak without the double opt-in) is in scope. - State snapshot handling. Snapshots are validated by version (
version: 1, rejected otherwise withERR_STATE_VERSION); an unreadable snapshot is quarantined to a.corrupt-*file rather than overwritten, and the engine degrades to fresh rather than crashing. A crafted snapshot that crashes the engine, escapes the defensive restore, or silently destroys recoverable history is in scope. Path traversal in the file backend write path likewise. - Untrusted ingestion, as a documented boundary.
assert,ingest, and the authenticated write endpoints trust the operator: fabricated facts skew the store. By design this is the operator trust boundary, the host owns input validation, and thekeymeshBridgeexists to retract facts from a source whose credential is later distrusted. A path where unauthenticated input reaches a write, or where a write escapes the audit trail, is in scope; skew from a trusted-but-lying feeder within the same trust domain is not. - Misuse-resistance of statement keys. FNV-1a 64 statement keys are non-cryptographic, predictable, and collision-constructible, and the package must never use them for authentication, authorization, or integrity decisions. Any internal code path that does is in scope.
- Supply chain. Tarball contamination, compromised npm scope, or a published artifact whose provenance attestation does not match the source commit.
- The security of upstream provider APIs and the accuracy of the data you choose to assert.
- Custody of the facts you assert and your provider credentials before anything reaches GapTime; that is the operator's responsibility (GapTime never receives the credentials at all).
- Store skew caused by an operator asserting false facts within their own trust domain (see the documented boundary above).
- Theoretical attacks against FNV-1a as a hash; it is declared non-cryptographic and is never used for security decisions. Report a violation of that rule, not the hash.
- Denial of service through unbounded inputs to your own embedding application; the serve bridge's own caps are in scope, your application's are yours.
- Zero runtime dependencies. The transitive attack surface of the published package is the package itself. Sibling bridges are structural; the optional peers are never imported at runtime.
- Provenance. Every release is published with
npm publish --provenance(SLSA attestation from GitHub Actions). Verify withnpm view @takk/gaptime@<version> --json | jq .dist.attestations. - Files allowlist.
package.json#filesenumerates exactly what ships (dist,README.md,LICENSE,NOTICE,CHANGELOG.md,SECURITY.md); nothing else can leak into the tarball. The published artifact carries 58 files. - Frozen lockfile.
pnpm-lock.yamlis committed, and CI installs with--frozen-lockfile, so builds are reproducible and dependency swaps cannot ride a CI run. - Two-step release. A reviewable GitHub Release precedes every npm publish (see .github/RELEASING.md).