Encryption
CredenShare uses industry-standard encryption to protect every credential you share. This page details the encryption mechanisms and security architecture.
Where encryption happens
This depends on where the share is created, and the difference matters: on one path we hold a key that could decrypt your content, and on the other we hold none we can use.
| Created via | Encrypted where | Can CredenShare decrypt it? |
|---|---|---|
| Web app | In your browser | No — the key never reaches us in the clear |
| REST API | In your client | No — the API refuses plaintext |
| Official SDKs | In your process | No — the client encrypts before the request |
| Slack app | On our servers | Yes — the credential passes through Slack first |
Web and API shares
A content key is generated in the client and used to encrypt your fields with AES-256-GCM before anything is sent. That key travels in the share link's URL fragment, which browsers never transmit to a server. What we store is ciphertext plus a hash of an access token (and, with custody, sealed copies of the key), so we can serve the share to whoever holds the link without being able to read it.
The API enforces this rather than merely encouraging it: a create must declare
e2ee-aes256-gcm and supply ciphertext, and a plaintext value is rejected. See
client-side encryption for the exact wire format.
item_key_wrap, which the Node, Python and Go
SDKs send when you set their custody option, is not such a copy: nothing in the product reads it
back, so it cannot rebuild the link.Slack shares
A credential sent through the Slack app has already passed through Slack before it reaches us, so client-side encryption buys nothing. These are encrypted on our servers with AES-256 envelope encryption, using a customer-managed key in AWS KMS. We can decrypt them; we say so plainly rather than implying otherwise.
Encryption at rest
| Component | Algorithm | Key management |
|---|---|---|
| Client-encrypted content | AES-256-GCM | Key travels in the link; with custody, a share created in the browser also has a copy stored sealed to your account key (and your team's key, for team content), and an API create has one stored sealed to your account key alone when a key you granted account custody sends an account_key_wrap. An item_key_wrap can be stored with the share, but nothing in the product reads it back |
| Server-encrypted content | AES-256 envelope encryption | Customer-managed key in AWS KMS |
| Database fields | AES-256 | Managed database encryption |
Encryption in Transit
How connections to CredenShare are protected:
- Web app, share and paste hosts: TLS 1.2 or better, and an HSTS header with a one-year
max-ageandincludeSubDomains - API endpoints: HTTPS; the official SDKs default to
https://api.credenshare.io/v1 - Internal calls: our functions authenticate to AWS services with scoped IAM roles
Key Management
For shares created from the web, the REST API or an SDK there is no server-side key that can decrypt them. The content key is generated in the client and never reaches us in the clear. For a share created in the browser, zero-knowledge custody also stores a copy of it, sealed to your account key (and, for team content, to your team's key). We hold those keys only sealed under secrets we do not keep — your passphrase, which never reaches us, or the custody secret of an API key you have granted account custody, which we generate when the key is created, return to you once and never store — so we cannot open any of it.
An item_key_wrap sent with a REST API or SDK create can be stored with the share too, wrapped
to that API key's custody public key, but nothing in the product reads it back: the dashboard
does not use it to open the share or rebuild its link. A copy the dashboard can use comes from an
account_key_wrap instead: the content key wrapped to your account key, sent on a REST API create
by a key you granted account custody.
Server-encrypted (Slack) shares use envelope encryption: a new data key is generated for every encryption operation, and the master key that wraps it is customer-managed in AWS KMS.
Data Lifecycle
Client-encrypted shares — web, REST API and SDKs
Encrypt in client → Store ciphertext → Serve ciphertext → Decrypt in browser → Delete
- Encrypt: the client generates a content key and encrypts the fields
- Store: we store the ciphertext plus a hash of an access token
- Serve: we return the ciphertext to whoever presents the link
- Decrypt: the recipient's browser decrypts using the key in the URL fragment
- Delete: at expiration the ciphertext is deleted
Server-encrypted (Slack) shares
Create → Encrypt → Store → Access → Decrypt → Display → Delete
- Create: the credential arrives from the Slack dialog
- Encrypt: the server encrypts it with a per-share data key wrapped by KMS
- Store: the encrypted credential is saved to the database
- Access: the recipient visits the share URL
- Decrypt: the server asks KMS to unwrap the data key
- Display: the plaintext credential is shown to the recipient
- Delete: once expired or consumed, the encrypted data is deleted