bitwarden/server
Sends
Active contributors: tools team.
Purpose
Sends are Bitwarden's encrypted, time-bounded sharing feature. A user creates a Send (text or file), optionally adds a passphrase and an access limit, and shares the access URL. Recipients open the URL, optionally enter the passphrase, and the client decrypts the payload locally. The server only ever sees ciphertext.
Where the code lives
| Layer | Path |
|---|---|
| Domain | src/Core/Tools/SendFeatures/ and src/Core/Tools/Entities/Send.cs |
| API surface | src/Api/Tools/ (sends + send-access endpoints) |
| Schema | src/Sql/dbo/Tables/Send.sql, stored procs Send_* |
| EF | src/Infrastructure.EntityFramework/Tools/Send/ |
| File storage | Azure Blob via ISendFileStorageService |
| Key rotation hooks | src/Api/KeyManagement/Validators/SendRotationValidator.cs |
Key abstractions
| Type | Path | Description |
|---|---|---|
Send |
src/Core/Tools/Entities/Send.cs |
The Send row. Stores type (Text/File), key (encrypted with the user's key), access count, expiration, optional password hash. |
SendType |
src/Core/Tools/Enums/SendType.cs |
Text or File. |
ISendService / SendService |
src/Core/Tools/SendFeatures/Services/ |
Domain logic: create / update / access / authenticate. |
SendAccessTokenable |
src/Core/Tools/Models/Business/Tokenables/SendAccessTokenable.cs |
The signed token issued to a recipient when they pass the password check. |
ISendAuthorizationService |
src/Core/Tools/SendFeatures/Services/SendAuthorizationService.cs |
Validates passwords, increments the access count, returns the SendAccessTokenable on success. |
SendsController |
src/Api/Tools/Controllers/SendsController.cs |
Owner-side CRUD endpoints. |
SendAccessController |
src/Api/Tools/Controllers/SendAccessController.cs |
Recipient-side endpoints (/sends/access/{id}, /sends/{id}/access/file/{fileId}). |
How it works
sequenceDiagram
participant Owner
participant Api
participant Recipient
Owner->>Api: POST /sends (encrypted payload, password hash?)
Api->>Api: SendService.CreateAsync
Api-->>Owner: { id, accessId, key }
Recipient->>Api: POST /sends/access/{accessId} (password)
Api->>Api: SendAuthorizationService validates
Api-->>Recipient: { encryptedPayload, sendAccessToken }
Recipient->>Recipient: decrypts client-sideThe recipient never authenticates as a Bitwarden user. The Policies.Send JWT policy is a special scope that the SendAccessController issues just for completing the access flow.
Files
For File sends, the server returns a SAS-signed Azure Blob URL on the second leg; the recipient downloads the encrypted file directly.
Limits
Free users get only Text sends; premium users get File sends. Counts and expirations are enforced server-side. Bitwarden's published limits are visible in the per-plan StaticStore definitions (src/Core/Utilities/StaticStore.cs).
Integration points
- Authentication — issuance uses normal user JWTs; access uses the special
api.send.accessscope. - Push — Send updates do not push to other devices (Sends are one-shot artefacts).
- Key rotation — when a user rotates their master password, every Send key needs re-wrapping.
SendRotationValidator(src/Api/KeyManagement/Validators/SendRotationValidator.cs) gates the rotation: clients must provide updated wrapped Send keys for every existing Send. - Audit events — Send creation / deletion logs
Send_Created/Send_Deletedevents.
Entry points for modification
- Add a new Send field → extend
Send, the request/response models, and theSendService.SaveAsyncvalidation. - Tighten access controls →
SendAuthorizationService.AuthenticateAsync. Be careful with timing-attack-prone comparisons; useCryptographicOperations.FixedTimeEquals. - Change retention →
SendCleanupJob(insrc/Api/Jobs/) deletes expired Sends. - New Send type → extend
SendType, the storage logic, and the access controller.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.