Skip to content

Add 1Password Encrypted Vault Backup App #97

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Jun 4, 2025
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions onepassword_sdks/demo-vault-backup-webapp/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Use Node.js 18 as the base image for the container
FROM node:lts-bookworm-slim

# Set the working directory to /app inside the container
WORKDIR /webapp

# Install required tools and configure the 1Password CLI repository
RUN apt-get update && \
apt-get install -y \
curl \
gnupg \
ca-certificates \
lsb-release && \
curl -sS https://downloads.1password.com/linux/keys/1password.asc | \
gpg --dearmor --output /usr/share/keyrings/1password-archive-keyring.gpg && \
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/1password-archive-keyring.gpg] https://downloads.1password.com/linux/debian/$(dpkg --print-architecture) stable main" | \
tee /etc/apt/sources.list.d/1password.list && \
mkdir -p /etc/debsig/policies/AC2D62742012EA22/ && \
curl -sS https://downloads.1password.com/linux/debian/debsig/1password.pol | \
tee /etc/debsig/policies/AC2D62742012EA22/1password.pol && \
mkdir -p /usr/share/debsig/keyrings/AC2D62742012EA22 && \
curl -sS https://downloads.1password.com/linux/keys/1password.asc | \
gpg --dearmor --output /usr/share/debsig/keyrings/AC2D62742012EA22/debsig.gpg && \
apt-get update && \
apt-get install -y 1password-cli

# Check the installed version of 1Password CLI to ensure it’s working
RUN op --version

# Copy package.json and package-lock.json (if present) to the working directory
COPY package*.json ./

# Install Node.js dependencies defined in package.json
RUN npm install

# Copy all remaining application files to the container
COPY . .

# Set permissions: 755 for directories, 644 for files
RUN chown -R node:node /webapp && \
find /webapp -type d -exec chmod 755 {} \; && \
find /webapp -type f -exec chmod 644 {} \;

# Switch to non-root user
USER node

# Expose port 3002 for the application to listen on
EXPOSE 3002

# Define the command to start the Node.js application
CMD ["npm", "start"]
75 changes: 75 additions & 0 deletions onepassword_sdks/demo-vault-backup-webapp/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# 1Password Encrypted Vault Backup App

This web app enables secure backup and restoration of 1Password vaults, encrypting the backup with a user-provided passcode and storing sensitive keys in a dedicated 1Password vault. It uses the 1Password JS SDK and CLI for vault operations, with encryption handled via Argon2 and AES-256-CBC.

## Overview

This app allows you to:
- Connect to a 1Password account using a service account token.
- List and select vaults for backup.
- Encrypt and save vault data to a downloadable file.
- Store encryption keys in a secure 1Password vault.
- Restore vaults from an encrypted backup file to a destination account.

## Requirements

- [Docker](https://docs.docker.com/get-started/get-docker/)
- [1Password Service Account](https://developer.1password.com/docs/service-accounts/get-started) with:
- Read access for listing vaults and items (backup).
- Vault creation and item creation permissions (restore).

## Installation

1. [Install Docker](https://docs.docker.com/get-started/get-docker/).
2. Clone or download this project.
3. Navigate to the project folder and run:

```
docker compose up -d
```

## Usage

### Backup
1. Open `https://localhost:3002` in your browser.
2. Click **Backup** in the sidebar.
3. Enter your 1Password service account token and click **Connect**.
4. Select vaults to back up and provide a passcode (minimum 8 characters).
5. Click **Backup Selected Vaults** or **Backup All Vaults**.
6. Save the generated encryption keys to a new 1Password vault or download them.
7. Download the encrypted `backup.1pbackup` file.

### Restore
1. Open `https://localhost:3002` and click **Restore**.
2. Upload the `backup.1pbackup` file and enter the service account token, passcode, and system key.
3. Select vaults to restore from the backup.
4. Click **Restore Selected Vaults**.
5. Verify the restored vaults in the destination account.

## Special Handling with CLI

- **Vault Creation**: Uses 1Password CLI (`op vault create`) to create new vaults for restored data and key storage, as vault creation is not supported by the SDK.

## Security Features

- Runs on HTTPS with a self-signed certificate (local testing).
- Uses Argon2 for key derivation and AES-256-CBC for backup encryption.
- Verifies backup integrity with HMAC-SHA256.
- Saves encryption keys (passcode and system key) in a secure 1Password vault.
- Uses `p-limit` to prevent overwhelming the 1Password API.
- Implements retry logic for API rate limits or conflicts.

## Troubleshooting

- Ensure Docker is running and the container is active (`docker logs <container-name>`).
- Verify service account token permissions (read for backup, create for restore/keys).
- Check `https://localhost:3002` is accessible; accept the self-signed certificate if prompted.
- Confirm passcode and system key match the backup file during restoration.
- Ensure the backup file is not corrupted or tampered with (HMAC verification failure).

## Limitations

- Passkeys cannot be backed up or restored (use 1Password desktop/mobile apps).
- SDK does not support archived items for backup/restore.
- Restored vault names are appended with "(Restored)".
- Fixed concurrency limits (2 vaults, 1 item at a time) may need tuning for large backups.
11 changes: 11 additions & 0 deletions onepassword_sdks/demo-vault-backup-webapp/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
services:
app:
build:
context: .
dockerfile: Dockerfile
image: demo-vault-backup-webapp:v1.0.0
ports:
- "3002:3002"
environment:
- NODE_ENV=development
command: npm start
24 changes: 24 additions & 0 deletions onepassword_sdks/demo-vault-backup-webapp/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "demo-vault-backup-webapp",
"version": "1.0.0",
"main": "webapp.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node webapp.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": "",
"dependencies": {
"@1password/sdk": "^0.3.0",
"argon2": "^0.41.1",
"body-parser": "^2.2.0",
"ejs": "^3.1.10",
"express": "^4.21.2",
"express-session": "^1.18.1",
"multer": "^1.4.5-lts.2",
"p-limit": "^4.0.0",
"selfsigned": "^2.4.1"
}
}
Empty file.
Empty file.
Loading