Skip to content

Commit 1c6dbd8

Browse files
authored
Merge branch 'main' into add-adr-about-breaking-up-core
2 parents 9597c12 + 8355121 commit 1c6dbd8

4 files changed

Lines changed: 1348 additions & 1155 deletions

File tree

docs/architecture/adr/0030-adopt-pnpm.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
adr: "0030"
3-
status: Proposed
3+
status: Accepted
44
date: 2026-06-08
55
tags: [clients, server, sdk]
66
---
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
---
2+
adr: "0031"
3+
status: "Proposed"
4+
date: 2026-06-23
5+
tags: [server]
6+
---
7+
8+
# 0031 - Adopt Minimal APIs
9+
10+
<AdrTable frontMatter={frontMatter}></AdrTable>
11+
12+
## Context and problem statement
13+
14+
.NET 6 introduced minimal APIs — a lighter alternative to controllers designed for simplicity,
15+
speed, and ahead-of-time (AOT) compilation. As of .NET 10, minimal APIs now support automatic
16+
validation via data annotation attributes, closing the last significant feature gap with
17+
controllers.
18+
19+
The key architectural advantage: minimal APIs let us decompose the server into smaller, composable
20+
pieces. Each feature in its own library owns its `.csproj` — and its dependencies — making it
21+
straightforward to deploy a feature independently or bundle several into a single Lite container.
22+
23+
## Considered options
24+
25+
- **Keep using controllers** - Continue using controllers for all our APIs. Controllers are well
26+
understood by the team and have a proven track record. However, controllers are no longer
27+
Microsoft's preferred direction, have no path to AOT compatibility, and resist the composable
28+
architecture we're moving toward.
29+
- **Use minimal APIs for new endpoints** - Controllers and minimal APIs can be used side-by-side;
30+
new features can use minimal APIs exclusively, segregating their concerns in their own project.
31+
This also keeps a future AOT compilation path open.
32+
- **Migrate controllers to minimal APIs** - We could ban controllers entirely and embark on an
33+
aggressive switch to minimal APIs, resulting in a consistent codebase with no mixed styles.
34+
However, this is very time-consuming, and there are other pieces that need to fall into place
35+
before we can achieve AoT compilation anyway — so we wouldn't get the performance benefits right
36+
away.
37+
38+
## Decision outcome
39+
40+
Chosen option: **Use minimal APIs for new endpoints**.
41+
42+
New endpoints use minimal APIs, placed in a feature-scoped library that exposes two methods:
43+
`Add[Feature]Services` and `Map[Feature]Endpoints`. The host service calls both under an endpoint
44+
group, which makes extracting any feature into a standalone service behind a reverse proxy
45+
straightforward later.
46+
47+
```csharp
48+
// Feature library: MyFeature/ServiceCollectionExtensions.cs
49+
public static IServiceCollection AddMyFeatureServices(this IServiceCollection services)
50+
{
51+
services.TryAddScoped<IMyFeatureService, MyFeatureService>();
52+
return services;
53+
}
54+
55+
// Feature library: MyFeature/EndpointRouteBuilderExtensions.cs
56+
public static RouteGroupBuilder MapMyFeatureEndpoints(this IEndpointRouteBuilder routes)
57+
{
58+
var group = routes.MapGroup("");
59+
group.MapGet("/", GetAll);
60+
group.MapPost("/", Create);
61+
return group;
62+
}
63+
64+
// Host service: Program.cs
65+
builder.Services.AddMyFeatureServices();
66+
67+
app.UseEndpoints(endpoints =>
68+
{
69+
endpoints.MapDefaultControllerRoute();
70+
endpoints.MapGroup("/my-feature")
71+
.MapMyFeatureEndpoints();
72+
});
73+
```
74+
75+
### Positive consequences
76+
77+
- Better segregation of features similar to clients and sdk-internal
78+
- Teams own their feature library's `.csproj`, giving them direct control over their package
79+
dependencies
80+
- Easier path to breaking a feature out as its own service, or composing features into a Lite
81+
container
82+
- Enables a future path to AoT compilation, improving cold-start performance
83+
84+
### Negative consequences
85+
86+
- A new way of writing endpoints has to be learned
87+
- Controllers and minimal APIs will coexist in the codebase for the foreseeable future, which
88+
increases the surface area developers need to be familiar with
89+
- `ActionFilterAttribute`s must be rewritten as endpoint filters before any controller that uses
90+
them can be migrated to minimal APIs
91+
92+
### Plan
93+
94+
An `ENDPOINT_LIBRARY.md` in `src/Libraries` will document the canonical library shape, how to wire
95+
it into the existing monolith, and the path to extracting a feature as a standalone service.
96+
97+
New endpoints added to existing controller-based projects should still use minimal APIs where
98+
possible, even if not yet in their own feature-scoped library. Existing controllers will be migrated
99+
opportunistically. Icons, Notifications, and Events are prioritized as early migration targets given
100+
their small endpoint surface area; migration for a project is considered complete when it has no
101+
remaining controller classes. Heavier projects will be migrated as opportunities arise.

docs/architecture/security/principles/01-servers-are-zero-knowledge.mdx

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,30 @@ Communicated information is limited to vault item URIs. These URIs are part of a
6464
content, but we do this to speed up loading of vaults, ensure favicons accurately represent the
6565
associated URI, and avoid leaking vault contents to local network administrators. This feature is
6666
easily disabled in client settings.
67+
68+
### Automatic confirmation policy
69+
70+
By default, users invited to join a Bitwarden organization must be confirmed by an administrator
71+
once they accept an invitation to join. The confirmation step completes the key exchange which
72+
allows for end-to-end-encrypted sharing of items between organizations and their members.
73+
74+
Enterprise organizations can optionally set up automatic confirmation of users if they do not want
75+
to manually confirm each user. Once activated, a background process will run in the unlocked browser
76+
extension of some administrator roles, which will perform this key exchange automatically upon
77+
request from the server.
78+
79+
This is incompatible with end-to-end encryption because it allows the Bitwarden server to request a
80+
key exchange on demand. Any actor with control over Bitwarden infrastructure may fabricate an
81+
invite, which would trigger the automatic confirmation process and give the attacker a copy of the
82+
organization key. This can then be used to decrypt organization data.
83+
84+
For these reasons:
85+
86+
1. The feature is opt-in only and administrators are warned about the security implications. The
87+
feature cannot be activated by the server acting alone - each browser extension that wishes to
88+
perform the key exchange must also enable a setting that can only be set locally on that device.
89+
90+
2. The organization and its members are cryptographically isolated from other organizations,
91+
providers and users to prevent cryptographic traversal and the compromise of other parties. These
92+
measures are outlined in our
93+
[help documentation](https://bitwarden.com/help/automatic-confirmation/).

0 commit comments

Comments
 (0)