Skip to content

feat(lightning): support loading LND TLS certificate from file#3861

Merged
Danswar merged 2 commits into
developfrom
feat/lightning-cert-from-file
Jun 10, 2026
Merged

feat(lightning): support loading LND TLS certificate from file#3861
Danswar merged 2 commits into
developfrom
feat/lightning-cert-from-file

Conversation

@Danswar

@Danswar Danswar commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator

Problem

The LND TLS certificate is currently loaded only from the LIGHTNING_API_CERTIFICATE env var, which is hand-copied. When the live cert on the node is rotated/regenerated, the env var goes stale and the app starts throwing recurring "self-signed certificate" errors on dfxdev.

Change

Adds support for an optional env var LIGHTNING_API_CERTIFICATE_PATH. When it is set and the file is readable, the app reads the live certificate directly from disk. Otherwise it falls back to the existing LIGHTNING_API_CERTIFICATE env var, completely unchanged.

  • New module-level readCert() helper in src/config/config.ts feeds the existing certificate config field.
  • The lightning-client TLS logic (HTTPS agent ca) is untouched.
  • .env.example documents the new optional var.

Backward compatibility

Fully backward compatible. With no LIGHTNING_API_CERTIFICATE_PATH set, behavior is identical to before (and an unreadable path silently falls back to the env var). Safe to deploy first — no behavior change until the path env is set.

Related

Testing

  • npx tsc --noEmit — passes
  • jest config + lightning specs — 18 passing

Add optional LIGHTNING_API_CERTIFICATE_PATH env var. When set and the file is readable, the LND TLS certificate is read from disk (the live cert); otherwise it falls back to the existing LIGHTNING_API_CERTIFICATE env var, unchanged. Fully backward compatible.
@davidleomay

Copy link
Copy Markdown
Member

Suggestion: remove the fallback entirely

The silent catch-all fallback to LIGHTNING_API_CERTIFICATE makes deployment errors invisible. If LIGHTNING_API_CERTIFICATE_PATH is set but the file is missing or unreadable (misconfigured volume mount, wrong path, deploy order mistake), we silently fall back to the Vault-stored copy — and won't notice until the live cert rotates and goes stale, which is the exact problem this PR aims to fix.

Hidden fallbacks are also confusing when debugging: "is my app using the live cert or the stale one?"

Since:

  1. fix(lightning): reuse https Agent across LND requests #3854 (cached https.Agent) already prevents the TLS error from stale certs
  2. The paired infra PR Feature/dev 533 bank account api #366 ensures the file is mounted at container start
  3. No scenario exists where the file path is set but shouldn't be used

→ I'd remove the fallback and the LIGHTNING_API_CERTIFICATE env var entirely. If the path is set, read it or crash — that makes misconfigurations visible immediately.

@Danswar

Danswar commented Jun 10, 2026

Copy link
Copy Markdown
Collaborator Author

Done — removed the fallback. readCert() now reads LIGHTNING_API_CERTIFICATE_PATH and throws if it's unset/unreadable, so a broken mount fails loudly instead of silently using a stale cert. Dropped LIGHTNING_API_CERTIFICATE from .env.example too.

One knock-on: this app code is shared with dfxprd, which wasn't in the original (dfxdev-only) scope. To avoid breaking prod once the env var is gone, I also migrated dfxprd in the infra PR (mount the live cert + set the path env on the prod dfx-api/lds-api services). See DFXServer/server#366.

@github-actions

github-actions Bot commented Jun 10, 2026

Copy link
Copy Markdown

⚠️ Unverified Commits (1)

The following commits are not signed/verified:

  • 49ac77e Read LND cert from file only, drop env-var fallback (Danswar)
How to sign commits
# SSH signing (recommended)
git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/id_ed25519.pub
git config --global commit.gpgsign true

# Re-sign last commit
git commit --amend -S --no-edit
git push --force-with-lease

@davidleomay davidleomay left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved. Deploy after server PR (DFXServer/server#366) — that adds the cert mount + LIGHTNING_API_CERTIFICATE_PATH env var.

@Danswar Danswar force-pushed the feat/lightning-cert-from-file branch from c9ee3d6 to 49ac77e Compare June 10, 2026 15:00
@Danswar

Danswar commented Jun 10, 2026

Copy link
Copy Markdown
Collaborator Author

Small refinement after CI: readCert() only throws when LIGHTNING_API_CERTIFICATE_PATH is set but unreadable (your point — no silent fallback on a broken mount). When the path is unset it returns undefined instead of throwing, because Configuration is built eagerly at import and a hard throw broke every test suite that loads config (CI sets no Lightning env). Net effect is the same in real deploys (path is always set via compose); this just keeps non-Lightning environments (tests/CI) bootable. CI green now.

Address review: if LIGHTNING_API_CERTIFICATE_PATH is set, read it or throw.
The LIGHTNING_API_CERTIFICATE env var was the stale copy this change fixes,
so keeping it as a silent fallback only masks a broken mount. Remove it.
@Danswar Danswar force-pushed the feat/lightning-cert-from-file branch from 49ac77e to bf4ee74 Compare June 10, 2026 15:09
@Danswar Danswar merged commit 45776c7 into develop Jun 10, 2026
7 checks passed
@Danswar Danswar deleted the feat/lightning-cert-from-file branch June 10, 2026 15:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants