Feature proposal: share connections and their credentials with a team, through an encrypted vault on a shared folder
Maintainers usually reply within 1 day
@drbelt27 is already working on this.
Since Sep 23, 2026.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 25/100
- Issue type
- Feature
- Clarity
- Mostly clear
- Activity status
- Active
- Tech stack
- rust, typescript
Research direction
Start by reading the discussion about whether this security-sensitive feature belongs in core and what shape maintainers want; the proposal names connections.json, export_crypto, and find_connection_by_id as affected areas. The work is not ready to start until the scope and conflict policy are decided; any eventual implementation should preserve the stated secret-handling guarantees and validate both the existing tests and real multi-machine concurrency.
Written by the indexing model from the issue text.
Description
The problem
My team of a handful of developers shares a network folder (SharePoint/OneDrive, but any SMB share would do). We work on the same ~40 database servers, almost all behind per-server SSH tunnels. Today every one of us retypes the same hosts, users, passwords and tunnel credentials by hand, and when a password rotates we find out one by one, when a connection stops working.
The existing export/import gets a colleague started once, but it is a one-shot copy: after that the two machines drift apart, and there is no way to keep a set of connections in sync across a team.
I have implemented this for my own team and it is working, but before I send a pull request I would rather know whether you want the feature in core at all, and in what shape. The code touches connections.json, the keychain path and find_connection_by_id, so it is not something I want to drop on you as a surprise.
What I built
An opt-in vault file on a folder the team already shares.
Encryption. The payload is AES-256-GCM under a key derived with Argon2id from a master password the team agrees on. It reuses export_crypto, which already does exactly this for encrypted exports — I only exposed derive_key plus a seal/open pair for callers that keep their own envelope. The header stays in plain text (format, revision, KDF parameters, a verifier blob) so a wrong password is reported as a wrong password instead of surfacing as a corrupt file. The salt is generated once and lives in the header, so every member derives the same key.
The master password is never persisted. Not in the config, not in the keychain. It is asked once per launch, the 32-byte key is derived once and kept in memory for the session. That is the point of the feature, and it is also why shared connections are unusable while the vault is locked: find_connection_by_id asks the vault for a shared connection's secrets and fails if it is locked, rather than falling back to anything else.
How it fits the existing model. Shared connections are materialized into the local connections.json without their secrets, flagged shared: true. Every existing screen — the list, groups, tags — keeps working untouched. save_connections_file strips the secrets of a shared connection centrally, so no code path can leak one into the file.
Concurrency. The shared file is never held open. Each operation is a read, an in-memory merge, and at most one write, all inside a lock file that is released immediately (stale locks older than 30s are broken). The merge is a proper three-way merge against the payload of the last successful sync, cached locally and sealed with the same key — without that base you cannot tell "my colleague added this" from "I deleted this". Deletions propagate as tombstones that expire after 90 days. When the same record changed on both sides the local version wins and the resolution is logged.
What travels: connections with their credentials, the groups and tags they need, and the SSH profiles they tunnel through (including tunnel password and key passphrase) — without those a colleague receives a connection pointing at a profile they do not have.
Sharing is decided on the connections screen, on the existing multi-selection, so a whole selection costs one write to the share.
State of the code
Implemented on top of 0.23.0, with 37 new Rust tests covering the merge, the vault format and the locking, and 25 frontend tests for the pure helpers. The existing suite still passes.
To be straight about how far the testing goes: I have it running against my team's shared folder, and the single-machine flows — creating the vault, sharing a connection, locking and unlocking, the credentials moving between keychain and vault — work end to end. The concurrent case, two members writing around the same time, is covered by unit tests on the merge and the locking but has not yet been exercised with a real second machine. I am doing that with a colleague next; I did not want to describe it as proven before it is.
What I would like to know before opening the PR
- Do you want this in core? It writes credentials to a network folder, which is a security-relevant decision that belongs to you, not to me. If you would rather this lived outside core, say so and I will stop here.
- Is a per-launch master password acceptable UX for you? I deliberately refused to cache it anywhere. An alternative would be storing it in the OS keychain so it is asked once per machine, but that weakens the guarantee a lot.
- Conflict policy. I went for last-writer-wins with the local side winning and a log line, on the grounds that a diff UI for two versions of a connection is a lot of surface for a rare event. If you would rather prompt the user, that changes the design.
- Would you prefer it split? The SSH-profile part could land separately from the connection part, though a shared connection with a tunnel is not much use without it.
Happy to adjust any of this before writing the PR, and equally happy to hear that it does not belong in the project.
- Dominant language
- TypeScript
- Stars
- 5.1k
- Forks
- 335
- Avg merge
- 1d 22h
- Merged PRs (30d)
- 75
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing 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.
More from TabularisDB/tabularis
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
TabularisDB/tabularis#905 ·
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
TabularisDB/tabularis#903 ·
Maintainers usually reply within 1 day
-
[Bug]: Plugin UI slots data-grid.toolbar.actions and sidebar.footer.actions receive an empty contextOpenbug help wanted
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
TabularisDB/tabularis#892 ·
Maintainers usually reply within 1 day
-
Difficulty 4/5 3-5 days Newbie friendliness 48/100
TabularisDB/tabularis#919 · 3 comments ·
Maintainers usually reply within 1 day
-
Difficulty 3/5 1-2 days Newbie friendliness 75/100
TabularisDB/tabularis#916 ·
Maintainers usually reply within 1 day
All issues in TabularisDB/tabularis
Similar issues
-
area: backend bug priority: low
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
snapotter-hq/SnapOtter#2254 ·
Maintainers usually reply within 1 day
-
bug ticket
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
cratestack/cratestack#1154 ·
Maintainers usually reply within 1 day
-
server 消息处理器 cmd 分支补显式错误回报——竞态非法命令现走未处理拒绝Possibly taken @openaddr claimed this today. Openready-for-agent refactor wayfinder:task
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
openaddr/dafung-web#428 ·
Maintainers usually reply within 1 day
-
Flaky: mongodb-memory-server 'Port already in use' when another process starts a mongod concurrentlyOpenarea:testing bug effort:S priority:P2
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
Maintainers usually reply within 1 day
-
lens:agent lens:process process
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
thebristolsound/birdbrain#1772 ·
Maintainers usually reply within 1 day