windows_hello poster

windows_hello

Flutter plugin for Windows Hello verification and Windows Credential Manager (PasswordVault) access.

Use it when your Windows desktop app needs to:

  • Confirm the user with face, fingerprint, iris, or Windows Hello PIN
  • Store, read, list, and delete secrets in the system Credential Locker

Most APIs return typed results (BiometricAvailability, VerifyResult, VaultResult) so you can branch on clear outcomes instead of decoding raw platform channel errors.

Windows only. Android, iOS, macOS, Linux, and Web are not supported.

Features

  • Check whether Windows Hello is available on the device
  • Show the system Windows Hello prompt with a custom reason string
  • Store / overwrite credentials in PasswordVault
  • Read, list, and delete credentials by resource and username
  • Typed result enums for common success and failure paths
  • FakeWindowsHelloPlatform for unit tests without a Windows machine

Supported unlock methods

Windows Hello decides which gesture to show based on what the user has enrolled. This plugin does not let you force a specific method.

Method Supported
Face Yes
Fingerprint Yes
Iris Yes
Windows Hello PIN Yes
Account password No
Security key (FIDO2) No

VerifyResult.verified means the user passed the Hello prompt. Face, fingerprint, iris, and PIN all return the same verified result — the API does not report which gesture was used.

Requirements

Requirement Value
OS Windows 10 version 1607 (Anniversary Update) or later
Flutter 3.3.0 or later
Dart 3.12.2 or later
Hello setup At least one Windows Hello method enrolled (or PIN) for verification

Install

dependencies:
  windows_hello: ^0.1.0

Then:

flutter pub get

Quick start

import 'package:windows_hello/windows_hello.dart';

final hello = WindowsHello.instance;

// 1. Check availability
final availability = await hello.checkBiometricAvailability();
if (availability != BiometricAvailability.available) {
  // Handle not configured / no device / policy, etc.
  return;
}

// 2. Prompt Windows Hello
final result = await hello.requestBiometricVerification(
  reason: 'Confirm it is you',
);
if (result == VerifyResult.verified) {
  // Continue with the protected action.
}

Credential Manager

Secrets are stored in the per-app Windows Credential Locker (PasswordVault). You can confirm them in Control Panel → Credential Manager → Windows Credentials.

final hello = WindowsHello.instance;

// Store (overwrites if resource + username already exist)
final stored = await hello.storeCredential(
  resource: 'com.example.app',
  username: 'alice',
  secret: 's3cret',
);

// Read — null means not found
final cred = await hello.readCredential(
  resource: 'com.example.app',
  username: 'alice',
);
print(cred?.secret);

// List all credentials for a resource
final all = await hello.getAllCredentials(
  resource: 'com.example.app',
);

// Delete
final deleted = await hello.deleteCredential(
  resource: 'com.example.app',
  username: 'alice',
);

Choosing a resource name

Use a stable, app-owned identifier (for example your reverse-DNS package id). Credentials are keyed by resource + username. Storing again with the same pair overwrites the previous secret.

API overview

Method Returns Notes
checkBiometricAvailability() BiometricAvailability Never throws PlatformException (maps to unknown)
requestBiometricVerification({reason}) VerifyResult Never throws PlatformException (maps to unknown)
storeCredential(...) VaultResult Overwrites existing resource + username
deleteCredential(...) VaultResult notFound when nothing matched
readCredential(...) VaultCredential? null = missing; other failures throw PlatformException
getAllCredentials(...) List<VaultCredential> Empty list = none; other failures throw PlatformException

BiometricAvailability

Value Meaning
available Hello can be prompted
deviceNotPresent No usable biometric / Hello device
notConfiguredByUser User has not set up Windows Hello
disabledByPolicy Blocked by organization policy
deviceBusy Sensor or Hello UI is busy
unknown Unexpected / channel failure

VerifyResult

Value Meaning
verified User passed the Hello prompt
canceled User dismissed the prompt
retriesExhausted Too many failed attempts
deviceNotPresent No usable device
notConfiguredByUser Hello not set up
disabledByPolicy Blocked by policy
deviceBusy Device busy
unknown Unexpected / channel failure

VaultResult

Value Meaning
success Operation completed
notFound No matching credential (delete)
accessDenied Windows denied access
unknown Unexpected / channel failure

Error handling

// Biometric APIs — branch on enums
switch (await hello.checkBiometricAvailability()) {
  case BiometricAvailability.available:
    break;
  case BiometricAvailability.notConfiguredByUser:
    // Ask the user to set up Windows Hello in Settings.
    break;
  default:
    // Unavailable or unknown.
    break;
}

// Vault reads — null vs exception
try {
  final cred = await hello.readCredential(
    resource: 'com.example.app',
    username: 'alice',
  );
  if (cred == null) {
    // Not stored yet.
  } else {
    // Use cred.secret
  }
} on PlatformException catch (e) {
  // Access denied or other vault failure — not the same as "missing".
}

Example app

The example/ folder is a Windows desktop demo with:

  • Windows Hello availability + verify actions
  • Editable PasswordVault resource / username / secret fields
  • Plain-language status messages for each result
cd example
flutter run -d windows

Testing

Inject a fake platform — no Windows machine required:

import 'package:flutter_test/flutter_test.dart';
import 'package:windows_hello/windows_hello.dart';

void main() {
  test('verification success path', () async {
    final fake = FakeWindowsHelloPlatform(
      availability: BiometricAvailability.available,
      verifyResult: VerifyResult.verified,
    );
    final hello = WindowsHello(platform: fake);

    expect(
      await hello.checkBiometricAvailability(),
      BiometricAvailability.available,
    );
    expect(
      await hello.requestBiometricVerification(reason: 'test'),
      VerifyResult.verified,
    );
  });
}

When to use local_auth instead

local_auth (via local_auth_windows) already covers the common “unlock this action with Windows Hello” case and supports multiple platforms.

Prefer windows_hello when you need:

  1. PasswordVault / Credential Manager from Flutter (not offered by local_auth)
  2. Typed availability and verify results without decoding channel errors
  3. A Windows-only dependency without the full multi-platform local_auth stack

Limitations

  • Windows desktop only
  • Cannot force face-only / fingerprint-only / PIN-only (system chooses)
  • Does not prompt for account password or security keys
  • PasswordVault is per-user / per-app; credentials are not shared across apps
  • AppContainer apps are limited to 20 credentials in the locker (Windows platform limit)

Privacy

This plugin performs no network calls and collects no telemetry. All operations stay on-device via WinRT (UserConsentVerifier and PasswordVault).

Federated packages

Package Role
windows_hello App-facing Dart API (this package)
windows_hello_platform_interface Platform interface + Pigeon messages
windows_hello_windows C++/WinRT implementation

License

See LICENSE.

Libraries

windows_hello