Last updated: March 15, 2026

Regularly auditing your password manager vault is essential for maintaining strong security hygiene. Over time, vaults accumulate stale credentials, weak passwords, and forgotten shared items that create attack vectors. This guide walks through practical methods to audit your vault using command-line tools and scripts, designed for developers and power users who want automation and control.

Why Vault Auditing Matters

Password managers simplify credential management, but they can also become repositories of security debt. A vault with hundreds of entries likely contains:

An audit helps you identify and remediate these issues before they become problems. Rather than manually reviewing each entry, you can use CLI tools and scripting to automate much of this process.

Prerequisites

Before you begin, make sure you have the following ready:

Step 1 - Exporting Your Vault Data

The first step in any audit is getting your vault data into a format you can analyze. Most password managers support encrypted exports that maintain your data’s security during the audit process.

Bitwarden CLI Export

Bitwarden provides a straightforward export command:

Install Bitwarden CLI first
npm install -g @bitwarden/cli

Login and unlock
bw login your-email@example.com
bw unlock

Export to JSON (will prompt for encryption password)
bw export --output ~/vault-export.json --format json

The exported JSON contains all your vault items including login credentials, secure notes, and payment cards. Keep this file secure, it’s unencrypted unless you provide a password during export.

1Password CLI Export

1Password requires using the CLI to export data:

Install 1Password CLI
brew install --cask 1password-cli

Sign in
op signin

Export vault to JSON
op list items | op get item - > ~/1password-export.json

KeePassXC Export

For KeePass databases, you can export directly:

Using keepassxc-cli
keepassxc-cli export --format csv database.kdbx -o vault-export.csv

Step 2 - Analyzing Password Strength

Once you have your vault data exported, the next step is analyzing password strength. You can write custom scripts or use existing tools to identify weak passwords.

Python Script for Password Analysis

Here’s a practical script that analyzes exported Bitwarden JSON:

#!/usr/bin/env python3
import json
import re
import sys
from typing import Dict, List

def analyze_password(password: str) -> Dict[str, any]:
    """Analyze a password for common weaknesses."""
    result = {
        'length': len(password),
        'has_upper': bool(re.search(r'[A-Z]', password)),
        'has_lower': bool(re.search(r'[a-z]', password)),
        'has_digit': bool(re.search(r'[0-9]', password)),
        'has_special': bool(re.search(r'[!@#$%^&*(),.?":{}|<>]', password)),
        'is_weak': False,
        'issues': []
    }

    if len(password) < 12:
        result['is_weak'] = True
        result['issues'].append('password too short (<12 characters)')

    if not result['has_upper'] or not result['has_lower']:
        result['is_weak'] = True
        result['issues'].append('missing case variation')

    if not result['has_digit'] or not result['has_special']:
        result['is_weak'] = True
        result['issues'].append('missing character diversity')

    # Check for common patterns
    if re.match(r'^[a-zA-Z]+$', password):
        result['issues'].append('letters only')
    if re.match(r'^[0-9]+$', password):
        result['issues'].append('digits only')

    return result

def audit_vault(json_file: str):
    """Audit exported Bitwarden vault."""
    with open(json_file, 'r') as f:
        vault = json.load(f)

    weak_passwords = []
    items = vault.get('items', [])

    for item in items:
        if item.get('type') != 1:  # Skip non-login items
            continue

        login = item.get('login', {})
        password = login.get('password', '')

        if not password:
            continue

        analysis = analyze_password(password)

        if analysis['is_weak']:
            weak_passwords.append({
                'name': item.get('name', 'Unknown'),
                'url': login.get('uri', ''),
                'issues': analysis['issues']
            })

    # Report results
    print(f"\nVault Audit Results")
    print(f"=" * 50)
    print(f"Total login items: {len(items)}")
    print(f"Weak passwords found: {len(weak_passwords)}\n")

    if weak_passwords:
        print("Weak Passwords:")
        for item in weak_passwords:
            print(f"  - {item['name']} ({item['url']})")
            for issue in item['issues']:
                print(f"      {issue}")

if __name__ == '__main__':
    if len(sys.argv) < 2:
        print("Usage - python audit_vault.py <exported-json-file>")
        sys.exit(1)
    audit_vault(sys.argv[1])

Run this script against your exported vault:

python3 audit_vault.py ~/vault-export.json

Step 3 - Identifying Reused Passwords

Password reuse is one of the most common security vulnerabilities. A data breach at one service exposes all accounts using the same password.

Finding Duplicates

Add this function to your analysis script to detect password reuse:

def find_reused_passwords(vault_data: Dict) -> List[Dict]:
    """Find passwords used across multiple accounts."""
    password_map = {}

    for item in vault_data.get('items', []):
        if item.get('type') != 1:
            continue

        password = item.get('login', {}).get('password', '')
        if not password:
            continue

        if password not in password_map:
            password_map[password] = []

        password_map[password].append({
            'name': item.get('name'),
            'url': item.get('login', {}).get('uri', '')
        })

    # Return only duplicates
    return [
        {'password': p, 'accounts': accounts}
        for p, accounts in password_map.items()
        if len(accounts) > 1
    ]

This identifies which passwords appear multiple times in your vault, allowing you to prioritize updating these credentials.

Step 4 - Checking for Compromised Passwords

Beyond analyzing password strength, you should check whether your passwords have appeared in known data breaches. The Have I Been Pwned API provides this functionality through a k-anonymity model that protects your actual passwords.

Integration with HIBP

import hashlib
import requests

def check_compromised(password: str) -> bool:
    """Check if password appears in known breaches."""
    # Hash password with SHA-1
    sha1_hash = hashlib.sha1(password.encode('utf-8')).hexdigest().upper()
    prefix, suffix = sha1_hash[:5], sha1_hash[5:]

    # Query HIBP API with prefix (k-anonymity)
    response = requests.get(
        f'https://api.pwnedpasswords.com/range/{prefix}'
    )

    if response.status_code != 200:
        return False

    # Check if our hash suffix appears in results
    for line in response.text.splitlines():
        hash_suffix, count = line.split(':')
        if hash_suffix == suffix:
            return True

    return False

def audit_compromised(vault_file: str):
    """Check all passwords against breach database."""
    with open(vault_file, 'r') as f:
        vault = json.load(f)

    compromised = []

    for item in vault.get('items', []):
        if item.get('type') != 1:
            continue

        password = item.get('login', {}).get('password', '')
        if password and check_compromised(password):
            compromised.append(item.get('name'))

    if compromised:
        print("\nCompromised passwords found in:")
        for name in compromised:
            print(f"  - {name}")
    else:
        print("\nNo compromised passwords found.")

Use this carefully, while the k-anonymity model protects your passwords, you’re still sending partial hashes to an external service. For maximum security, consider running this check only on an offline machine.

Step 5 - Create an Audit Workflow

Rather than performing manual audits, establish a regular workflow using your password manager’s built-in features combined with custom scripts.

Automated Weekly Audit

#!/bin/bash
Weekly vault audit script

DATE=$(date +%Y-%m-%d)
AUDIT_DIR=~/vault-audits
mkdir -p "$AUDIT_DIR"

Export vault
bw unlock --raw
export BW_SESSION
bw export --format json --output "$AUDIT_DIR/vault-$DATE.json"

Run analysis
python3 audit_vault.py "$AUDIT_DIR/vault-$DATE.json" > "$AUDIT_DIR/report-$DATE.txt"

Check for compromised passwords
python3 audit_compromised.py "$AUDIT_DIR/vault-$DATE.json" >> "$AUDIT_DIR/report-$DATE.txt"

echo "Audit complete. Report saved to $AUDIT_DIR/report-$DATE.txt"

Schedule this with cron to run weekly:

Add to crontab
0 9 * * 0 /path/to/weekly-audit.sh

Additional Audit Areas

Beyond passwords, review these vault components:

Two-Factor Authentication - Check which accounts still rely on less secure 2FA methods like SMS. Identify accounts without any two-factor enabled.

Secure Notes - Audit sensitive information stored in secure notes. Ensure nothing critical is stored without protection.

Shared Items - Review items shared with family or team members. Remove access for people who no longer need it.

Recovery Options - Verify your recovery email and phone number are current. Check that backup codes are stored securely.

Attachments - Review large files stored in your vault. Consider moving these to dedicated encrypted storage solutions.

Troubleshooting

Configuration changes not taking effect

Restart the relevant service or application after making changes. Some settings require a full system reboot. Verify the configuration file path is correct and the syntax is valid.

Permission denied errors

Run the command with sudo for system-level operations, or check that your user account has the necessary permissions. On macOS, you may need to grant terminal access in System Settings > Privacy & Security.

Connection or network-related failures

Check your internet connection and firewall settings. If using a VPN, try disconnecting temporarily to isolate the issue. Verify that the target server or service is accessible from your network.

Frequently Asked Questions

How long does it take to audit your password manager vault: a practical guide?

For a straightforward setup, expect 30 minutes to 2 hours depending on your familiarity with the tools involved. Complex configurations with custom requirements may take longer. Having your credentials and environment ready before starting saves significant time.

What are the most common mistakes to avoid?

The most frequent issues are skipping prerequisite steps, using outdated package versions, and not reading error messages carefully. Follow the steps in order, verify each one works before moving on, and check the official documentation if something behaves unexpectedly.

Do I need prior experience to follow this guide?

Basic familiarity with the relevant tools and command line is helpful but not strictly required. Each step is explained with context. If you get stuck, the official documentation for each tool covers fundamentals that may fill in knowledge gaps.

Is this approach secure enough for production?

The patterns shown here follow standard practices, but production deployments need additional hardening. Add rate limiting, input validation, proper secret management, and monitoring before going live. Consider a security review if your application handles sensitive user data.

Where can I get help if I run into issues?

Start with the official documentation for each tool mentioned. Stack Overflow and GitHub Issues are good next steps for specific error messages. Community forums and Discord servers for the relevant tools often have active members who can help with setup problems.

Related Articles