kdbxtool.database¶
High-level Database API for KDBX files.
This module provides the main interface for working with KeePass databases: - Opening and decrypting KDBX files - Creating new databases - Searching for entries and groups - Saving databases
Classes
|
A custom icon in a KDBX database. |
|
High-level interface for KDBX databases. |
|
Settings for a KDBX database. |
|
Stream cipher for encrypting/decrypting protected values in XML. |
- class kdbxtool.database.ProtectedStreamCipher(stream_id, stream_key)[source]¶
Bases:
objectStream cipher for encrypting/decrypting protected values in XML.
KDBX uses a stream cipher (ChaCha20 or Salsa20) to protect sensitive values like passwords in the XML payload. Each protected value is XOR’d with the cipher output in document order.
- class kdbxtool.database.CustomIcon(uuid, data, name=None, last_modification_time=None)[source]¶
Bases:
objectA custom icon in a KDBX database.
Custom icons are PNG images that can be assigned to entries and groups for visual customization beyond the standard icon set.
- last_modification_time¶
When the icon was last modified
- Type:
datetime.datetime | None
- class kdbxtool.database.DatabaseSettings(generator='kdbxtool', database_name='Database', database_description='', default_username='', maintenance_history_days=365, color=None, master_key_change_rec=-1, master_key_change_force=-1, memory_protection=<factory>, recycle_bin_enabled=True, recycle_bin_uuid=None, history_max_items=10, history_max_size=6291456, custom_icons=<factory>, deleted_objects=<factory>)[source]¶
Bases:
objectSettings for a KDBX database.
- Parameters:
generator (str)
database_name (str)
database_description (str)
default_username (str)
maintenance_history_days (int)
color (str | None)
master_key_change_rec (int)
master_key_change_force (int)
recycle_bin_enabled (bool)
recycle_bin_uuid (uuid_module.UUID | None)
history_max_items (int)
history_max_size (int)
custom_icons (dict[uuid_module.UUID, CustomIcon])
deleted_objects (list[DeletedObject])
- recycle_bin_uuid¶
UUID of recycle bin group
- Type:
uuid_module.UUID | None
- custom_icons¶
Dictionary of custom icons (UUID -> CustomIcon)
- Type:
dict[uuid_module.UUID, CustomIcon]
- custom_icons: dict[uuid_module.UUID, CustomIcon]¶
- deleted_objects: list[DeletedObject]¶
- __init__(generator='kdbxtool', database_name='Database', database_description='', default_username='', maintenance_history_days=365, color=None, master_key_change_rec=-1, master_key_change_force=-1, memory_protection=<factory>, recycle_bin_enabled=True, recycle_bin_uuid=None, history_max_items=10, history_max_size=6291456, custom_icons=<factory>, deleted_objects=<factory>)¶
- Parameters:
generator (str)
database_name (str)
database_description (str)
default_username (str)
maintenance_history_days (int)
color (str | None)
master_key_change_rec (int)
master_key_change_force (int)
recycle_bin_enabled (bool)
recycle_bin_uuid (uuid_module.UUID | None)
history_max_items (int)
history_max_size (int)
custom_icons (dict[uuid_module.UUID, CustomIcon])
deleted_objects (list[DeletedObject])
- Return type:
None
- class kdbxtool.database.Database(root_group, settings=None, header=None, inner_header=None, binaries=None)[source]¶
Bases:
objectHigh-level interface for KDBX databases.
This class provides the main API for working with KeePass databases. It handles encryption/decryption, XML parsing, and model management.
- Example usage:
# Open existing database db = Database.open(“passwords.kdbx”, password=”secret”)
# Find entries entries = db.find_entries(title=”GitHub”)
# Create entry entry = db.root_group.create_entry(
title=”New Site”, username=”user”, password=”pass123”,
)
# Save changes db.save()
- Parameters:
root_group (Group)
settings (DatabaseSettings | None)
header (KdbxHeader | None)
inner_header (InnerHeader | None)
- __init__(root_group, settings=None, header=None, inner_header=None, binaries=None)[source]¶
Initialize database.
Usually you should use Database.open() or Database.create() instead.
- Parameters:
root_group (Group) – Root group containing all entries/groups
settings (DatabaseSettings | None) – Database settings
header (KdbxHeader | None) – KDBX header (for existing databases)
inner_header (InnerHeader | None) – Inner header (for existing databases)
- Return type:
None
- zeroize_credentials()[source]¶
Explicitly zeroize stored credentials from memory.
Call this when done with the database to minimize the time credentials remain in memory. Note that Python’s string interning may retain copies; for maximum security, use SecureBytes for credential input.
- Return type:
None
- dump()[source]¶
Return a human-readable summary of the database for debugging.
- Returns:
Multi-line string with database metadata and statistics.
- Return type:
- merge(source, *, mode=None)[source]¶
Merge another database into this one.
Combines entries, groups, history, attachments, and custom icons from the source database into this database using UUID-based matching and timestamp-based conflict resolution.
- Parameters:
- Returns:
MergeResult with counts and statistics about the merge
- Raises:
MergeError – If merge cannot be completed
- Return type:
Example
>>> target_db = Database.open("main.kdbx", password="secret") >>> source_db = Database.open("branch.kdbx", password="secret") >>> result = target_db.merge(source_db) >>> print(f"Added {result.entries_added} entries") >>> target_db.save()
- property transformed_key: bytes | None¶
Get the transformed key for caching.
The transformed key is the result of applying the KDF (Argon2) to the credentials. Caching this allows fast repeated database opens without re-running the expensive KDF.
Security note: The transformed key is as sensitive as the password. Anyone with this key can decrypt the database. Store securely and zeroize when done.
- Returns:
The transformed key, or None if not available (e.g., newly created DB)
- property kdf_salt: bytes | None¶
Get the KDF salt used for key derivation.
The salt is used together with credentials to derive the transformed key. If the salt changes (e.g., after save with regenerate_seeds=True), any cached transformed_key becomes invalid.
- Returns:
The KDF salt, or None if no header is set
- property settings: DatabaseSettings¶
Get database settings.
- classmethod open(filepath, password=None, keyfile=None, yubikey_slot=None, yubikey_serial=None)[source]¶
Open an existing KDBX database.
- Parameters:
password (str | None) – Database password
yubikey_slot (int | None) – YubiKey slot for challenge-response (1 or 2, optional). If provided, the database’s KDF salt is used as challenge and the 20-byte HMAC-SHA1 response is incorporated into key derivation. Requires yubikey-manager package: pip install kdbxtool[yubikey]
yubikey_serial (int | None) – Serial number of specific YubiKey to use when multiple devices are connected. Use list_yubikeys() to discover serials.
- Returns:
Database instance
- Raises:
FileNotFoundError – If file doesn’t exist
ValueError – If credentials are wrong or file is corrupted
YubiKeyError – If YubiKey operation fails
- Return type:
- classmethod open_interactive(filepath, keyfile=None, yubikey_slot=None, yubikey_serial=None, prompt='Password: ', max_attempts=3)[source]¶
Open a KDBX database with interactive password prompt.
Prompts the user for a password using secure input (no echo). If the password is incorrect, allows retrying up to max_attempts times.
This is a convenience method for CLI applications that need to securely prompt for database credentials.
- Parameters:
- Returns:
Database instance
- Raises:
FileNotFoundError – If file or keyfile doesn’t exist
AuthenticationError – If max_attempts exceeded with wrong password
YubiKeyError – If YubiKey operation fails
- Return type:
Example
>>> db = Database.open_interactive("vault.kdbx") Password: >>> db = Database.open_interactive("vault.kdbx", keyfile="vault.key") Password:
- classmethod open_bytes(data, password=None, keyfile_data=None, filepath=None, transformed_key=None, yubikey_slot=None, yubikey_serial=None)[source]¶
Open a KDBX database from bytes.
Supports both KDBX3 and KDBX4 formats. KDBX3 databases are opened read-only and will be automatically upgraded to KDBX4 on save.
- Parameters:
data (bytes) – KDBX file contents
password (str | None) – Database password
keyfile_data (bytes | None) – Keyfile contents (optional)
filepath (Path | None) – Original file path (for save)
transformed_key (bytes | None) – Precomputed transformed key (skips KDF, faster opens)
yubikey_slot (int | None) – YubiKey slot for challenge-response (1 or 2, optional). If provided, the database’s KDF salt is used as challenge and the 20-byte HMAC-SHA1 response is incorporated into key derivation. Requires yubikey-manager package: pip install kdbxtool[yubikey]
yubikey_serial (int | None) – Serial number of specific YubiKey to use when multiple devices are connected. Use list_yubikeys() to discover serials.
- Returns:
Database instance
- Raises:
YubiKeyError – If YubiKey operation fails
- Return type:
- classmethod create(filepath=None, password=None, keyfile=None, database_name='Database', cipher=Cipher.AES256_CBC, kdf_config=None)[source]¶
Create a new KDBX database.
- Parameters:
filepath (str | Path | None) – Path to save the database (optional)
password (str | None) – Database password
database_name (str) – Name for the database
cipher (Cipher) – Encryption cipher to use
kdf_config (Argon2Config | AesKdfConfig | None) – KDF configuration (Argon2Config or AesKdfConfig). Defaults to Argon2Config.standard() with Argon2d variant.
- Returns:
New Database instance
- Return type:
- save(filepath=None, *, allow_upgrade=False, regenerate_seeds=True, kdf_config=None, cipher=None, yubikey_slot=None, yubikey_serial=None)[source]¶
Save the database to a file.
KDBX3 databases are automatically upgraded to KDBX4 on save. When saving a KDBX3 database to its original file, explicit confirmation is required via the allow_upgrade parameter.
- Parameters:
filepath (str | Path | None) – Path to save to (uses original path if not specified)
allow_upgrade (bool) – Must be True to confirm KDBX3 to KDBX4 upgrade when saving to the original file. Not required when saving to a new file.
regenerate_seeds (bool) – If True (default), regenerate all cryptographic seeds (master_seed, encryption_iv, kdf_salt, random_stream_key) on save. Set to False only for testing or when using pre-computed transformed keys.
kdf_config (Argon2Config | AesKdfConfig | None) – Optional KDF configuration for KDBX3 upgrade. Use presets like: - Argon2Config.standard() / high_security() / fast() - AesKdfConfig.standard() / high_security() / fast() Defaults to Argon2Config.standard() with Argon2d variant.
cipher (Cipher | None) – Optional encryption cipher. Use one of: - Cipher.AES256_CBC (default, widely compatible) - Cipher.CHACHA20 (modern, faster in software) - Cipher.TWOFISH256_CBC (requires oxifish package) If not specified, preserves existing cipher.
yubikey_slot (int | None) – YubiKey slot for challenge-response (1 or 2, optional). If provided (or if database was opened with yubikey_slot), the new KDF salt is used as challenge and the response is incorporated into key derivation. Requires yubikey-manager package.
yubikey_serial (int | None) – Serial number of specific YubiKey to use when multiple devices are connected. Use list_yubikeys() to discover serials.
- Raises:
DatabaseError – If no filepath specified and database wasn’t opened from file
Kdbx3UpgradeRequired – If saving KDBX3 to original file without allow_upgrade=True
YubiKeyError – If YubiKey operation fails
- Return type:
None
- reload()[source]¶
Reload the database from disk using stored credentials.
Re-reads the database file and replaces all in-memory state with the current file contents. Useful for discarding unsaved changes or syncing with external modifications.
- Raises:
DatabaseError – If database wasn’t opened from a file
MissingCredentialsError – If no credentials are stored
- Return type:
None
- xml(*, pretty_print=False)[source]¶
Export database XML payload.
Returns the decrypted, decompressed XML payload of the database. Protected values (passwords, etc.) are shown in plaintext. Useful for debugging and migration.
- dump_xml(filepath, *, pretty_print=True)[source]¶
Write database XML payload to a file.
Writes the decrypted, decompressed XML payload to a file. Protected values (passwords, etc.) are shown in plaintext. Useful for debugging and migration.
- to_bytes(*, regenerate_seeds=True, kdf_config=None, cipher=None, yubikey_slot=None, yubikey_serial=None)[source]¶
Serialize the database to KDBX4 format.
KDBX3 databases are automatically upgraded to KDBX4 on save. This includes converting to the specified KDF and ChaCha20 protected stream.
- Parameters:
regenerate_seeds (bool) – If True (default), regenerate all cryptographic seeds (master_seed, encryption_iv, kdf_salt, random_stream_key) on save. This prevents precomputation attacks where an attacker can derive the encryption key in advance. Set to False only for testing or when using pre-computed transformed keys.
kdf_config (Argon2Config | AesKdfConfig | None) – Optional KDF configuration for KDBX3 upgrade. Use presets like: - Argon2Config.standard() / high_security() / fast() - AesKdfConfig.standard() / high_security() / fast() Defaults to Argon2Config.standard() with Argon2d variant.
cipher (Cipher | None) – Optional encryption cipher. Use one of: - Cipher.AES256_CBC (default, widely compatible) - Cipher.CHACHA20 (modern, faster in software) - Cipher.TWOFISH256_CBC (requires oxifish package) If not specified, preserves existing cipher.
yubikey_slot (int | None) – YubiKey slot for challenge-response (1 or 2, optional). If provided, the (new) KDF salt is used as challenge and the 20-byte HMAC-SHA1 response is incorporated into key derivation. Requires yubikey-manager package: pip install kdbxtool[yubikey]
yubikey_serial (int | None) – Serial number of specific YubiKey to use when multiple devices are connected. Use list_yubikeys() to discover serials.
- Returns:
KDBX4 file contents as bytes
- Raises:
MissingCredentialsError – If no credentials are set
YubiKeyError – If YubiKey operation fails
- Return type:
- set_credentials(password=None, keyfile_data=None)[source]¶
Set or update database credentials.
- Parameters:
- Raises:
ValueError – If both password and keyfile are None
- Return type:
None
- find_entries(title=None, username=None, password=None, url=None, notes=None, otp=None, tags=None, string=None, autotype_enabled=None, autotype_sequence=None, autotype_window=None, uuid=None, path=None, recursive=True, history=False, first=False)[source]¶
Find entries matching criteria.
- Parameters:
title (str | None) – Match entries with this title
username (str | None) – Match entries with this username
password (str | None) – Match entries with this password
url (str | None) – Match entries with this URL
notes (str | None) – Match entries with these notes
otp (str | None) – Match entries with this OTP
string (dict[str, str] | None) – Match entries with custom properties (dict of key:value)
autotype_enabled (bool | None) – Filter by AutoType enabled state
autotype_sequence (str | None) – Match entries with this AutoType sequence
autotype_window (str | None) – Match entries with this AutoType window
uuid (UUID | None) – Match entry with this UUID
path (list[str] | str | None) – Path to entry as list of group names ending with entry title, or as a ‘/’-separated string. When specified, other criteria are ignored.
recursive (bool) – Search in subgroups
history (bool) – Include history entries in search
first (bool) – If True, return first match or None. If False, return list.
- Returns:
Entry or None If first=False: List of matching entries
- Return type:
If first=True
- find_groups(name=None, uuid=None, path=None, recursive=True, first=False)[source]¶
Find groups matching criteria.
- Parameters:
name (str | None) – Match groups with this name
uuid (UUID | None) – Match group with this UUID
path (list[str] | str | None) – Path to group as list of group names or as a ‘/’-separated string. When specified, other criteria are ignored.
recursive (bool) – Search in nested subgroups
first (bool) – If True, return first matching group or None instead of list
- Returns:
List of matching groups, or single Group/None if first=True
- Return type:
- find_entries_contains(title=None, username=None, password=None, url=None, notes=None, otp=None, recursive=True, case_sensitive=False, history=False)[source]¶
Find entries where fields contain the given substrings.
All criteria are combined with AND logic. None means “any value”.
- Parameters:
title (str | None) – Match entries whose title contains this substring
username (str | None) – Match entries whose username contains this substring
password (str | None) – Match entries whose password contains this substring
url (str | None) – Match entries whose URL contains this substring
notes (str | None) – Match entries whose notes contain this substring
otp (str | None) – Match entries whose OTP contains this substring
recursive (bool) – Search in subgroups
case_sensitive (bool) – If False (default), matching is case-insensitive
history (bool) – Include history entries in search
- Returns:
List of matching entries
- Return type:
- find_entries_regex(title=None, username=None, password=None, url=None, notes=None, otp=None, recursive=True, case_sensitive=False, history=False)[source]¶
Find entries where fields match the given regex patterns.
All criteria are combined with AND logic. None means “any value”.
- Parameters:
title (str | None) – Regex pattern to match against title
username (str | None) – Regex pattern to match against username
password (str | None) – Regex pattern to match against password
url (str | None) – Regex pattern to match against URL
notes (str | None) – Regex pattern to match against notes
otp (str | None) – Regex pattern to match against OTP
recursive (bool) – Search in subgroups
case_sensitive (bool) – If False (default), matching is case-insensitive
history (bool) – Include history entries in search
- Returns:
List of matching entries
- Raises:
re.error – If any pattern is not a valid regex
- Return type:
- find_attachments(id=None, filename=None, regex=False, recursive=True, history=False, first=False)[source]¶
Find attachments in the database.
- Parameters:
id (int | None) – Match attachments with this binary reference ID
filename (str | None) – Match attachments with this filename (exact or regex)
regex (bool) – If True, treat filename as a regex pattern
recursive (bool) – Search in subgroups
history (bool) – Include history entries in search
first (bool) – If True, return first match or None. If False, return list.
- Returns:
Attachment or None If first=False: List of matching attachments
- Return type:
If first=True
- property attachments: list[Attachment]¶
Get all attachments in the database.
- deref(value)[source]¶
Resolve KeePass field references in a value.
Parses field references in the format {REF:X@Y:Z} and replaces them with the actual values from the referenced entries: - X = Field to retrieve (T=Title, U=Username, P=Password, A=URL, N=Notes, I=UUID) - Y = Field to search by (T, U, P, A, N, I) - Z = Search value
References are resolved recursively, so a reference that resolves to another reference will continue resolving until a final value is found.
- Parameters:
value (str | None) – String potentially containing field references
- Returns:
The resolved string with all references replaced
A UUID if the final result is a UUID reference
None if any referenced entry cannot be found
The original value if it contains no references or is None
- Return type:
Example
>>> # Entry with password = '{REF:P@I:ABCD1234...}' >>> db.deref(entry.password) # Returns the referenced password >>> >>> # With prefix/suffix: 'prefix{REF:U@I:...}suffix' >>> db.deref(value) # Returns 'prefix<username>suffix'
- move_entry(entry, destination)[source]¶
Move an entry to a different group.
This is a convenience method that calls entry.move_to(). It validates that both the entry and destination belong to this database.
- Parameters:
- Raises:
ValueError – If entry or destination is not in this database
ValueError – If entry has no parent
ValueError – If destination is the current parent
- Return type:
None
- move_group(group, destination)[source]¶
Move a group to a different parent group.
This is a convenience method that calls group.move_to(). It validates that both the group and destination belong to this database.
- Parameters:
- Raises:
ValueError – If group or destination is not in this database
ValueError – If group is the root group
ValueError – If group has no parent
ValueError – If destination is the current parent
ValueError – If destination is the group itself or a descendant
- Return type:
None
- property recyclebin_group: Group | None¶
Get the recycle bin group, or None if disabled.
If recycle_bin_enabled is True but no recycle bin exists yet, this creates one automatically.
- Returns:
Recycle bin Group, or None if recycle bin is disabled
- trash_entry(entry)[source]¶
Move an entry to the recycle bin.
If the entry is already in the recycle bin, it is permanently deleted.
- Parameters:
entry (Entry) – Entry to trash
- Raises:
ValueError – If entry is not in this database
ValueError – If recycle bin is disabled
- Return type:
None
- trash_group(group)[source]¶
Move a group to the recycle bin.
If the group is already in the recycle bin, it is permanently deleted. Cannot trash the root group or the recycle bin itself.
- Parameters:
group (Group) – Group to trash
- Raises:
ValueError – If group is not in this database
ValueError – If group is the root group
ValueError – If group is the recycle bin
ValueError – If recycle bin is disabled
- Return type:
None
- empty_group(group)[source]¶
Delete all entries and subgroups from a group.
This permanently deletes all contents (does not use recycle bin). The group itself is not deleted.
- Parameters:
group (Group) – Group to empty
- Raises:
ValueError – If group is not in this database
- Return type:
None
- apply_protection_policy(entry)[source]¶
Apply the database’s memory protection policy to an entry.
Updates the protected flag on the entry’s string fields according to the database’s memory_protection settings.
This is automatically applied when saving the database, but can be called manually if you need protection applied immediately for in-memory operations.
- Parameters:
entry (Entry) – Entry to apply policy to
- Return type:
None
- apply_protection_policy_all()[source]¶
Apply memory protection policy to all entries in the database.
Updates all entries’ string field protection flags according to the database’s memory_protection settings.
- Return type:
None
- property custom_icons: dict[UUID, CustomIcon]¶
Get dictionary of custom icons (UUID -> CustomIcon).
- remove_custom_icon(uuid)[source]¶
Remove a custom icon from the database.
Note: This does not update entries/groups that reference this icon. They will continue to reference the now-missing UUID.
- find_custom_icon_by_name(name)[source]¶
Find a custom icon by name.
- Parameters:
name (str) – Name of the icon to find (must match exactly one icon)
- Returns:
UUID of the matching icon, or None if not found
- Raises:
ValueError – If multiple icons have the same name
- Return type:
UUID | None