@takk/modelchain is a stable (1.0.0) library for measurable LLM routing, with
native streaming, native tool calling, and a Vercel AI SDK adapter. We take
security reports seriously and aim to acknowledge each one within two business
days.
Each published version follows strict SemVer (see SPEC.md §5 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/modelchain |
current latest dist-tag |
Please 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/modelchain). - Reproduction steps or a minimal proof-of-concept.
- Impact assessment (what an attacker can achieve).
- Any suggested mitigation.
If your report involves a vulnerability in a third-party peer dependency, please also link the upstream advisory (CVE, GHSA, etc.) so we can coordinate the disclosure.
PGP / 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.
Findings in any of the following are in scope:
- Credential handling. Any path that leaks a raw API key into a telemetry
event, a
router.inspect()snapshot, a thrown error message, or a log line. (By design, modelchain never logs, serialises, or emits raw key material; this is unit-tested.) - State persistence. Path traversal in the
FileStateBackendwrite path; any way to make modelchain write outside the configured path. The state backend persists only aggregated per-model metadata — never the raw key value, a prompt, or a response (seePRIVACY.md§2.4). Any path that causes a raw key, prompt, or response to reach the state file is therefore in scope and treated as a vulnerability. - Routing, failover, circuit, and budget logic. Any way to defeat the
per-model circuit breaker, the retry budget, or the
BudgetGuardso that a single failing model can cause unbounded retries, a cost spike, or a denial of service against the caller. - Streaming and tool calling. Any way to make modelchain mishandle a stream
so that budget is silently mis-committed, or any path where a malformed
tool-call response corrupts the normalised
ToolCall[]returned to the consumer. (Validating tool-call arguments against yourToolDefinition.parametersbefore execution remains the consumer's responsibility.) - Provider adapter injection. Header or URL injection through the
httpModelauthHeader/baseUrl/buildRequestconfiguration that lets an attacker redirect requests or smuggle headers. - Supply chain. Tarball contamination, compromised npm scope, or a published artifact whose provenance attestation does not match the source commit.
- The security of the upstream provider APIs themselves (OpenAI, Anthropic, Google, or any HTTP endpoint you configure) and the quality or safety of their responses.
- The custody of your API keys before they reach modelchain (your environment, your secret manager) — that is the operator's responsibility.
- Prompt-content safety, jailbreak detection, and content moderation — use a content-safety layer before the prompt reaches modelchain.
- Authentication / authorisation of the user issuing requests through your application.
- Encrypted-at-rest secret storage — use your platform's KMS / Secret Manager.
- Denial of service via unbounded inputs against your own application; request sizing and upstream rate limiting remain the operator's responsibility.
- Zero required runtime dependencies. The attack surface from transitive dependencies is eliminated for the core and every provider adapter, which call the REST APIs directly via Web Fetch. Provider SDKs and the Vercel AI SDK are optional peer dependencies you install explicitly.
- Provenance. Every release is published with
npm publish --provenance(SLSA attestation by GitHub Actions). Verify withnpm view @takk/modelchain@<version> --json | jq .dist.attestations. - Lockfile committed.
pnpm-lock.yamlis tracked in git for reproducible installs;pnpm auditruns in CI and advisories block merges; dependency upgrades go through Dependabot + code review.
- Use
@takk/modelchain/edgeinstead of/for edge functions — no Node built-ins. - Use a key resolver (function) instead of raw string keys whenever the runtime supports fetching secrets.
- Set
budget: { perRequestUsd, dailyUsd }to bound cost from runaway loops. - Subscribe to
circuit.openandbudget.exhaustedtelemetry events and route them to alerting. - Pin
pnpmto the version declared inpackageManager(pnpm@10.34.1). - Verify SLSA provenance:
npm view @takk/modelchain@1.0.0 --json | jq .dist.attestations - For tool calling: always validate tool-call arguments against your
ToolDefinition.parametersbefore executing.
modelchain does not perform cryptographic operations itself in v1.0.0. The
provider adapters rely on the platform's TLS stack via Web Fetch.