bug: gateway add --local unconditionally overwrites mTLS certificates on repeated invocation
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 8.7k
- Forks
- 1.3k
- Avg merge
- 2d 11h
- Merged PRs (30d)
- 253
Description
Agent Diagnostic
- Skills loaded:
create-github-issue - OpenShell version tested: v0.0.91 (latest tag on
main) - Latest release checked: v0.0.91 — no related fixes in changelog or commit history
- Known fixes reviewed:
git log --grepforstore_pki_bundle,import_local_package_mtls_bundle,mtls.*overwritefound no relevant patches - Possible duplicates reviewed: #2481 covers the system-gateway shadowing entry point to the same
store_pki_bundleoverwrite. This issue covers a different trigger: repeated--localinvocations without--oidc-issuer, where no system gateway is involved. - Findings:
import_local_package_mtls_bundle()unconditionally callsstore_pki_bundle()every time it finds certs in a package-managed directory, with no comparison against existing user-config certs. The OIDC code path returns early before reaching the mTLS branch, acting as an accidental guard. - Remaining reason for filing: No guard exists in
import_local_package_mtls_bundleto skip the import when a valid bundle already exists.
Description
Actual behavior: Running openshell gateway add --local without --oidc-issuer atomically replaces the entire ~/.config/openshell/<gateway>/mtls/ directory, regardless of whether the existing certificates are valid or identical to the source.
import_local_package_mtls_bundle() (crates/openshell-cli/src/commands/gateway.rs:634) searches package-managed TLS directories and calls store_pki_bundle() (crates/openshell-bootstrap/src/mtls.rs:15) without checking whether a valid bundle already exists in the user config directory. store_pki_bundle() writes to a temp directory, backs up the existing mtls/ directory, renames the temp into place, then deletes the backup — an unconditional atomic replace.
When --oidc-issuer IS specified, the OIDC branch returns early (gateway.rs:984) before reaching the mTLS import code, so certificates are never touched. The OIDC flag acts as an accidental guard against the overwrite.
Additionally, the gateway server's certgen subcommand (crates/openshell-server/src/certgen.rs:515) also calls store_pki_bundle("openshell", &bundle) unconditionally in local mode, so server restarts that regenerate PKI will also overwrite the CLI's client certs.
Expected behavior: If a valid mTLS bundle already exists in the user config directory and matches the package-managed source (or is otherwise still valid), gateway add --local should skip the import rather than silently replacing it.
Reproduction Steps
- Manually place valid mTLS certificates (
ca.crt,tls.crt,tls.key) into~/.config/openshell/gateways/<gateway>/mtls/ - Run
openshell gateway add https://localhost:8443 --local— the existing certificates are silently replaced with certs imported from the package-managed TLS directory
Environment
- OS: macOS (Darwin 25.5.0), also affects Linux
- OpenShell: v0.0.91
- Latest release checked: yes — no related fixes found
- Possible duplicates checked: yes — #2481 covers the system-gateway shadowing path; this issue covers the
import_local_package_mtls_bundlepath
Related
- #2481 — covers the system-gateway shadowing entry point to the same
store_pki_bundleoverwrite. The fix proposed there (CLI-layer guard for system gateways) would not address this issue, since this path does not involve a system gateway.
Relevant Code Paths
crates/openshell-cli/src/commands/gateway.rs:634—import_local_package_mtls_bundle()crates/openshell-cli/src/commands/gateway.rs:987-993— mTLS branch calling the importcrates/openshell-bootstrap/src/mtls.rs:15—store_pki_bundle()atomic replacecrates/openshell-server/src/certgen.rs:515— server-sidestore_pki_bundle()call (also overwrites unconditionally)
Proposed Fix
Add a comparison in import_local_package_mtls_bundle() that reads the existing user-config bundle (if present), compares it byte-for-byte (or by cert fingerprint) against the package-managed source, and skips the store_pki_bundle() call when they match. This keeps store_pki_bundle itself unconditional — it is a low-level storage primitive — and puts the "should we reimport?" decision where the context exists.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with import_local_package_mtls_bundle() in crates/openshell-cli/src/commands/gateway.rs and read store_pki_bundle() in crates/openshell-bootstrap/src/mtls.rs to understand the replacement flow. Check the mTLS branch around gateway.rs:987-993 and the local-mode call in crates/openshell-server/src/certgen.rs:515. Done means repeated local gateway setup no longer replaces an existing valid bundle unexpectedly.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- cli, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100