Skip to content

About

No description, website, or topics provided.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Latest commit

 

History

2 Commits

Folders and files

Repository files navigation

Bitwarden server and client builds

The existing server and cloudflared services run the Vaultwarden deployment. Client builds are opt-in, one-shot Compose services; a regular docker compose up does not build clients.

Android Password Manager

./build-clients --target android

The native Compose equivalent is:

OUTPUT_UID=$(id -u) OUTPUT_GID=$(id -g) docker compose run --rm --build --no-deps android

Compose selects services and profiles rather than accepting a --target flag. The wrapper supplies that interface and sets artifact ownership to the invoking user. --build builds the toolchain image; the one-shot container then compiles and exports the client. docker compose build android alone only builds the toolchain image. The builder uses Linux amd64 Android tools; ARM hosts need amd64 emulation. The first build downloads the Android SDK/NDK, Rust toolchain, and dependencies, and compiles the SDK for four ABIs. Allow several GB of RAM, ample disk space, internet access, and a substantial first-build time. BUILD_JOBS=1 reduces concurrency. The app's Gradle heap defaults to 4 GB; set GRADLE_HEAP (for example, 6g) if the release shrinker needs more memory. Other compiler processes use additional RAM.

On success, artifacts/android/ contains:

  • bitwarden-foss.apk: a locally signed, non-debuggable fdroidRelease APK containing arm64-v8a, armeabi-v7a, x86_64, and x86 native SDK libraries.
  • SHA256SUMS: checksum of the signed APK.
  • sources.txt: exact Android and SDK revisions and the selected flavor.
  • LICENSE-android.txt and LICENSE-sdk.txt: upstream GPL license texts.

Check and install it with:

(cd artifacts/android && sha256sum -c SHA256SUMS)
adb install -r artifacts/android/bitwarden-foss.apk

The app uses the upstream package ID com.x8bit.bitwarden. Its local signing key differs from Bitwarden's store/release keys, so it cannot update an official installation. Subsequent local builds use the same key and can update each other. A debug APK is not used for this target.

Sources and free build configuration

Every default build checks GitHub for the latest published stable Android Password Manager release whose tag ends in -bwpm, resolves the tag to an exact commit, and fetches that commit. Drafts, prereleases, and Authenticator releases are excluded. Releases are compared by publication time across all API pages. The builder reads the SDK version from the selected checkout's version catalog and resolves its matching commit automatically. sources.txt records the release tag and both exact commits. Cached build outputs do not skip the release check.

The APK retains the checked-in local-build version metadata. Upstream's release CI overrides that metadata when publishing store builds.

The Android fdroid flavor excludes the standard flavor's Firebase, Google Play billing/review, and ML Kit dependencies. Those integrations, including Firebase push sync and ML Kit card scanning, are therefore absent. This is Bitwarden's flavor in its own F-Droid repository; this build is not an official F-Droid build or a reproducibility certification.

The SDK is compiled locally from sdk-internal, whose mobile binding crate offers GPL-3.0 licensing. The build enables upstream's bitwarden_ensure_non_commercial compile-time guard, builds no commercial feature, and substitutes the locally published SDK using upstream's supported localSdk=true setting in the untracked user.properties configuration file. An external Gradle init script routes that SDK's LOCAL version exclusively to Maven Local, so a GitHub Packages token is unnecessary. It does not edit upstream repositories or build files. Every build checks that neither upstream checkout has changes to tracked files before exporting the APK. No source patches are carried or reapplied when updating. The Android SDK/NDK are build tools downloaded from Google; their SDK licenses are accepted during image creation.

Updating upstream

To check, pull, and build the latest release, run:

./build-clients --target android

ANDROID_REF defaults to latest. An existing full-SHA ANDROID_REF in the shell environment or .env pins the build instead; remove that setting or set it to latest to enable automatic release selection. Clear an old SDK_REF override as well so the SDK follows the selected Android release. Release lookup failures stop the build; the builder does not silently use an older cached release.

For a reproducible build of a specific release:

  1. Choose a stable Password Manager release from upstream Android releases. Password Manager tags end in -bwpm; Authenticator tags are a different app.
  2. Resolve the selected tag to its full commit SHA (requires Git on the host):
ANDROID_TAG=v2026.9.1-bwpm # Replace with the release you want.
ANDROID_REF=$(git ls-remote https://github.com/bitwarden/android.git \
  "refs/tags/$ANDROID_TAG" "refs/tags/$ANDROID_TAG^{}" \
  | awk 'NR == 1 { sha = $1 } /\^\{\}$/ { sha = $1 } END { print sha }')
test "${#ANDROID_REF}" -eq 40 && \
  ANDROID_REF="$ANDROID_REF" ./build-clients --target android
  1. To pin that revision for future builds, add or update the ANDROID_REF=<resolved full SHA> entry in this directory's .env. Keep any other existing settings in that file. Remove an old SDK_REF override if present; the builder selects the SDK matching the pinned Android revision automatically.
  2. Check artifacts/android/sources.txt, run the checksum command above, and install the APK. Keep the signing volume so the installed local app accepts the update.

The SDK commit lookup uses GitHub's public commits API once per new SDK revision, then caches the result. An optional full-SHA SDK_REF override avoids that lookup; the builder checks that it matches the SDK selected by Android.

The update process requires no upstream source edits, patch rebasing, or separate SDK version selection. Upstream can still change its required Android/JDK/NDK tools or build interfaces; no external builder can guarantee compatibility with every future release. If an update changes those requirements, update this builder's toolchain configuration using upstream's build documentation. Builds fail rather than silently altering upstream code.

Self-hosted server configuration

This Android revision has no upstream build-time server URL option. The APK keeps upstream's default server selection. Set the server through the client's server selector, or use upstream's supported managed-device configuration:

Application configuration key Type Example value
baseEnvironmentUrl string https://vault.example.com

Configure this for package com.x8bit.bitwarden through an Android device/profile owner's MDM/EMM application restrictions. This is deployment configuration outside the APK and survives client upgrades without source customization. It requires a managed device or profile; an ordinary APK installation does not supply application restrictions. See Bitwarden's managed-client instructions and individual-client setup.

Caches and signing key

Compose keeps downloads/build outputs in android-build-cache and android-maven-cache, and the generated signing key/password in android-signing. The signing volume must be preserved and backed up if you want to update installed local builds. docker compose down -v removes it, along with the caches. The key is never copied to the exported artifacts or built image. The source cache is managed by the builder: tracked changes there are reset before each build. Changes belong in the build recipe, rather than in the cache.

Browser extension

./build-clients --target browser

This builds upstream's production OSS extension for Chromium (Manifest V3) and Firefox (Manifest V2), and exports into artifacts/browser/:

  • bitwarden-foss-chrome.zip and bitwarden-foss-firefox.zip: unsigned extensions.
  • SHA256SUMS: checksums of both ZIPs.
  • sources.txt: client commit, release tag, OSS variant, locked SDK package version and source commit, and Node version.
  • LICENSE-clients.txt and LICENSE-sdk.txt: upstream GPL licenses.

The builder follows upstream's OSS browser workflow: it exports the original root files, browser sources and libraries to a disposable build tree, excluding bitwarden_license/, installs the locked npm dependencies, and removes @bitwarden/commercial-sdk-internal. It runs the regular browser webpack configuration, rather than build:bit:*. The published OSS SDK package selected by the lockfile supplies the WASM SDK; this target does not rebuild it from Rust. Export requires a successful build, a module graph with no commercial source/package references, a valid manifest, and the SDK WASM artifact. The upstream checkout is checked for tracked changes. No source patches or lockfile edits occur.

Node 24 matches this release's .nvmrc; a change in upstream's required Node major stops the build with a toolchain update message. npm downloads are cached in the browser-build-cache volume, while the build tree is recreated on every run. Upstream's build scripts reserve an 8 GB Node heap; allow additional memory for parallel minification workers and several GB of disk space.

Verified with browser-v2026.9.3: both production builds, ZIP integrity and checksums, OSS module checks, and unchanged bytes for all 5,887 original files in the exported build tree. A Chromium runtime smoke test reached the login form through normal worker startup and first-run onboarding. Firefox was compiled and its artifact checked, but was not tested in a running Firefox instance.

Installing and updating

(cd artifacts/browser && sha256sum -c SHA256SUMS)
mkdir -p artifacts/browser/chrome-unpacked
unzip -o artifacts/browser/bitwarden-foss-chrome.zip -d artifacts/browser/chrome-unpacked

In Chromium, open chrome://extensions, enable Developer mode, choose Load unpacked, and select that directory. Keep the same directory for updates; empty it, extract the new ZIP into that same path, and click Reload. See Chrome's local installation instructions. These artifacts do not carry store signatures or automatic store updates.

In Firefox, open about:debugging, choose This Firefox, then Load Temporary Add-on, and select the Firefox ZIP. This installation lasts until Firefox restarts. Regular Firefox requires Mozilla signing for persistent installation; the builder does not submit or sign extensions. The upstream Firefox extension ID is retained, so use a separate profile or remove the store extension before testing. See temporary installation and Firefox signing requirements. Safari packaging requires macOS and is deferred with iOS.

Every default browser build checks all GitHub release pages for the latest published stable browser-v… release, resolves its full commit SHA, and fetches it. This repository uses client-specific tag prefixes; -bwpm applies to the mobile repositories. Drafts, prereleases, and other clients' releases are excluded, and lookup failures stop the build rather than reuse a stale release.

To update, run ./build-clients --target browser again. BROWSER_REF defaults to latest; remove any old pin from the shell or .env to restore automatic updates. To pin a release, choose its tag from upstream browser releases, resolve it with git ls-remote as in the Android example (using the clients repository and browser-v… tag), and set BROWSER_REF=<full SHA> in .env or on the build command. Check the selected release and commit in sources.txt.

The production browser build exposes no default server URL override in its webpack configuration. Select the self-hosted server in the extension's login screen. Upstream also supports browser managed-storage policies; its managed-settings documentation describes the environment setting. Development-only flags do not configure a production extension. This target adds no source customization for the server URL.

All supported clients

./build-clients --target clients

Currently this builds Android, then the browser extensions. Each service has its own client profile and the shared clients profile. Use the wrapper or explicit one-shot services to build; docker compose --profile clients up also selects the existing server services.

Remaining upstream repositories:

  • Web, desktop, and CLI
  • iOS is deferred: it requires macOS/Xcode, and no Mac builder is available. A hosted macOS workflow could build an unsigned archive; installing on an iPhone also requires Apple signing and provisioning.

About

No description, website, or topics provided.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages