Installation Guide
This guide walks you through installing FIDO Bridge on both your Linux desktop and Android device.
Prerequisites
Before you begin, make sure you have:
Hardware Requirements
- Linux Machine: Any modern Linux distribution with kernel 4.4+ (for UHID support)
- Android Device: Android 7.0 (Nougat) or higher with NFC support
- YubiKey: YubiKey 5 NFC or any FIDO2-compatible NFC security key
Software Requirements
Linux Desktop
-
Rust: Version 1.90 or higher
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -
Git: For cloning the repository
sudo apt install git # Debian/Ubuntu
sudo dnf install git # Fedora -
Build Dependencies:
# Debian/Ubuntu
sudo apt install build-essential pkg-config libssl-dev
# Fedora
sudo dnf install gcc pkg-config openssl-devel
# Arch Linux
sudo pacman -S base-devel openssl
Android Device
-
Flutter SDK: Version 3.0 or higher
# Download Flutter from https://flutter.dev/docs/get-started/install
# Or use snap on Ubuntu:
sudo snap install flutter --classic -
Android SDK: Installed via Android Studio or command-line tools
flutter doctor # Check for missing dependencies
Installation Steps
Part 1: Install the Linux Client
Option 1: Download Pre-built Binary (Recommended)
The easiest way to install FIDO Bridge is to download the pre-built release binaries:
-
Download the latest release:
Visit GitHub Releases and download:
fido-bridge-linux-v*.tar.gzorfido-bridge-linux-v*- Linux client binary
Or use
wget/curl:# Get the latest version (replace v0.1.0 with actual latest version)
VERSION=v0.1.0
wget https://github.com/0xC9C3/fido-bridge/releases/download/${VERSION}/fido-bridge-linux-${VERSION}
# Or with curl:
curl -LO https://github.com/0xC9C3/fido-bridge/releases/download/${VERSION}/fido-bridge-linux-${VERSION} -
Make the binary executable:
chmod +x fido-bridge-linux-v* -
Verify the binary:
./fido-bridge-linux-v* --versionExpected output:
fido-bridge 0.1.0 -
Install using the built-in installer (Recommended):
./fido-bridge-linux-v* installSkip to the "What the installer does" section below for details.
Option 2: Build from Source
For developers or if you want to customize the build:
-
Clone the repository:
git clone https://github.com/0xC9C3/fido-bridge.git
cd fido-bridge -
Build the client in release mode:
cargo build --release --bin fido-bridgeThis will create the binary at
/path/to/fido-bridge/target/release/fido-bridge. -
Verify the build:
./target/release/fido-bridge --versionExpected output:
fido-bridge 0.1.0 -
Install using the built-in installer (Recommended):
The easiest and most secure way to install FIDO Bridge is using the built-in self-installer:
./target/release/fido-bridge installWhat the installer does (
/path/to/fido-bridge/crates/client/src/commands/install.rs):-
Creates directories:
~/.local/bin/- Binary installation location~/.config/fido-bridge/- Configuration and storage~/.config/systemd/user/- User systemd service
-
Installs the binary:
- Copies
fido-bridgeto~/.local/bin/fido-bridge - Sets executable permissions (755)
- Checks if
~/.local/binis in PATH and warns if not
- Copies
-
Creates configuration file:
- Interactive prompts for server mode (embedded/remote), port, and log level
- Creates
~/.config/fido-bridge/config.toml - Sets secure permissions (600) on config file
-
Sets up UHID permissions (requires sudo):
- Uses
setfaclto grant read/write access to/dev/uhidfor your user only (secure) - Installs udev rule at
/etc/udev/rules.d/99-fido-bridge.rulesfor persistence across reboots - Automatically reloads udev rules
- Uses
-
Installs systemd service:
- Creates
~/.config/systemd/user/fido-bridge.servicewith security hardening - Reloads systemd daemon
- Enables and starts the service
- Verifies service is running
- Creates
-
Verifies installation:
- Checks service is active with
systemctl --user is-active fido-bridge - Provides troubleshooting guidance if service fails to start
- Checks service is active with
Interactive options:
- Server mode: embedded (local server) or remote
- Port number: default 3000 for embedded mode
- Log level: debug, info, warn, or error
Non-interactive mode:
./target/release/fido-bridge install --non-interactiveUses defaults: embedded mode on port 3000 with info logging.
Manual installation (not recommended):
If you prefer manual installation or the installer doesn't work:
# Copy binary
mkdir -p ~/.local/bin
cp target/release/fido-bridge ~/.local/bin/fido-bridge
chmod +x ~/.local/bin/fido-bridge
# Create config directory
mkdir -p ~/.config/fido-bridge
# Set up UHID access (one of these methods):
sudo setfacl -m u:$USER:rw /dev/uhid # Temporary, lost on reboot
# OR
sudo usermod -a -G input $USER # Persistent, requires logout
# Create systemd service (see "Running as a Service" section below) -
Part 2: Install the Android App
Option 1: Download Pre-built APK (Recommended)
-
Download the latest APK:
Visit GitHub Releases and download:
fido-bridge-android-v*.apk
Or download directly to your Android device via browser.
-
Install the APK:
On Android device:
- Open the downloaded APK file
- Enable "Install from unknown sources" if prompted
- Tap "Install"
Via adb (if device is connected to computer):
adb install fido-bridge-android-v*.apk -
Grant NFC permissions:
- Open the FIDO Bridge app
- Grant NFC access when prompted
- Enable notification permissions (for transaction alerts)
Option 2: Build from Source
For developers or if you want to customize the app:
-
Navigate to the app directory:
cd /path/to/fido-bridge/app -
Install Flutter dependencies:
flutter pub get -
Ensure Android device is connected (or emulator is running):
flutter devicesYou should see your Android device listed.
-
Build the APK:
For testing (debug build):
flutter build apk --debugFor production (release build):
flutter build apk --releaseThe APK will be created at:
- Debug:
app/build/app/outputs/flutter-apk/app-debug.apk - Release:
app/build/app/outputs/flutter-apk/app-release.apk
- Debug:
-
Install the app on your Android device:
Via USB (if device is connected):
flutter installManual installation:
- Transfer the APK to your phone
- Enable "Install from unknown sources" in Android settings
- Tap the APK file to install
-
Grant NFC permissions:
- Open the FIDO Bridge app
- Grant NFC access when prompted
- Enable notification permissions (for transaction alerts)
Part 3: Set Up the Relay Server
You have three options for the relay server:
Option A: Use Embedded Server (Recommended for Testing / not wanting to manage the server)
The Linux client can run its own embedded server:
-
Edit configuration (create
~/.config/fido-bridge/config.toml):[server]
mode = "embedded"
port = 3000 -
The client will automatically start the server when launched.
Option B: Deploy with Docker (Recommended for Production)
The easiest way to deploy a standalone server is using the official Docker image:
-
Using Docker directly:
docker run -d \
--name fido-bridge-server \
-p 8080:8080 \
-e FIDO_BRIDGE_LOG_LEVEL=info \
ghcr.io/0xc9c3/fido-bridge-server:latest -
Using Docker Compose (recommended):
Create a
docker-compose.ymlfile:services:
fido-bridge-server:
image: ghcr.io/0xc9c3/fido-bridge-server:latest
container_name: fido-bridge-server
ports:
- "8080:8080"
environment:
FIDO_BRIDGE_ADDR: 0.0.0.0:8080
FIDO_BRIDGE_LOG_LEVEL: info
FIDO_BRIDGE_LOG_FORMAT: pretty
FIDO_BRIDGE_SESSION_TIMEOUT_SECS: 300
FIDO_BRIDGE_ENABLE_CORS: "true"
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 30s
timeout: 3s
retries: 3Start the server:
docker compose up -dView logs:
docker compose logs -f -
Available Docker images:
ghcr.io/0xc9c3/fido-bridge-server:latest- Latest stable releaseghcr.io/0xc9c3/fido-bridge-server:v0.1.0- Specific versionghcr.io/0xc9c3/fido-bridge-server:1- Major version tag
-
Environment variables (see Dockerfile for all options):
FIDO_BRIDGE_ADDR- Bind address (default:0.0.0.0:8080)FIDO_BRIDGE_LOG_LEVEL- Log level: trace, debug, info, warn, errorFIDO_BRIDGE_LOG_FORMAT- Log format: json, pretty, compactFIDO_BRIDGE_SESSION_TIMEOUT_SECS- Session timeout in seconds (default: 300)FIDO_BRIDGE_ENABLE_CORS- Enable CORS (default: true)
-
(Production) Use a reverse proxy:
Example Nginx configuration:
server {
listen 443 ssl http2;
server_name relay.fido-bridge.example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
} -
Configure the client to use remote server (
~/.config/fido-bridge/config.toml):[server]
mode = "remote"
url = "https://your-server.example.com" -
Update Android app server URL:
Edit
app/lib/src/config/app_config.dart:static const String serverUrl = 'https://your-server.example.com';Rebuild the Android app after changing the server URL.
Option C: Build and Deploy Server from Source
For advanced users who want to build from source:
-
Build the server:
cd /path/to/fido-bridge
cargo build --release --bin fido-bridge-serverOr download the pre-built binary from GitHub Releases:
VERSION=v0.1.0
wget https://github.com/0xC9C3/fido-bridge/releases/download/${VERSION}/fido-bridge-server-linux-${VERSION}
chmod +x fido-bridge-server-linux-${VERSION} -
Run the server:
# From source build:
./target/release/fido-bridge-server
# Or from downloaded binary:
./fido-bridge-server-linux-v* -
Configure the client and app (same as Option B steps 6-7 above)
Part 4: Verify Installation
-
Start the Linux client:
# If installed with the installer (recommended)
systemctl --user start fido-bridge
# Or run directly (requires /dev/uhid access)
./target/release/fido-bridge daemonNote: Direct execution requires read/write access to
/dev/uhid. Thefido-bridge installcommand automatically sets up secure ACL permissions sosudois NOT needed. If you haven't run the installer, you'll need to either:- Run
fido-bridge install(recommended - sets up persistent ACL via udev rules) - Manually grant access:
sudo setfacl -m u:$USER:rw /dev/uhid - Run with
sudo(not recommended for security reasons)
Expected output:
[INFO] FIDO Bridge Client starting...
[INFO] Created UHID device at /dev/hidraw3
[INFO] Embedded server listening on http://0.0.0.0:3000
[INFO] Waiting for pairing requests... - Run
-
Check that UHID device was created:
ls -l /dev/hidraw*You should see a new
/dev/hidrawXdevice with recent timestamp. -
Open the Android app:
- Launch "FIDO Bridge" from your app drawer
- You should see the home screen with "No paired devices"
-
Proceed to pairing (see Pairing Guide)
Configuration Options
Linux Client Configuration
Location: ~/.config/fido-bridge/config.toml
[server]
# Server mode: "embedded" or "remote"
mode = "embedded"
# Port for embedded server (only used if mode = "embedded")
port = 3000
# URL for remote server (only used if mode = "remote")
url = "https://relay.fido-bridge.example.com"
[logging]
# Log level: "trace", "debug", "info", "warn", "error"
level = "info"
# Log to file in addition to stdout
file = "/var/log/fido-bridge/client.log"
[timeouts]
# Transaction timeout in seconds (default: 240)
transaction_timeout = 240
# ClientPIN timeout in seconds (default: 30)
clientpin_timeout = 30
# Message polling interval in milliseconds (default: 250)
poll_interval_ms = 250
Android App Configuration
Server URL: Edit app/lib/src/config/app_config.dart before building.
Polling Intervals: Configured in app/lib/src/services/background_service.dart:
const activePollInterval = Duration(milliseconds: 250);
const backgroundPollInterval = Duration(seconds: 5);
Running as a Service
Linux systemd Service
Recommended: Use the built-in installer
The easiest way to set up FIDO Bridge as a service is using the built-in installer:
./target/release/fido-bridge install
This automatically:
- Creates the systemd user service
- Sets up UHID permissions
- Enables the service to start on login
Manual Setup (if not using the installer):
-
Create service file (
~/.config/systemd/user/fido-bridge.service):[Unit]
Description=FIDO Bridge Service - Secure FIDO device pairing daemon
Documentation=https://github.com/0xc9c3/fido-bridge
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/home/username/.local/bin/fido-bridge daemon
Restart=on-failure
RestartSec=5s
# Environment
Environment="RUST_LOG=warn,fido_bridge=info"
# Security hardening
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=read-only
ReadWritePaths=%h/.config/fido-bridge
# Resource limits
LimitNOFILE=65536
[Install]
WantedBy=default.targetNote: Replace
/home/username/.local/bin/fido-bridgewith the actual path to your binary, or use the full path like%h/.local/bin/fido-bridgewhere%hexpands to your home directory. -
Enable and start the service:
systemctl --user daemon-reload
systemctl --user enable fido-bridge
systemctl --user start fido-bridge -
Check status:
systemctl --user status fido-bridge
# Or use the built-in command:
fido-bridge status
Android Background Service
The Android app automatically runs a background service for message polling:
- Service starts when app is launched
- Continues running even when app is closed
- Shows persistent notification (required for foreground service)
- Can be disabled in app settings if desired
Uninstallation
Linux Client
Using the built-in uninstaller (Recommended):
# Uninstall service and binary, keep configuration
fido-bridge uninstall
# Uninstall everything including configuration
fido-bridge uninstall --remove-config
# Skip confirmation prompt
fido-bridge uninstall --force
Source: /path/to/fido-bridge/crates/client/src/commands/uninstall.rs
What it does:
- Stops and disables the systemd service (
systemctl --user stop/disable fido-bridge) - Removes service file from
~/.config/systemd/user/fido-bridge.service - Reloads systemd daemon
- Removes binary from
~/.local/bin/fido-bridge - Optionally removes configuration directory
~/.config/fido-bridge/(with--remove-config)
What it does NOT remove (manual cleanup required):
- Udev rules at
/etc/udev/rules.d/99-fido-bridge.rules - Group membership (if manually added to
plugdevorinputgroups) - ACL permissions on
/dev/uhid(will reset on reboot)
To remove udev rules manually:
sudo rm /etc/udev/rules.d/99-fido-bridge.rules
sudo udevadm control --reload-rules
sudo udevadm trigger
To remove group membership (if manually added):
sudo gpasswd -d $USER plugdev
sudo gpasswd -d $USER input
Manual Uninstallation (if uninstall command is not available):
-
Stop the service (if running):
systemctl --user stop fido-bridge
systemctl --user disable fido-bridge -
Remove service file:
rm ~/.config/systemd/user/fido-bridge.service
systemctl --user daemon-reload -
Remove binary:
rm ~/.local/bin/fido-bridge -
Remove configuration and data:
rm -rf ~/.config/fido-bridge
Android App
-
Uninstall via Android settings:
- Settings → Apps → FIDO Bridge → Uninstall
-
Or via adb:
adb uninstall com.example.fido_bridge
Troubleshooting Installation
Linux Client Won't Start
Error: Permission denied (os error 13)
Solution: Run with sudo or add your user to the input group:
sudo usermod -a -G input $USER
# Log out and back in for group change to take effect
Error: error while loading shared libraries: libssl.so.3
Solution: Install OpenSSL 3:
sudo apt install libssl3 # Debian/Ubuntu
sudo dnf install openssl-libs # Fedora
Error: UHID device creation failed
Solution: Verify kernel supports UHID:
lsmod | grep uhid
# If empty, try loading the module:
sudo modprobe uhid
Android App Build Failures
Error: Android SDK not found
Solution: Install Android SDK via Android Studio or run:
flutter doctor --android-licenses
Error: Gradle build failed
Solution: Update Gradle wrapper:
cd app/android
./gradlew wrapper --gradle-version 8.0
Error: Flutter version mismatch
Solution: Update Flutter:
flutter upgrade
flutter clean
flutter pub get
Server Connection Issues
Error: Android app shows "Connection failed"
Solution:
- Verify server is running:
curl http://localhost:3000/health - Check firewall allows port 3000
- Verify Android app server URL matches actual server address
- Check server logs for errors
Error: "SSL certificate verification failed"
Solution:
- Use HTTPS with valid TLS certificate (not self-signed)
- Or disable certificate verification (development only):
// In app/lib/src/services/api_client.dart
HttpClient()..badCertificateCallback = (cert, host, port) => true;
Next Steps
- Pairing Guide - Pair your Linux desktop with Android device
- Troubleshooting - Common issues and solutions
- Building from Source - Development workflow