The core infrastructure backend (API, database, Docker, etc).
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
Mick Letofsky 6547361e31
PM-33964 - Unify CipherSeeder factories behind CipherSeed domain model. (#7330)
3 days ago
..
Attributes Decouple seeder cipher encryption from internal vault crates (#7211) 3 weeks ago
Data Fix 12 silent switch defaults in Seeder with fail-fast throws (#7277) 1 week ago
Factories PM-33964 - Unify CipherSeeder factories behind CipherSeed domain model. (#7330) 3 days ago
Models PM-33964 - Unify CipherSeeder factories behind CipherSeed domain model. (#7330) 3 days ago
Options PM-34033 - Add individual user seeding to preset pipeline (#7304) 4 days ago
Pipeline PM-34033 - Add user & org API key seeding and improve CLI output (#7324) 4 days ago
Queries Add query for email verification link (#6984) 2 months ago
Recipes PM-34033 - Add user & org API key seeding and improve CLI output (#7324) 4 days ago
Scenes PM-33964 - Unify CipherSeeder factories behind CipherSeed domain model. (#7330) 3 days ago
Seeds PM-34033 - Add individual user seeding to preset pipeline (#7304) 4 days ago
Services PM-34033 - Add individual user seeding to preset pipeline (#7304) 4 days ago
Steps PM-33964 - Unify CipherSeeder factories behind CipherSeed domain model. (#7330) 3 days ago
CLAUDE.md PM-33964 - Unify CipherSeeder factories behind CipherSeed domain model. (#7330) 3 days ago
IQuery.cs Add query for email verification link (#6984) 2 months ago
IScene.cs Use Scene result for SingleUserScene (#6909) 2 months ago
IStep.cs Seeder Enhancements - Phase 3 (#6973) 1 month ago
README.md PM-33964 - Unify CipherSeeder factories behind CipherSeed domain model. (#7330) 3 days ago
SceneResult.cs [PM-22263] [PM-29849] Initial PoC of seeder API (#6424) 3 months ago
Seeder.csproj Seeder Enhancements - Phase 3 (#6973) 1 month ago

README.md

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.

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.

Project Structure

The Seeder is organized around six core patterns, each with a specific responsibility:

Pipeline

Purpose: Composable architecture for fixture-based and generated seeding.

When to use: New bulk operations, especially with presets. Provides ultimate flexibility.

Flow: Preset JSON → Loader → Builder → Steps → Executor → Context → BulkCommitter

Why this architecture wins:

  • Infrastructure as Code: JSON presets define complete scenarios
  • Mix & Match: Fixtures + generation in one preset
  • Extensible: Add entity types via new step implementations

Phase order (org): Org → OrgApiKey → Roster → Owner (conditional) → Generator (conditional) → Users → Groups → Collections → Folders → Ciphers → CipherCollections → CipherFolders → CipherFavorites → PersonalCiphers Phase order (individual): IndividualUser → NamedFolders → Generator → Folders → Ciphers → FolderAssignments → FavoriteAssignments

Files: Pipeline/ folder

Factories

Purpose: Create individual domain entities with cryptographically correct encrypted data.

When to use: Need to create ONE entity (user, cipher, collection) with proper encryption.

Key characteristics:

  • Create ONE entity per method call
  • Handle encryption/transformation internally
  • Stateless (except for SDK service dependency)
  • Do NOT interact with database directly

Naming: {Entity}Seeder with Create() methods

Pipeline cipher path: Each cipher factory accepts a single CipherSeed parameter. CipherSeed.FromSeedItem() converts a deserialized SeedVaultItem into a CipherSeed for the pipeline path.

Recipes

Purpose: Orchestrate cohesive bulk operations using BulkCopy for performance.

When to use: Need to create MANY related entities as one cohesive operation.

Key characteristics:

  • Orchestrate multiple entity creations as a cohesive operation
  • Use BulkCopy for performance optimization
  • Interact with database directly
  • Compose Factories for individual entity creation
  • SHALL have a Seed() method that executes the complete recipe
  • Use method parameters (with defaults) for variations, not separate methods

Naming: {DomainConcept}Recipe with a Seed() method

Models

Purpose: DTOs that transform plaintext cipher data into encrypted form for database storage.

When to use: Need to convert CipherViewDto to EncryptedCipherDto during the encryption pipeline.

Key characteristics:

  • Pure data structures (DTOs)
  • No business logic
  • Handle serialization/deserialization (camelCase ↔ PascalCase)
  • Mark encryptable fields with [EncryptProperty] attribute

Scenes

Purpose: Create complete, isolated test scenarios for integration tests.

When to use: Need a complete test scenario with proper ID mangling for test isolation.

Key characteristics:

  • Complete, realistic test scenarios with ID mangling for isolation
  • Receive mangling service via DI — returns a map of original→mangled values for assertions
  • CAN modify database state

Naming: {Scenario}Scene with a SeedAsync() method

Queries

Purpose: Read-only data retrieval for test assertions and verification.

When to use: Need to READ existing seeded data for verification or follow-up operations.

Key characteristics:

  • Read-only (no database modifications)
  • Return typed data for test assertions

Naming: {DataToRetrieve}Query with an Execute() method

Data

Purpose: Reusable, realistic test data collections that provide the foundation for cipher generation.

When to use: Need realistic, filterable data for cipher content (company names, passwords, usernames).

Key characteristics:

  • Static readonly arrays and classes
  • Filterable by region, type, category
  • Deterministic (seeded randomness for reproducibility)
  • Composable across regions
  • Enums provide the public API

See Data/README.md for Generators and Distributions details.

Services

Purpose: Injectable services that provide cross-cutting functionality via dependency injection.

Context-aware string mangling for test isolation. Adds unique prefixes to emails and strings for collision-free test data. Enabled via --mangle CLI flag (SeederUtility) or application settings (SeederApi).

Rust SDK Integration

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

CipherViewDto → encrypt_fields (field-level encryption via bitwarden_crypto) → EncryptedCipherDto → Server Format

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