writing-server-code

Bitwarden server code conventions for C# and .NET. Use when working in the server repo, creating commands, queries, services, or API endpoints. Also use when…

npx skills add https://github.com/bitwarden/server --skill writing-server-code

Architectural Rationale

Command Query Separation (CQS)

New features should use the CQS pattern — discrete action classes instead of large entity-focused services. See ADR-0008.

Why CQS matters at Bitwarden: The codebase historically grew around entity-focused services (e.g., CipherService) that accumulated hundreds of methods. CQS breaks these into single-responsibility classes (CreateCipherCommand, GetOrganizationApiKeyQuery), making code easier to test, reason about, and modify without unintended side effects.

Commands = write operations. Change state, may return result. Named after the action: RotateOrganizationApiKeyCommand.

Queries = read operations. Return data, never change state.

When NOT to use CQS: When modifying existing service-based code, follow the patterns already in the file. Don't refactor to CQS unless explicitly asked. If asked to refactor, apply the pattern only to the scope requested.

Caching

When caching is needed, follow the conventions in CACHING.md. Use IFusionCache instead of IDistributedCache.

Don't implement caching unless requested. If a user describes a performance problem where caching might help, suggest it — but don't implement without confirmation.

GUID Generation

Always use CoreHelpers.GenerateComb() for entity IDs — never Guid.NewGuid(). Sequential COMBs prevent SQL Server index fragmentation that random GUIDs cause on clustered indexes, which is critical for Bitwarden's database performance at scale.

Library shape

When creating or modifying code under src/Libraries/, read src/Libraries/LIBRARY.md — it is the canonical shape and covers public surface, settings, endpoints, repositories, and cross-library dependencies.

Critical Rules

These are the most frequently violated conventions. Claude cannot fetch the linked docs at runtime, so these are inlined here:

  • Use TryAdd* for DI registration (TryAddScoped, TryAddTransient) — prevents duplicate registrations when multiple modules register the same service
  • File-scoped namespacesnamespace Bit.Core.Vault; not namespace Bit.Core.Vault { ... }
  • Nullable reference types are enabled (ADR-0024) — use ! (null-forgiving) when you know a value isn't null; use required modifier for properties that must be set during construction
  • Async suffix on all async methodsCreateAsync, not Create, when the method returns Task
  • Controller actions return ActionResult<T> — not IActionResult or bare T
  • Testing with xUnit — use [Theory, BitAutoData] (not [AutoData]), SutProvider<T> for automatic SUT wiring, and Substitute.For<T>() from NSubstitute for mocking

Examples

GUID generation

// CORRECT — sequential COMB prevents index fragmentation
var id = CoreHelpers.GenerateComb();

// WRONG — random GUIDs fragment clustered indexes
var id = Guid.NewGuid();

DI registration

// CORRECT — idempotent, won't duplicate
services.TryAddScoped<ICipherService, CipherService>();

// WRONG — silently duplicates registration, last-wins causes subtle bugs
services.AddScoped<ICipherService, CipherService>();

Namespace style

// CORRECT — file-scoped
namespace Bit.Core.Vault.Commands;

// WRONG — block-scoped
namespace Bit.Core.Vault.Commands
{
    // ...
}

Further Reading

Lebih banyak skill dari bitwarden

analyzing-git-sessions
bitwarden
Menganalisis komit git dan perubahan dalam rentang waktu atau rentang komit, memberikan ringkasan terstruktur untuk tinjauan kode, retrospektif, catatan kerja, atau sesi…
official
figma-to-angular
bitwarden
Skill ini mengubah spesifikasi desain Figma menjadi komponen Angular yang sudah diimplementasikan sepenuhnya dengan cerita Storybook di dalam monorepo Bitwarden Clients. Outputnya harus sesuai secara visual dengan desain sambil mengikuti semua konvensi basis kode.
official
agent-access
bitwarden
Retrieve login credentials, API keys, and secrets (username, password, TOTP) from the user's Bitwarden vault via aac. Use when you need credentials to sign…
official
action-audit
bitwarden
Audit penggunaan aksi GitHub Actions di seluruh organisasi. Mencari aksi tertentu (mode insiden) atau memindai semua file workflow untuk aksi yang tidak sesuai…
official
action-remediate
bitwarden
Remediate GitHub Actions action findings identified by the action-audit skill. Applies the appropriate fix per action type — `@main` ref for internal…
official
analyzing-code-security
bitwarden
Keterampilan ini harus digunakan ketika pengguna meminta untuk "menganalisis kode untuk masalah keamanan", "memeriksa kerentanan OWASP", "meninjau kode terhadap CWE Top 25", "menemukan…
official
applying-bitwarden-branding
bitwarden
Apply Bitwarden brand standards — logo usage, color palette, typography, iconography, and capitalization rules — grounded in bitwarden.com/brand and the…
official
architecting-solutions
bitwarden
Merancang solusi di tingkat tim sambil tetap selaras dengan arsitektur holistik Bitwarden. Mencakup pola pikir keamanan, penilaian arsitektural,…
official