Skip to content

Commit 58f1f95

Browse files
authored
Merge branch 'main' into ps/include-end-to-end-encryption-in-security-principles
2 parents e029710 + 65d9ce4 commit 58f1f95

File tree

33 files changed

+4621
-2157
lines changed

33 files changed

+4621
-2157
lines changed
Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
1-
name: "Pull Request Labeler"
1+
name: Label
22

33
on:
4-
pull_request_target: {}
4+
pull_request:
55

66
jobs:
7-
labeler:
8-
name: "Pull Request Labeler"
7+
label:
8+
name: Label
9+
runs-on: ubuntu-22.04
910
permissions:
1011
contents: read
1112
pull-requests: write
12-
runs-on: ubuntu-22.04
13+
1314
steps:
14-
- uses: actions/labeler@8558fd74291d67161a8a78ce36a881fa63b766a9 # v5.0.0
15+
- name: Label pull request
16+
uses: actions/labeler@8558fd74291d67161a8a78ce36a881fa63b766a9 # v5.0.0
1517
with:
1618
sync-labels: true # Remove labels if matches are removed

.github/workflows/scan.yml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ jobs:
2929
ref: ${{ github.event.pull_request.head.sha }}
3030

3131
- name: Scan with Checkmarx
32-
uses: checkmarx/ast-github-action@03a90e7253dadd7e2fff55f5dfbce647b39040a1 # 2.0.37
32+
uses: checkmarx/ast-github-action@184bf2f64f55d1c93fd6636d539edf274703e434 # 2.0.41
3333
env:
3434
INCREMENTAL:
3535
"${{ contains(github.event_name, 'pull_request') && '--sast-incremental' || '' }}"
@@ -45,7 +45,7 @@ jobs:
4545
--output-path . ${{ env.INCREMENTAL }}
4646
4747
- name: Upload Checkmarx results to GitHub
48-
uses: github/codeql-action/upload-sarif@9278e421667d5d90a2839487a482448c4ec7df4d # v3.27.2
48+
uses: github/codeql-action/upload-sarif@d68b2d4edb4189fd2a5366ac14e72027bd4b37dd # v3.28.2
4949
with:
5050
sarif_file: cx_result.sarif
5151

@@ -65,10 +65,9 @@ jobs:
6565
ref: ${{ github.event.pull_request.head.sha }}
6666

6767
- name: Scan with SonarCloud
68-
uses: sonarsource/sonarcloud-github-action@383f7e52eae3ab0510c3cb0e7d9d150bbaeab838 # v3.1.0
68+
uses: sonarsource/sonarqube-scan-action@bfd4e558cda28cda6b5defafb9232d191be8c203 # v4.2.1
6969
env:
7070
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
71-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
7271
with:
7372
args: >
7473
-Dsonar.organization=${{ github.repository_owner }} -Dsonar.projectKey=${{

custom-words.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ bitwardensecret
99
bytemark
1010
Casbin
1111
clickjacking
12+
codebases
1213
CODEOWNERS
1314
CQRS
1415
CTAP2
@@ -20,6 +21,7 @@ HKDF
2021
hotfix
2122
hotfixed
2223
hotfixes
24+
Hyperscale
2325
iframes
2426
inet
2527
IntelliJ

docs/architecture/adr/0014-typescript-strict.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,5 +144,24 @@ https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Null
144144
const foo = null ?? "default string";
145145
```
146146

147+
#### Use `!` on required `@Input` parameters
148+
149+
Typescript's property initialization has no knowledge of Angular's guarantees. That means that
150+
151+
```ts
152+
@Input({ required: true }) options: WebAuthnOptions;
153+
```
154+
155+
will error as `options` is not initialized in the constructor. The suggested fix is to use the
156+
non-null assert operator, `!`.
157+
158+
```ts
159+
@Input({ required: true }) options!: WebAuthnOptions;
160+
```
161+
162+
Once [required input signals][requiredInputs] are out of dev preview for us (Angular 19), we can
163+
transition to using them and initialize these kinds of parameters in the class body or constructor.
164+
147165
[null]: https://www.typescriptlang.org/tsconfig#strictNullChecks
148166
[plugin]: https://github.com/allegro/typescript-strict-plugin
167+
[requiredInputs]: https://angular.dev/guide/components/inputs#required-inputs
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Read-Only Database Replicas
2+
3+
## Context
4+
5+
Bitwarden utilizes
6+
[Azure SQL Hyperscale](https://learn.microsoft.com/en-us/azure/azure-sql/database/service-tier-hyperscale?view=azuresql)
7+
and its
8+
[high-availability replica](https://learn.microsoft.com/en-us/azure/azure-sql/database/service-tier-hyperscale-replicas?view=azuresql#high-availability-replica)
9+
available as a _read_ replica. This allows Bitwarden to double the max worker limit (along with
10+
compute, memory, and network throughput) without needing to scale up the primary database. The HA
11+
replica replicates the primary instance by mirroring the transaction log records.
12+
13+
## Vision
14+
15+
More read-only capabilities should be used in conjunction with read-only replicas, especially after
16+
stored procedures have been tuned and there are prominent performance bottlenecks relating to
17+
read-only queries.
18+
19+
## Usage
20+
21+
We currently use the read-only replica in two areas:
22+
23+
1. [Methods within the Dapper repositories](https://github.com/search?q=repo%3Abitwarden%2Fserver+%22using+%28var+connection+%3D+new+SqlConnection%28ReadOnlyConnectionString%29%29%22&type=code)
24+
with `using (var connection = new SqlConnection(ReadOnlyConnectionString))` defined.
25+
2. Data engineering pipelines that require direct connection to the database.
26+
27+
## Gotchas / Considerations
28+
29+
- [CAP Theorem](https://en.wikipedia.org/wiki/CAP_theorem) applies here. Microsoft does not
30+
guarantee data consistency and
31+
[propagation latency](https://learn.microsoft.com/en-us/azure/azure-sql/database/read-scale-out?view=azuresql#data-consistency)
32+
could vary greatly. For business logic that need consistency, read-only replicas are not a viable
33+
solution.
34+
- Lack of observability -- currently there is limited visibility into query performance metrics as
35+
well as resource utilization on the replica itself.
36+
- Long-running queries on read-only replicas can cause
37+
[blocking](https://learn.microsoft.com/en-us/azure/azure-sql/database/read-scale-out?view=azuresql#long-running-queries-on-read-only-replicas).
38+
- The HA replica is not a backup and should not be treated as such. If a destructive migration had
39+
been run on the primary instance it will be reflected on the HA replica. DR procedures will have
40+
to be carried out in this scenario and there will be data loss.

docs/architecture/index.md

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,6 @@ In this section we will cover the high level architecture of Bitwarden, how it i
88
focusing initially on how the server and clients interact with each other, before diving into the
99
details of the server and clients.
1010

11-
Since the web based clients mostly behave the same we will primarily cover the web vault, but also
12-
client specific areas for the browser extension, desktop application and CLI. The Mobile application
13-
has its own codebase.
14-
15-
The documentation of our architecture is primarily done using an interactive tool called IcePanel.
16-
It's recommend to start with one of the interactive
17-
[tours](https://s.icepanel.io/jCGiag2SENoQIU/EACm) of our application structure.
11+
Since the web-based clients mostly behave the same, we will focus on the web vault while calling out
12+
client-specific areas for the browser extension, desktop application and CLI. The mobile
13+
applications have their own codebases.

docs/architecture/mobile-clients/android/index.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,13 @@ The lowest level of the data layer are the "data source" classes. These are the
5959
that include data persisted in [Room](https://developer.android.com/jetpack/androidx/releases/room)
6060
/ [SharedPreferences](https://developer.android.com/reference/android/content/SharedPreferences),
6161
data retrieved from network requests using [Retrofit](https://github.com/square/retrofit), and data
62-
retrieved via interactions with the [Bitwarden SDK](https://github.com/bitwarden/sdk).
62+
retrieved via interactions with the [Bitwarden SDK](https://github.com/bitwarden/sdk-internal).
6363

6464
Note that these data sources are constructed in a manner that adheres to a very important principle
6565
of the app: **that function calls should not throw exceptions** (see the
66-
[style and best practices documentation](styles-best-practices.md#best-practices--kotlin) for more
67-
details.) In the case of data sources, this tends to mean that suspending functions like those
68-
representing network requests or Bitwarden SDK calls should return a
66+
[style and best practices documentation](/docs/contributing/code-style/android-kotlin.md#best-practices--kotlin)
67+
for more details.) In the case of data sources, this tends to mean that suspending functions like
68+
those representing network requests or Bitwarden SDK calls should return a
6969
[Result](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-result/) type. This is an important
7070
responsibility of the data layer as a wrapper around other third party libraries, as dependencies
7171
like Retrofit and the Bitwarden SDK tend to throw exceptions to indicate errors instead.
@@ -369,7 +369,7 @@ components. If there is any new unique UI component that is added, it should alw
369369
it should be made a shareable component.
370370

371371
Refer to the
372-
[style and best practices documentation](styles-best-practices.md#best-practices--jetpack-compose)
372+
[style and best practices documentation](/docs/contributing/code-style/android-kotlin.md#best-practices--jetpack-compose)
373373
for additional information on best practices when using Compose.
374374

375375
#### State-hoisting

docs/architecture/mobile-clients/ios/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ data sources as well as higher-level "repository" and "service" classes.
6060
The lowest level of the core layer are the data model objects. These are the raw sources of data
6161
that include data retrieved or sent via network requests, data persisted with
6262
[CoreData](https://developer.apple.com/documentation/coredata/), and data that is used to interact
63-
with the [Bitwarden SDK](https://github.com/bitwarden/sdk).
63+
with the [Bitwarden SDK](https://github.com/bitwarden/sdk-internal).
6464

6565
The models are roughly organized based on their use and type:
6666

docs/architecture/sdk/dependencies.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Dependencies
2+
3+
The SDK is structured as several standalone crates. Each crate can have their own dependencies and
4+
versions of dependencies. It's worth reading the [Dependency Resolution][dep-res] article in the
5+
Cargo Book to better understand how dependencies are resolved in Rust.
6+
7+
## Avoid adding dependencies
8+
9+
The SDK takes a conservative approach to adding dependencies. The number of direct and indirect
10+
dependencies you have are directly related to the time it takes for a clean build. Dependencies also
11+
permanently increase the base maintenance cost of the project as they require frequent updates to
12+
keep up with security patches and new features.
13+
14+
To that effort we **must** be conservative with adding dependencies. And we ask that you consider
15+
the following when evaluating a new dependency:
16+
17+
- Do we already have a dependency or transient dependency that does the same thing? If so we
18+
_should_ use that instead.
19+
- How complex is the desired functionality?
20+
- How much time would it take to implement the functionality yourself?
21+
- Is it likely to change?
22+
- How much of the dependency will we be using?
23+
- Are you only using a small part of the dependency?
24+
- Are you using the dependency in a way that is not intended?
25+
- How well maintained is the dependency?
26+
- How often are new versions released?
27+
- How many open issues does the dependency have?
28+
- Audit the dependency tree.
29+
- How many dependencies does the dependency have?
30+
- How many of those dependencies are we already using?
31+
32+
If we only ever need a small fraction of the functionality we should consider implementing it
33+
ourselves.
34+
35+
## Ranges
36+
37+
For any library we always use ranges for dependencies. This allows other crates to depend on the the
38+
SDK without requiring the exact same versions. The Cargo lockfile ensures dependencies are
39+
consistent between builds.
40+
41+
### Explicit ranges
42+
43+
We use explicit ranges for dependencies, i.e. we specify the minimum and maximum version of a
44+
dependency. This helps avoiding confusion around how Cargo expands implicit versions.
45+
46+
```toml
47+
# Bad
48+
serde = "1.0.0"
49+
serde = "1"
50+
serde = ">1"
51+
52+
# Good
53+
serde = ">1.0, <2.0"
54+
```
55+
56+
## Workspace dependencies
57+
58+
To provide a more developer-friendly experience for managing dependencies we define commonly used
59+
dependencies in our workspace `Cargo.toml`. This allow us to update dependencies across the
60+
workspace by modifying a single file.
61+
62+
Internal dependencies i.e. dependencies that are part of the same workspace **must** be defined
63+
using workspace definitions.
64+
65+
```toml
66+
# Bad
67+
bitwarden-core = { version = "1.0", path = "../bitwarden-core" }
68+
69+
# Good
70+
bitwarden-core = { workspace = true }
71+
```
72+
73+
dep-res: https://doc.rust-lang.org/cargo/reference/resolver.html

docs/architecture/sdk/index.md

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ internal private items.
1717

1818
## Architecture
1919

20-
The Bitwarden SDK is structured as a single [Git repository](https://github.com/bitwarden/sdk) with
21-
multiple internal crates. Please review the `README` in the repository for up to date information
22-
about the different crates.
20+
The Bitwarden SDK is structured as a single
21+
[Git repository](https://github.com/bitwarden/sdk-internal) with multiple internal crates. Please
22+
review the `README` in the repository for up to date information about the different crates.
2323

2424
We generally strive towards extracting features into separate crates to keep the `bitwarden-core`
2525
crate as lean as possible. This has multiple benefits such as faster compile-time and clear
@@ -98,9 +98,7 @@ WebAssembly module that can be used in JavaScript / TypeScript. To ensure compat
9898
browsers that do not support WebAssembly, we also generate a JavaScript module from the WebAssembly
9999
that can be used as a fallback.
100100

101-
The WebAssembly module is published on [npm](https://www.npmjs.com/package/@bitwarden/sdk-wasm) and
102-
prerelease builds are published on
103-
[GitHub Packages](https://github.com/bitwarden/sdk/pkgs/npm/sdk-wasm).
101+
The WebAssembly module is published on [npm](https://www.npmjs.com/package/@bitwarden/sdk-internal).
104102

105103
### C bindings
106104

docs/architecture/sdk/versioning.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ There may be certain functionality that is actively being developed and is not y
1010
cases, they should be marked as such and gated behind a `unstable` feature flag. Consuming client
1111
applications should avoid merging changes that depend on these features into `main`.
1212

13-
To track breaking changes, we use a [changelog file in the `bitwarden` crate][changelog]. This file
14-
should be updated with noteworthy changes for each PR.
13+
## Public APIs
1514

16-
[changelog]: https://github.com/bitwarden/sdk/blob/main/crates/bitwarden/CHANGELOG.md
15+
To track breaking changes to the public APIs for Secrets Manager, we use a [changelog file in the
16+
`bitwarden` crate][changelog]. This file should be updated with noteworthy changes.
17+
18+
[changelog]: https://github.com/bitwarden/sdk-sm/blob/main/crates/bitwarden/CHANGELOG.md
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# P01 - A locked vault is secure
2+
3+
Clients must ensure that highly sensitive vault data cannot be accessed in plain text once the vault
4+
has been locked, even if the device becomes compromised after the lock occurs. Protections are not
5+
guaranteed if the device is compromised before the vault is locked.
6+
7+
## Technical Considerations
8+
9+
Achieving this principle depends on the limitations of the platform and environment. For instance,
10+
in environments like JavaScript, where memory management is not fully under the control of the
11+
client, there may be residual plaintext in memory after the vault is locked. While ideal protection
12+
cannot be guaranteed in such cases, efforts must be made to minimize these risks through techniques
13+
such as clearing memory buffers and leveraging platform security features when available.
14+
15+
## Key storage mechanisms must provide adequate protection
16+
17+
Mechanisms used for storing encryption keys when the vault is locked, such as PINs or auto-login,
18+
must provide an appropriate level of security. If encryption keys are stored in less secure
19+
environments (e.g. in the OS's keyring), the associated risks must be carefully considered and
20+
mitigated to ensure that unauthorized access to the vault remains limited, even when convenience
21+
features are used.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# P02 - Limited security for vaults on semi-compromised devices
2+
3+
:::info Note
4+
5+
This principle applies only to unlocked vaults. Refer to [P01](./locked-vault-is-secure) for details
6+
on protections for locked vaults.
7+
8+
:::
9+
10+
A semi-compromised device is one where malware exists in User Space but has not breached Kernel or
11+
OS-level protections. On such devices, clients must leverage available protections to prevent
12+
malware from accessing plaintext vault data while the vault is unlocked.
13+
14+
- **Technical controls** (e.g., data compartmentalization or HSMs): Clients should maximize the use
15+
of Kernel/OS-level protections or other available system mechanisms to safeguard vault data.
16+
- **Administrative controls** (e.g., biometrics, 2FA, approval flows): Clients should balance
17+
security and usability, avoiding excessive complexity in the user flow.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# P03 - No security on fully compromised systems
2+
3+
:::info Note
4+
5+
This principle applies only to unlocked vaults. Refer to [P01](./locked-vault-is-secure) for details
6+
on protections for locked vaults.
7+
8+
:::
9+
10+
:::info Note
11+
12+
Bitwarden does not currently support Trusted Execution Environments (TEEs). While TEEs could
13+
potentially provide a secure processing space for vault data on compromised devices, their use is
14+
limited by the environments in which Bitwarden operates. For this reason, TEEs are not considered
15+
when defining what constitutes a fully compromised device.
16+
17+
:::
18+
19+
When hardware or OS-level integrity is fully compromised, vault data may become accessible to
20+
attackers. While Bitwarden continuously strives to provide robust protections, certain threats fall
21+
beyond the reach of software-based security measures.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# P04 - Controlled access to vault data
2+
3+
Clients must ensure that vault data, whether at rest or in use, is accessible only to authorized
4+
parties and always under the user's explicit control. Even when unlocked, access to vault data must
5+
be carefully restricted to specific contexts, such as autofill or explicit user actions. Isolation
6+
mechanisms must be employed, particularly in environments prone to unauthorized access—such as
7+
browsers—to prevent exposure to third parties without the user's consent.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# P05 - Minimized impact of security breaches
2+
3+
Even with robust security measures in place, user error or unforeseen vulnerabilities can lead to
4+
various security breaches, including the compromise of encryption keys or data leaks. Bitwarden
5+
should take available actions to help users limit the damage caused by such breaches, both in scope
6+
and duration. This includes:
7+
8+
- Detecting and invalidating compromised device sessions.
9+
- Rotating encryption keys to reduce the risk of “harvest now, decrypt later” attacks (forward
10+
secrecy).
11+
- Ensuring that any data added after a breach remains secure, maintaining post-compromise security.

docs/architecture/mobile-clients/android/styles-best-practices.md renamed to docs/contributing/code-style/android-kotlin.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
# Code Style Guidelines
1+
---
2+
title: Android & Kotlin
3+
---
24

3-
## Contents
5+
# Android & Kotlin
46

57
The following outlines the general code style and best practices for Android development. It is
68
expected that all developers are familiar with the code style documents referenced here and have

0 commit comments

Comments
 (0)