Org Sharing
Personal vault sync uses one wrapping key per machine. Org sharing is more interesting: multiple users need to decrypt the same blob, but no shared key exists. LPM uses an X25519 + AES scheme similar to ECIES to wrap the vault's AES key once per member.
Org sharing requires an Org plan.
How sharing works
lpm env share --org <org-slug> # share the current vault with an org
The flow when you first share:
- Each org member has already registered an X25519 public key with lpm.dev (the server stores public keys in
user_public_keys; private keys live on member machines). - The vault has a single AES key that encrypts the blob (same as personal sync).
- The AES key is wrapped per member — once for each member's X25519 public key, producing one row in
vault_org_keysper member. - On
pull: each member uses their X25519 private key to unwrap their copy of the AES key, then decrypts the blob.
[shared encryptedBlob] ← one ciphertext, AES-256-GCM
▲
│ decrypted with the per-vault AES key
│
[per-vault AES key]
┌────┼────┬────┬────┐
▼ ▼ ▼ ▼ ▼
alice bob carol dave eve ← one wrapped copy per member
(X25519 wrap) stored in vault_org_keys
Wire format for each wrapped entry: base64(ephemeral_public):base64(iv):base64(ciphertext+tag).
Adding a member
When an admin (or anyone with the rotate permission) wants to add a new member:
- Pull the AES key from your own wrapped copy (you already have decrypt access).
- Re-wrap it with the new member's X25519 public key.
- Push the new wrapped-key entry to
POST /api/orgs/{slug}/vaults/....
This happens automatically when a member joins an org that owns a vault you've shared, but it can also be triggered manually after the fact. The new member can lpm env pull immediately.
Removing a member
Removing a member is two steps, both of which matter:
- Drop the member's wrapped-key entry. RLS lets org admins do this from the dashboard or via API. This makes the server stop returning a wrapped key for that user on
pull. - Rotate the AES key. The leaver's copy of the old key still works against the old encrypted blob — they could still decrypt anything they downloaded before being removed, and could still decrypt blobs encrypted under that AES key if they ever obtained one. Rotation regenerates the AES key, re-encrypts the blob, and re-wraps for every remaining member:
lpm env rotate-key # rotates AES, re-wraps, re-encrypts, pushes
After rotation, the leaver's old wrapped key cannot decrypt the new blob, and the new blob is the only one the server returns.
If you skip the rotation step, you've revoked server-side access but not cryptographic access to data the leaver already downloaded. For real revocation, always rotate after removing.
Personal AND org rows for the same vault-id
Vault rows are keyed by (vaultId, userId) for personal entries and (vaultId, orgId) for org entries — both indexes coexist. The same vaultId can have both a personal row (for the owner) and an org row (shared). The CLI picks which side to read based on context:
lpm env pushagainst a project owned by a user → personal rowlpm env push --org acmeagainst the same project → org rowlpm env pulldefaults to whichever side the project is associated with
This lets a user "promote" a personal vault to an org vault without losing the personal copy as a fallback during the transition.
Audit visibility
For org vaults:
- Members with role
owner/admin/maintainersee the full audit log (every member's actions). - Members with lower roles cannot read other members' actions — RLS-enforced.
lpm env log # last 50 entries (filtered by your role)
The dashboard shows the same data with filters and time-range queries.
What's not supported
- Per-key permissions. Org members either have read access to the whole vault or no access. Per-key ACLs are a future ask.
- Per-environment permissions. A member with read access to a vault sees every environment in it. If you need to gate
productionseparately, use OIDC policies for CI (which do scope per-environment) or split into separate projects/vaults.
Plan
Org sharing requires an Org plan. Pro plans get personal cloud sync but not multi-member sharing.
Next
- Cloud Sync — the personal foundation org sharing extends
- Dashboard Pairing — how each member's other devices unlock
- OIDC for CI — per-environment policies that work alongside org sharing