MCPcopy Index your code
hub / github.com/bitwarden/sdk-internal

github.com/bitwarden/sdk-internal @rust-v3.0.0

Chat with this repo
repository ↗ · DeepWiki ↗ · release rust-v3.0.0 ↗ · + Follow
7,254 symbols 20,573 edges 1,256 files 1,004 documented · 14% 1 cross-repo links
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

Bitwarden Internal SDK

This repository houses the internal Bitwarden SDKs. We also provide a public Secrets Manager SDK.

[!WARNING]

The password manager SDK is not intended for public use and is not supported by Bitwarden at this stage. It is solely intended to centralize the business logic and to provide a single source of truth for the internal applications. As the SDK evolves into a more stable and feature complete state we will re-evaluate the possibility of publishing stable bindings for the public. The password manager interface is unstable and will change without warning.

Crates

The project is structured as a monorepo using cargo workspaces. Some of the more noteworthy crates are:

Requirements

  • Rust latest stable version - (preferably installed via rustup).
  • NodeJS and NPM.

Setup instructions

  1. Clone the repository:

    bash git clone https://github.com/bitwarden/sdk-internal.git cd sdk-internal

  2. Install the dependencies:

    bash npm ci

Building

Run the following command:

cargo build

Special considerations for Windows on ARM

For Windows on ARM, you will need the following in your PATH:

Integrating builds into client applications for local development

Integrating the SDK into client applications for local development requires two steps:

  1. Building sdk-internal with bindings specific to the client application, and
  2. Linking the build with your client for consumption there.

The instructions are different depending on the client that will be consuming the SDK.

[!NOTE]

These instructions assume a directory structure similar to:

text sdk-internal/ clients/ ios/ android/

If your repository directory structure differs you will need to adjust the commands accordingly.

Web clients

Building

Build the SDK to expose WASM bindings, which will be consumed by our web clients, by following the instructions in crates/bitwarden-wasm-internal.

After completing these instructions, you'll have built an SDK artifact that includes either OSS-licensed code, or both OSS- and commercially-licensed code, based on your choice of build script. See Licensing for details on why we have multiple packages and determine which one(s) you need to build.

Linking

The web clients use NPM to install sdk-internal as a dependency. NPM offers a dedicated command [link][npm-link] which can be used to temporarily replace the packages with a locally-built version.

When building the web sdk-internal artifacts, you had the option to build the OSS or the commercially-licensed version. You will need to adjust your npm link command according to which one you built, and which one you intend to make available to the client application for your local development.

Desired client build Build script you ran SDK artifact built Link command Result
OSS ./build.sh Artifact with OSS-licensed code npm link ../sdk-internal/crates/bitwarden-wasm-internal/npm SDK with OSS-licensed code linked to clients
Commercial (Bitwarden license) ./build.sh && ./build.sh -b Artifact with both OSS and commercially-licensed code npm link ../sdk-internal/crates/bitwarden-wasm-internal/npm ../sdk-internal/crates/bitwarden-wasm-internal/bitwarden_license/npm SDK with both OSS and commercially-licensed code linked to clients

Running npm link will restore any previously linked packages, so only the paths in the last run command will be linked. When doing commercial development, always link both packages (as shown above) so that changes to OSS types are also reflected in the client — linking only the commercially-licensed package will leave OSS types stale.

[!WARNING]

Running npm ci or npm install will replace the linked packages with the published version.

Android

Building

Build the SDK to expose Kotlin bindings through UniFFI, which will be consumed by our Android mobile app. Follow the instructions in crates/bitwarden-uniffi/kotlin.

Linking

  1. Build and publish the SDK to the local Maven repository:

bash ../sdk-internal/crates/bitwarden-uniffi/kotlin/publish-local.sh

  1. Set the user property localSdk=true in the user.properties file.

iOS

Building

Build the SDK to expose iOS bindings through UniFFI, which will be consumed by our iOS mobile app. Follow the instructions in crates/bitwarden-uniffi/swift.

Linking

Run the bootstrap script with the LOCAL_SDK environment variable set to true in order to use the local SDK build:

LOCAL_SDK=true ./Scripts/bootstrap.sh

Integrating into clients from published artifacts

[!WARNING]

BREAKING CHANGES When a pull request is opened to merge changes from sdk-internal into main, a Breaking Change Detection workflow will run and comment on the PR if breaking changes are detected on any clients. If your PR includes breaking changes you must be prepared to address them as soon as they merge with a corresponding PR in the client application repository. If not, any subsequent sdk-internal integrations into clients will be blocked, as those other teams will not know how best to resolve the breaking API contracts that you introduced.

In addition to linking to local builds during development, you will need to be able to integrate your sdk-internal changes into published artifacts, so that the client applications can be tested and published with the requisite SDK changes included.

The process for doing so varies based on the client, as the method by which the sdk-internal package is consumed differs.

Web clients

For our web clients, the sdk-internal packages for our OSS- and commercially-licensed SDK versions with their WebAssembly bindings is published to npm at:

  • https://www.npmjs.com/package/@bitwarden/sdk-internal and
  • https://www.npmjs.com/package/@bitwarden/commercial-sdk-internal

These npm packages are referenced as dependencies in our clients repo. See Licensing for details on why we have multiple packages.

Every commit to main in sdk-internal will trigger a publish of these packages, with versions structured as follows:

{SemanticVersion}-main.{actionRunNumber}

For example:

0.1.0-main.470

[!TIP]

To see what version is published to npm for a given publish action, you can check the Summary of the publish action in Github.

When you have completed development of changes in sdk-internal and need to consume them in the client application, you will need to update the npm dependency in your feature branch to reference the new SDK version:

  1. Merge the sdk-internal pull request. This will trigger a publish of the latest changes to npm.
  2. Update the versions of the sdk-internal dependencies in clients to reference this version. You can do this either:

  3. By updating to the latest version using npm install @bitwarden/sdk-internal@latest and npm install @bitwarden/commercial-sdk-internal@latest, or

  4. By referencing the specific published version, using npm install @bitwarden/sdk-internal@{version} and npm install @bitwarden/commercial-sdk-internal@{version}.

  5. Open a clients pull request to merge the client application changes that include this new sdk-internal version.

Mobile clients

The iOS and Android applications use an automated, reactive approach to integrating sdk-internal changes into their repositories.

When you need to integrate sdk-internal changes into the iOS or Android applications, you should use the automatically-generated pull requests for each repository:

Client SDK workflow Client workflow
Android https://github.com/bitwarden/sdk-internal/blob/main/.github/workflows/build-android.yml https://github.com/bitwarden/android/actions/workflows/sdlc-sdk-update.yml
iOS https://github.com/bitwarden/sdk-internal/blob/main/.github/workflows/build-swift.yml https://github.com/bitwarden/ios/actions/workflows/sdlc-sdk-update.yml

Server API Bindings

We auto-generate the server bindings using openapi-generator, which creates Rust bindings from the server OpenAPI specifications. These bindings are regularly updated to ensure they stay in sync with the server.

The bindings are exposed as multiple crates, one for each backend service:

When performing any API calls the goal is to use the generated bindings as much as possible. This ensures any changes to the server are accurately reflected in the SDK. The generated bindings are stateless, and always expects to be provided a Configuration instance. The SDK exposes these under the get_api_configurations function on the Client struct.

You should not expose the request and response models of the auto-generated bindings and should instead define and use your own models. This ensures the server request / response models are decoupled from the SDK models and allows for easier changes in the future without breaking backwards compatibility.

We recommend using either the From or TryFrom conversion traits depending on if the conversion requires error handling or not. Below are two examples of how this can be done:

```rust

use bitwarden_crypto::EncString;

use serde::{Serialize, Deserialize};

use serde_repr::{Serialize_repr, Deserialize_repr};

#[derive(Serialize, Deserialize, Debug, Clone)]

struct LoginUri {

pub uri: Option,

pub r#match: Option,

pub uri_checksum: Option,

}

#[derive(Clone, Copy, Serialize_repr, Deserialize_repr, Debug, PartialEq)]

#[repr(u8)]

pub enum UriMatchType {

Domain = 0,

Host = 1,

StartsWith = 2,

Exact = 3,

RegularExpression = 4,

Never = 5,

}

#[derive(Debug)]

struct VaultParseError;

impl TryFrom for LoginUri { type Error = VaultParseError;

fn try_from(uri: bitwarden_api_api::models::CipherLoginUriModel) -> Result<Self, Self::Error> {
    Ok(Self {
        uri: EncString::try_from_optional(uri.uri)
            .map_err(|_| VaultParseError)?,
        r#match: uri.r#match.map(|m| m.into()),
        uri_checksum: EncString::try_from_optional(uri.uri_checksum)
            .map_err(|_| VaultParseError)?,
    })
}

}

impl From for UriMatchType { fn from(value: bitwarden_api_api::models::UriMatchType) -> Self { match value { bitwarden_api_api::models::UriMatchType::Domain => Self::Domain, bitwarden_api_api::models::UriMatchType::Host => Self::Host, bitwarden_api_api::models::UriMatchType::StartsWith => Self::StartsWith, bitwarden_api_api::models::UriMatchType::Exact => Self::Exact, bitwarden_api_api::models::UriMatchType::RegularExpression => Self::RegularExpression,

Extension points exported contracts — how you extend this code

PayloadTypeName (Interface)
This trait is used to ensure that the payload type has a topic associated with it. [7 implementers]
crates/bitwarden-ipc/src/message.rs
CipherKind (Interface)
Helper trait for operations on cipher types. [8 implementers]
crates/bitwarden-vault/src/cipher/cipher.rs
Policy (Interface)
Defines the filtering behavior for a specific policy type. Implement this trait to control how a policy is enforced. [12 …
crates/bitwarden-policies/src/filter.rs
InnerFieldType (Interface)
Trait to define field type and value conversion for inner field types [8 implementers]
crates/bitwarden-exporters/src/cxf/editable_field.rs
Sealed (Interface)
This trait is used to seal the `ConstContentFormat` trait, preventing external implementations. [9 implementers]
crates/bitwarden-crypto/src/content_format.rs
BwCommand (Interface)
Trait implemented by commands that participate in the typestate dispatch. Commands that don't depend on auth/lock state [5 …
crates/bw/src/client_state.rs
ClientManagedTokens (Interface)
(no doc) [9 implementers]
crates/bitwarden-core/src/auth/auth_tokens.rs
ServerCommunicationConfigRepository (Interface)
Repository for storing server communication configuration This trait abstracts storage to allow TypeScript implementati [4 …
crates/bitwarden-server-communication-config/src/repository.rs

Core symbols most depended-on inside this repo

to_string
called by 2024
crates/bitwarden-crypto/src/enc_string/symmetric.rs
as_str
called by 582
crates/bitwarden-auth/src/api/enums/scope.rs
clone
called by 558
crates/bitwarden-ipc/src/ipc_client.rs
parse
called by 543
crates/bitwarden-uuid-macro/src/lib.rs
request
called by 504
crates/bitwarden-ipc/src/ipc_client_ext.rs
process_with_json_response
called by 269
crates/bitwarden-api-base/src/request.rs
as_ref
called by 261
crates/bitwarden-crypto/src/content_format.rs
process_with_empty_response
called by 230
crates/bitwarden-api-base/src/request.rs

Shape

Method 3,300
Function 2,071
Class 1,378
Enum 347
Interface 158

Languages

Rust100%
Kotlin1%
TypeScript1%

Modules by API surface

crates/bitwarden-vault/src/cipher/cipher.rs75 symbols
crates/bitwarden-api-api/src/apis/mod.rs73 symbols
crates/bitwarden-core/src/key_management/crypto.rs71 symbols
crates/bitwarden-crypto/src/store/context.rs60 symbols
crates/bitwarden-fido/src/types.rs54 symbols
crates/bitwarden-wasm-internal/src/pure_crypto.rs53 symbols
crates/bitwarden-user-crypto-management/src/key_rotation/sync.rs51 symbols
crates/bitwarden-api-api/src/apis/ciphers_api.rs50 symbols
crates/bitwarden-crypto/src/keys/symmetric_crypto_key.rs49 symbols
crates/bitwarden-server-communication-config/src/client.rs47 symbols
crates/bitwarden-auth/src/send_access/api/token_api_error_response.rs46 symbols
crates/bitwarden-vault/src/cipher/cipher_client/mod.rs39 symbols

Used by 1 indexed graphs manifest dependencies, hub-wide

For agents

$ claude mcp add sdk-internal \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact