From 89bcc42eff09ff7f8a597f32d98370728e979ecc Mon Sep 17 00:00:00 2001 From: Giuseppe Imperato Date: Thu, 4 Jun 2026 01:24:20 +0200 Subject: [PATCH 1/2] ci(release): download Windows App Runtime redistributable before Inno Setup The release workflow failed on every tag at "Build installer and portable ZIP": Installer/PassKey.iss bundles WindowsAppRuntimeInstall-x64.exe as a [Files] Source, but that binary is git-ignored (too large to commit) and CI never fetched it, so Inno Setup aborted with "Source file ... does not exist" on a fresh runner. Local builds worked only because the file existed on the dev box. build-installer.ps1 now ensures the redistributable is present before invoking Inno Setup, downloading it via Installer/Download-Runtime.ps1 (authoritative aka.ms URL pinned to WindowsAppSDK 1.8.260416003) when missing. Also make make-chrome-zip.ps1 / make-xpi.ps1 read the version from manifest.json instead of hardcoding "1.0.0", so the package filename matches the extension. Co-Authored-By: Claude Opus 4.8 --- make-chrome-zip.ps1 | 47 +++++++++++++++++++++++++++++++++++++ make-xpi.ps1 | 33 ++++++++++++++++++++++++++ scripts/build-installer.ps1 | 14 +++++++++++ 3 files changed, 94 insertions(+) create mode 100644 make-chrome-zip.ps1 create mode 100644 make-xpi.ps1 diff --git a/make-chrome-zip.ps1 b/make-chrome-zip.ps1 new file mode 100644 index 0000000..c7ac5fe --- /dev/null +++ b/make-chrome-zip.ps1 @@ -0,0 +1,47 @@ +Add-Type -AssemblyName System.IO.Compression +Add-Type -AssemblyName System.IO.Compression.FileSystem + +$src = 'A:\Progetti\00 PassKey\PK4\extensions\chrome' + +# Read the version from the manifest so the package name always matches the extension. +$version = (Get-Content (Join-Path $src 'manifest.json') -Raw | ConvertFrom-Json).version +$dest = "A:\Progetti\00 PassKey\PK4\passkey-chrome-$version.zip" + +if (Test-Path $dest) { Remove-Item $dest -Force } + +$stream = [System.IO.File]::Open($dest, [System.IO.FileMode]::Create) +$zip = [System.IO.Compression.ZipArchive]::new($stream, [System.IO.Compression.ZipArchiveMode]::Create) + +Get-ChildItem -Path $src -Recurse -File | ForEach-Object { + $relative = $_.FullName.Substring($src.Length + 1).Replace('\', '/') + + if ($relative -eq 'manifest.json') { + # Strip the "key" field — Chrome Web Store rejects manifests that contain it + $json = Get-Content $_.FullName -Raw | ConvertFrom-Json + $json.PSObject.Properties.Remove('key') + $content = ($json | ConvertTo-Json -Depth 10) + $bytes = [System.Text.Encoding]::UTF8.GetBytes($content) + $entry = $zip.CreateEntry($relative) + $writer = $entry.Open() + $writer.Write($bytes, 0, $bytes.Length) + $writer.Dispose() + Write-Host " Added: $relative (key field stripped)" + } else { + [System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($zip, $_.FullName, $relative) | Out-Null + Write-Host " Added: $relative" + } +} + +$zip.Dispose() +$stream.Dispose() + +# Verify +$zip2 = [System.IO.Compression.ZipFile]::OpenRead($dest) +$entries = $zip2.Entries | ForEach-Object { $_.FullName } | Sort-Object +$zip2.Dispose() + +Write-Host "" +Write-Host "ZIP contents:" -ForegroundColor Cyan +$entries | ForEach-Object { Write-Host " $_" } +Write-Host "" +Write-Host ("Done! Size: " + [math]::Round((Get-Item $dest).Length / 1KB, 1) + " KB") -ForegroundColor Green diff --git a/make-xpi.ps1 b/make-xpi.ps1 new file mode 100644 index 0000000..3ed0932 --- /dev/null +++ b/make-xpi.ps1 @@ -0,0 +1,33 @@ +Add-Type -AssemblyName System.IO.Compression +Add-Type -AssemblyName System.IO.Compression.FileSystem + +$src = 'A:\Progetti\00 PassKey\PK4\extensions\firefox' + +# Read the version from the manifest so the package name always matches the extension. +$version = (Get-Content (Join-Path $src 'manifest.json') -Raw | ConvertFrom-Json).version +$dest = "A:\Progetti\00 PassKey\PK4\passkey-firefox-$version.xpi" + +if (Test-Path $dest) { Remove-Item $dest -Force } + +$stream = [System.IO.File]::Open($dest, [System.IO.FileMode]::Create) +$zip = [System.IO.Compression.ZipArchive]::new($stream, [System.IO.Compression.ZipArchiveMode]::Create) + +Get-ChildItem -Path $src -Recurse -File | ForEach-Object { + $relative = $_.FullName.Substring($src.Length + 1).Replace('\', '/') + [System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($zip, $_.FullName, $relative) | Out-Null + Write-Host " Added: $relative" +} + +$zip.Dispose() +$stream.Dispose() + +# Verify +$zip2 = [System.IO.Compression.ZipFile]::OpenRead($dest) +$entries = $zip2.Entries | ForEach-Object { $_.FullName } | Sort-Object +$zip2.Dispose() + +Write-Host "" +Write-Host "XPI contents:" -ForegroundColor Cyan +$entries | ForEach-Object { Write-Host " $_" } +Write-Host "" +Write-Host ("Done! Size: " + [math]::Round((Get-Item $dest).Length / 1KB, 1) + " KB") -ForegroundColor Green diff --git a/scripts/build-installer.ps1 b/scripts/build-installer.ps1 index f2b4073..192028d 100644 --- a/scripts/build-installer.ps1 +++ b/scripts/build-installer.ps1 @@ -95,6 +95,20 @@ $firefoxManifest = @{ $chromeManifest | Out-File -Encoding utf8 -FilePath (Join-Path $publishPath "com.passkey.host.json") $firefoxManifest | Out-File -Encoding utf8 -FilePath (Join-Path $publishPath "com.passkey.host.firefox.json") +# 3.5 Ensure the Windows App Runtime redistributable is present. +# Installer\PassKey.iss bundles WindowsAppRuntimeInstall-x64.exe as a [Files] Source, +# but that binary is git-ignored (too large to commit). On a fresh CI runner it is +# missing, so download it here before invoking Inno Setup. Download-Runtime.ps1 holds +# the authoritative aka.ms URL pinned to the WindowsAppSDK package version. +$runtimeExe = Join-Path $RepoRoot "Installer\WindowsAppRuntimeInstall-x64.exe" +if (-not (Test-Path $runtimeExe)) { + Write-Host "Windows App Runtime redistributable missing — downloading..." -ForegroundColor Green + & (Join-Path $RepoRoot "Installer\Download-Runtime.ps1") + if (-not (Test-Path $runtimeExe)) { throw "Failed to obtain WindowsAppRuntimeInstall-x64.exe" } +} else { + Write-Host "Windows App Runtime redistributable already present." -ForegroundColor Green +} + # 4. Compile Inno Setup installer if (Test-Path $InnoSetupPath) { Write-Host "Compiling Inno Setup installer..." -ForegroundColor Green From de37c42394d92463e77a777d40b8178a6d17c927 Mon Sep 17 00:00:00 2001 From: Giuseppe Imperato Date: Thu, 4 Jun 2026 01:32:56 +0200 Subject: [PATCH 2/2] fix(landing): bump version references to v2.0.0 index.html still pointed to v1.0.17 in 10 places (download CTA, nav/hero/ extension links, JSON-LD downloadUrl + softwareVersion, direct Portable ZIP link). Update all to v2.0.0 to match the published release. Co-Authored-By: Claude Opus 4.8 --- landing/index.html | 1741 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1741 insertions(+) create mode 100644 landing/index.html diff --git a/landing/index.html b/landing/index.html new file mode 100644 index 0000000..b1253b9 --- /dev/null +++ b/landing/index.html @@ -0,0 +1,1741 @@ + + + + + + + + PassKey — Free Local Password Manager for Windows | Open Source + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+
v2.0.0  ·  Open Source  ·  GPL v3
+ +

+ Your passwords,
locked locally. +

+ +

+ AES-256-GCM encrypted vault. No cloud, no account, no subscription. + Your data never leaves your computer. +

+ + + +

+ Windows 10 version 1809+  ·  x64  ·  No .NET required +

+
+ + + + +
+
+
+ + + +
+
+ +
+ +

Built for security.
Designed for simplicity.

+

+ Every feature is designed around a single principle: your data belongs to you and only you. +

+
+ +
+ + +
+ lock +

AES-256-GCM Encryption

+

+ Every entry is encrypted with AES-256-GCM using a unique per-blob nonce. + Key derivation with Argon2id (64 MB · 3 iterations · 4 threads) and + PBKDF2-SHA256 (600 000 iterations) for backward compatibility. +

+
+ Encrypted Vault +
+
+ + +
+ wifi_off +

Fully Local

+

+ No cloud sync. No telemetry. No analytics. No network requests of any kind. + PassKey is 100% offline-first — your vault never leaves your device. +

+
+ + +
+ code +

Open Source

+

+ GPL v3 licensed. The full source code is on GitHub — readable, auditable and forkable by anyone. +

+
+ + +
+ extension +

Browser Extension

+

+ One-click autofill for Chrome, Firefox and Edge. Communicates with the desktop app via native messaging — no data leaves your machine. +

+
+ + +
+ translate +

6 Languages

+

+ Available in Italian, English, French, German, Spanish and Portuguese — with full UI localisation across every screen. +

+
+ + +
+
+ upload_file +

Import & Backup

+

+ Migrate from other managers or create encrypted backups in the PassKey format (.pkbak), secured with Argon2id-AES-GCM. +

+
+
+ Bitwarden JSON + 1Password .1pux + CSV + .pkbak +
+
+ +
+
+
+ + + +
+
+ +
+ +

Three steps to safer passwords

+

Up and running in minutes, no account required.

+
+ +
+ +
+
+
1
+
+ download +
+
+
+

Install Desktop

+

+ Download the installer from + GitHub Releases. + Self-contained, no .NET runtime required. Runs on Windows 10 1809+ x64. +

+
+
+ + + +
+
+
2
+
+ extension +
+
+
+

Install Extension

+

+ Add PassKey to + Chrome + or + Firefox + from the official stores. Works with Chrome, Edge and Firefox. +

+
+
+ + + +
+
+
3
+
+ key +
+
+
+

Autofill & go

+

+ Open the extension popup, unlock your vault, and autofill credentials with a single click — without ever leaving your browser tab. +

+
+
+ +
+
+
+ + + +
+
+
+ + +
+ +

Pairs with your browser

+ +
    +
  • + check_circle + One-click autofill from the extension popup +
  • +
  • + check_circle + Unlock vault directly in browser — never leave your tab +
  • +
  • + check_circle + Works with React, Angular and Vue virtual DOM +
  • +
  • + check_circle + Multi-step login forms (email-only first step) +
  • +
  • + check_circle + ECDH P-256 + AES-256-GCM session encryption +
  • +
+ + +
+ + +
+ +
+
3
+
Browsers supported
Chrome · Firefox · Edge
+
+ +
+
6
+
Languages
IT · EN · FR · DE · ES · PT
+
+ +
+
0
+
Cloud calls
Pure local IPC
+
+ +
+
GPL v3
+
Open source
Fully auditable
+
+ +
+ +
+
+
+ + + +
+
+ +
+ +

Frequently asked questions

+

Everything you need to know before downloading.

+
+ +
+ +
+ Does PassKey store passwords in the cloud? +

No. PassKey is fully offline. Your vault is stored locally on your Windows device and is never transmitted to any server. There is no cloud sync, no telemetry, and no network requests of any kind.

+
+ +
+ What encryption does PassKey use? +

Every vault entry is encrypted with AES-256-GCM using a unique per-blob nonce. The master password is never stored — it derives the encryption key via Argon2id (64 MB, 3 iterations, 4 threads). PBKDF2-SHA256 (600,000 iterations) is supported for backward compatibility.

+
+ +
+ Is PassKey free? +

Yes. PassKey is completely free and open-source under the GNU General Public License v3 (GPL v3). There are no subscriptions, no premium tiers, and no in-app purchases — ever.

+
+ +
+ Which browsers does the extension support? +

The PassKey extension supports Google Chrome, Mozilla Firefox, and Microsoft Edge. It communicates with the desktop app via native messaging — no credentials are sent over the network.

+
+ +
+ What are the system requirements? +

PassKey requires Windows 10 version 1809 (build 17763) or later, 64-bit. The installer is self-contained — no .NET runtime or additional dependencies are required.

+
+ +
+ Can I import from other password managers? +

Yes. PassKey supports importing from Bitwarden (JSON), 1Password (.1pux), and generic CSV files. You can also create and restore encrypted backups in PassKey's own .pkbak format.

+
+ +
+ Is PassKey open source? +

Yes. PassKey is fully open-source under GPL v3. The complete source code is publicly available on GitHub and can be audited, forked, or contributed to by anyone.

+
+ +
+ Does PassKey sync between multiple devices? +

PassKey does not sync automatically — this is by design, to keep your data local. You can manually transfer your vault by creating an encrypted .pkbak backup and restoring it on another Windows machine.

+
+ +
+
+
+ + + +
+
+
+

Start protecting your
passwords today.

+

Free, open-source, and runs entirely on your machine.

+ + + + +
+
+
+ + + + + + + + + + + + + + +