1
0
mirror of https://github.com/bitwarden/server synced 2026-02-02 01:33:19 +00:00
Files
server/util/Seeder
..
2026-01-14 09:02:49 -05:00

Bitwarden Database Seeder

A class library for generating and inserting properly encrypted test data into Bitwarden databases.

Domain Taxonomy

Cipher Encryption States

Term Description Stored in DB?
CipherView Plaintext/decrypted form. Human-readable data. Never
Cipher Encrypted form. All sensitive fields are EncStrings. Yes

The "View" suffix always denotes plaintext. No suffix means encrypted.

EncString Format

Encrypted strings follow this format:

2.{iv}|{ciphertext}|{mac}
  • 2 = Algorithm type (AES-256-CBC-HMAC-SHA256)
  • iv = Initialization vector (base64)
  • ciphertext = Encrypted data (base64)
  • mac = Message authentication code (base64)

Data Structure Differences

SDK Structure (nested):

{ "name": "2.x...", "login": { "username": "2.y...", "password": "2.z..." } }

Server Structure (flat, stored in Cipher.Data):

{ "Name": "2.x...", "Username": "2.y...", "Password": "2.z..." }

The seeder transforms SDK output to server format before database insertion.

Key Hierarchy

Organization Key (or User Key)
       │
       ├──▶ Encrypts Cipher.Key (optional per-cipher key)
       │
       └──▶ Encrypts cipher fields directly (if no per-cipher key)

For seeding, we encrypt directly with the organization key.

Entity Relationships

Organization
    │
    ├── Collections ──┬── CollectionCipher ──┐
    │                 │                      │
    └── Ciphers ──────┴──────────────────────┘

Ciphers belong to organizations and are assigned to collections via the CollectionCipher join table.

Project Structure

Factories

Create individual domain entities with realistic encrypted data.

Factory Purpose
CipherSeeder Creates encrypted Cipher entities via Rust SDK
CollectionSeeder Creates collections with encrypted names
OrganizationSeeder Creates organizations with keys
UserSeeder Creates users with encrypted credentials

Recipes

Bulk data operations using BulkCopy for performance.

Recipe Purpose
CiphersRecipe Bulk create ciphers and assign to collections
CollectionsRecipe Create collections with user permissions
GroupsRecipe Create groups with collection access
OrganizationWithUsersRecipe Full org setup with users

Models

DTOs for SDK interop and data transformation.

Model Purpose
CipherViewDto Plaintext input to SDK encryption
EncryptedCipherDto Parses SDK's encrypted output

Rust SDK Integration

The seeder uses FFI calls to the Rust SDK for cryptographically correct encryption:

CipherViewDto → RustSdkService.EncryptCipher() → EncryptedCipherDto → Server Format

This ensures seeded data can be decrypted and displayed in the actual Bitwarden clients.