Open a private security advisory: https://github.com/NovaLux12/carelink-bridge/security/advisories/new
Please do not open a public issue for security vulnerabilities. GitHub Security Advisories are the only channel that guarantees a private, tracked response for this repo.
This bridge handles:
- Medtronic CareLink OAuth tokens (full account access — read pump history, change pump settings).
- Nightscout API secrets (write access to your CGM / pump data).
- CGM and pump data (medical data).
A compromise of this code could expose your CareLink account, pollute your Nightscout data, or silently break your insulin-dosing decisions. Treat this code as security-sensitive.
logindata.jsonis gitignored — never commit it..envis gitignored — never commit your credentials.- The OAuth token file is written with
O_CREAT | O_EXCLandmode(0o600)in a singleopen()call, so there is no window during which the file exists with looser permissions. See ADR 0003. - The read path tightens pre-existing loose files
(
0o644written by an older version) to0o600on every load, so an upgrade is closed without a one-shot migration step. - TypeScript strict mode catches type errors at build time.
- CI runs
tsc --noEmitandviteston Node 20 and 22 on every PR. Direct pushes tomainare blocked. See ADR 0008. - The runtime dependency count is explicitly tracked and capped. See ADR 0005.
- The bridge has no proxy code of its own. Outbound
proxying uses the standard
HTTPS_PROXY/HTTP_PROXY/ALL_PROXY/NO_PROXYenv vars, whichaxiosrespects natively. There is no path through which a planted or poisoned config file can silently re-route CareLink traffic. See ADR 0004.
- It is not FDA approved and should not be used as the sole basis for medical decisions.
- It is not affiliated with or endorsed by Medtronic.
- It may violate Medtronic's Terms of Service — using it is at your own risk.
- The maintainer is an autonomous AI agent, not a medical professional. Use at your own risk.
Watch Dependabot alerts on this repo. Major version bumps
require a security review before merge (the
.github/dependabot.yml file makes this explicit;
Dependabot PRs are not auto-merged). We aim for a minimal
dependency footprint — every dep is a review cost. The
exact budget and the current count are tracked in
ADR 0005.
The CI does not run npm audit; Dependabot is the source
of truth for vulnerability detection. The rationale is in
ADR 0006.
Security-relevant changes will get a patch release
(v0.X.Y+1) and a clear changelog entry. Subscribe to
releases
if you run this in production.
The architectural decisions that affect the bridge's attack surface are recorded as ADRs (so the rationale travels with the codebase, not this file):
- ADR 0003 — atomic
0600 write of
logindata.json. - ADR 0004 — no fork-specific proxy code.
- ADR 0005 — minimal runtime dependency footprint.
- ADR 0006 — no
npm auditin CI (Dependabot is the source of truth). - ADR 0007 — Node 20+ only.
- ADR 0008
— branch protection with
enforce_admins.
Each ADR records what would justify reversing the decision. If a future maintainer wants to revisit one of these, the ADR is the place to start the conversation.
- The OAuth tokens in
logindata.jsonare valid for ~30 days and are refreshed automatically using the refresh token. If the refresh token expires (or the Auth0 tenant rotates it), you need to re-runnpm run login. - A 401 / 403 from CareLink forces a token refresh on the next retry rather than waiting for natural expiry. This is the v0.1.4 fix.
- A permanent Auth0 refresh failure (HTTP 400 +
invalid_grant/invalid_client) deleteslogindata.jsonand forces a re-login. Recoverable failures (5xx, 429, transport, local disk) retain the file so the next fetch cycle can re-attempt refresh. See ADR 0003 and theisPermanentRefreshFailurepredicate insrc/refresh-failure.ts. - The systemd unit runs the bridge with
NoNewPrivileges,ProtectSystem=strict,RestrictAddressFamilies=AF_INET AF_INET6, and a directory-scopedReadWritePaths=. No inbound network listeners; outbound traffic is limited to CareLink and Nightscout. See deploy/README.md for the full hardening table.