Skip to content
Return to Projects
Case Study

FrostVault

A zero-knowledge Windows password manager with deception built in.

The Problem

Mainstream password managers are cloud-first and ask you to trust a third party with your most sensitive secrets. FrostVault keeps everything local and encrypted — and fights back when someone tries to break in.

My Role

Built solo with AI-assisted development — cryptographic design, application logic, the PySide6 UI, and Windows packaging.

Highlights

  • AES-256-GCM authenticated encryption for all vault data at rest
  • Honey Vault serves believable decoy credentials under a wrong master key or duress
  • Freeze Mode and Ice Crystal Fingerprints provide tamper detection
  • Ships as a single standalone Windows executable — no installer, no cloud

Stack

Python 3.12PySide6AES-256-GCMCryptographyPyInstaller

Constraints

  • Offline-first: vault data must never leave the user's machine.
  • Single-binary distribution — no installer, no runtime to ship.
  • Threat model includes coerced access, not just remote attackers.

System Architecture

Interface
PySide6 Desktop UI
Application
Vault Manager
Honey Vault
Freeze Mode
Cryptography
AES-256-GCM
Key Derivation
Ice Crystal Fingerprints
Storage
Encrypted local vault file

Key Trade-offs

The decisions worth defending — what I chose, what I turned down, and why.

Storage architecture

Chose

Single encrypted local file

Rejected

Cloud-synced vault

Removes the third-party trust dependency entirely; matches the offline-first threat model at the cost of cross-device sync.

Wrong-password behaviour

Chose

Honey Vault returns plausible decoys

Rejected

Hard fail with a clear error

A loud failure tells an attacker they have the wrong key. A believable decoy buys time and frustrates duress scenarios.

Crypto stack

Chose

AES-256-GCM via the `cryptography` library

Rejected

Custom-built primitives

Authenticated encryption out of the box, audited implementation, zero novel crypto risk.

What I'd Do Differently

An honest retrospective — the stuff I'd change with more time, more users, or a second pass.

  1. 1Add an automated integrity self-test that runs on every launch and surfaces tampering visibly to the user.
  2. 2Move key derivation parameters to a versioned header so future Argon2 tuning doesn't break old vaults.
  3. 3Ship a portable Linux build — Windows-only narrows the audience more than I expected.

Technical Deep-Dive

Architecture, specifications, and implementation details.

Build & Deployment

FrostVault v1.0.0 — IceLegends


#1. Build Environment

RequirementValue
OSWindows 10 / 11 x64
Python3.12.x
Package manageruv (%USERPROFILE%\.local\bin\uv.exe)
Build toolPyInstaller ≥6.0
Installer toolInno Setup 6 (%LOCALAPPDATA%\Programs\Inno Setup 6\ISCC.exe)
Virtual environment.venv\ (project root)

#2. Dependencies

# requirements.txt
PySide6>=6.7.0
cryptography>=42.0.0
argon2-cffi>=23.1.0
zxcvbn>=4.4.28
Pillow>=10.0.0
keyboard>=0.13.5
pyperclip>=1.8.0
PyInstaller>=6.0.0

Install:

uv pip install --python .venv\Scripts\python.exe -r requirements.txt

#3. PyInstaller Build

##3.1 Command

cd D:\Proiecte\Frost_Vault\FrostVault_v1

.\.venv\Scripts\python.exe -m PyInstaller `
    --noconfirm `
    --onedir `
    --windowed `
    --name "FrostVault" `
    --icon "assets\icons\frostvault.ico" `
    --add-data "assets;assets" `
    --paths "." `
    main.py

##3.2 Flags Explained

FlagPurpose
--onedirOutput a folder (faster startup than --onefile)
--windowedNo console window (Windows GUI app)
--add-data "assets;assets"Bundle assets folder into the executable
--paths "."Add project root to module search path

##3.3 Output Structure

dist/
└── FrostVault/
    ├── FrostVault.exe          ← Main executable
    ├── assets/                 ← Bundled assets (icons, etc.)
    └── _internal/
        ├── PySide6/            ← Qt6 DLLs
        ├── cryptography/
        ├── argon2_cffi_bindings/
        └── *.pyd / *.dll       ← Python extension modules

##3.4 Spec File

PyInstaller generates FrostVault.spec in the project root. This file can be used for reproducible builds:

.\.venv\Scripts\python.exe -m PyInstaller --noconfirm FrostVault.spec

#4. Inno Setup Installer

##4.1 Command

& "C:\Users\Matei\AppData\Local\Programs\Inno Setup 6\ISCC.exe" `
    "D:\Proiecte\Frost_Vault\FrostVault_v1\installer\frostvault_setup.iss"

##4.2 Installer Configuration

SettingValue
App ID{8F3C2A1D-4B7E-4F9A-B2C6-1D3E5F7A9B0C}
Install location%LOCALAPPDATA%\IceLegends\FrostVault\
PrivilegesUser-level only (no UAC prompt)
CompressionLZMA2/Ultra64 with solid compression
Outputdist\installer\FrostVault_Setup_v1.0.0.exe
Wizard styleModern

##4.3 Installer Features

  • Desktop shortcut (optional, user-selectable)
  • Start Menu entry under IceLegends\FrostVault
  • Clean uninstaller (via Add/Remove Programs, HKCU)
  • Post-install "Launch FrostVault now" option
  • Custom welcome/finish page text with security feature summary
  • Registry key: HKCU\Software\IceLegends\FrostVault\InstallPath

##4.4 Vault Data Preservation

The vault database (%APPDATA%\FrostVault\vault.db) is stored outside the install directory. Uninstalling FrostVault does NOT delete the vault. The uninstall script includes a commented-out [UninstallDelete] entry that can be enabled if desired.


#5. Output Sizes (v1.0.0)

ArtifactSize
dist\FrostVault\ (directory)~150 MB
FrostVault_Setup_v1.0.0.exe~37 MB
Installed size~150 MB
vault.db (empty vault)~20 KB

#6. Full Rebuild Pipeline

# Step 1 — Clean
Remove-Item -Recurse -Force dist, build -ErrorAction SilentlyContinue

# Step 2 — Regenerate icon (if needed)
.\.venv\Scripts\python.exe scripts\generate_icon.py

# Step 3 — PyInstaller
.\.venv\Scripts\python.exe -m PyInstaller --noconfirm --onedir --windowed `
    --name "FrostVault" --icon "assets\icons\frostvault.ico" `
    --add-data "assets;assets" --paths "." main.py

# Step 4 — Inno Setup
New-Item -ItemType Directory -Force -Path "dist\installer" | Out-Null
& "C:\Users\Matei\AppData\Local\Programs\Inno Setup 6\ISCC.exe" `
    "installer\frostvault_setup.iss"

# Step 5 — Output
Write-Host "Installer: dist\installer\FrostVault_Setup_v1.0.0.exe"

#7. Version Bump Checklist

When releasing a new version:

  • Update #define AppVersion in installer\frostvault_setup.iss
  • Update version string in main.py window title
  • Update AppId in .iss only if breaking schema changes (forces clean install)
  • Run full rebuild pipeline (Step 1–5 above)
  • Test installer on a clean Windows VM
  • Verify vault.db from previous version is still readable after upgrade
~ End of Document ~