Python bindings to FreeDesktop.org Secret Service API for secure password and credential storage
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Python bindings to the FreeDesktop.org Secret Service API for secure storage and retrieval of passwords and other secrets on Linux systems. SecretStorage integrates with GNOME Keyring, KWallet (version 5.97+), and KeePassXC through D-Bus communication, providing a standardized interface for credential management across Linux desktop environments.
pip install secretstoragecryptography>=2.0, jeepney>=0.6__version__ = '3.3.3' # Version string
__version_tuple__ = (3, 3, 3) # Version tuple (major, minor, patch)import secretstorageCommon imports for specific functionality:
from secretstorage import Collection, Item, dbus_init
from secretstorage import get_default_collection, create_collection
from secretstorage import LockedException, ItemNotFoundExceptionimport secretstorage
# Initialize D-Bus connection
connection = secretstorage.dbus_init()
# Get the default collection (keyring)
collection = secretstorage.get_default_collection(connection)
# Store a password
item = collection.create_item(
'My Application Password', # label
{'application': 'myapp', 'username': 'john'}, # attributes
b'my_secret_password' # secret data
)
# Retrieve the password later
items = list(collection.search_items({'application': 'myapp', 'username': 'john'}))
if items:
secret = items[0].get_secret()
print(f"Retrieved password: {secret.decode()}")
# Clean up
connection.close()SecretStorage follows the FreeDesktop.org Secret Service specification with these key components:
The library automatically handles encryption/decryption, session management, and D-Bus protocol details, providing a high-level Python interface for secure credential storage.
Establishes and manages D-Bus connections to the Secret Service, with service availability checking and proper connection lifecycle management.
def dbus_init() -> DBusConnection:
"""Returns a new connection to the session bus."""
def check_service_availability(connection: DBusConnection) -> bool:
"""Returns True if Secret Service daemon is available."""Manages collections (keyrings) including creation, retrieval, locking/unlocking, and deletion. Collections serve as secure containers for organizing related secret items.
def get_default_collection(connection: DBusConnection, session: Optional[Session] = None) -> Collection:
"""Returns the default collection, creating if necessary."""
def create_collection(connection: DBusConnection, label: str, alias: str = '', session: Optional[Session] = None) -> Collection:
"""Creates a new collection with given label and alias."""
def get_all_collections(connection: DBusConnection) -> Iterator[Collection]:
"""Returns generator of all available collections."""
class Collection:
def create_item(self, label: str, attributes: Dict[str, str], secret: bytes, replace: bool = False, content_type: str = 'text/plain') -> Item: ...
def search_items(self, attributes: Dict[str, str]) -> Iterator[Item]: ...
def is_locked(self) -> bool: ...
def unlock(self) -> bool: ...Handles individual secret items with comprehensive operations for storing, retrieving, and managing secret data, attributes, and metadata.
class Item:
def get_secret(self) -> bytes:
"""Returns item secret data."""
def set_secret(self, secret: bytes, content_type: str = 'text/plain') -> None:
"""Sets item secret data."""
def get_attributes(self) -> Dict[str, str]:
"""Returns item attributes dictionary."""
def set_attributes(self, attributes: Dict[str, str]) -> None:
"""Sets item attributes."""
def get_label(self) -> str:
"""Returns item label."""
def delete(self) -> None:
"""Deletes the item."""Provides powerful search capabilities for finding secret items across collections using attribute-based queries with support for global and collection-specific searches.
def search_items(connection: DBusConnection, attributes: Dict[str, str]) -> Iterator[Item]:
"""Searches items across all collections."""Comprehensive exception hierarchy for handling various error conditions including service unavailability, locked collections, missing items, and dismissed authentication prompts.
class SecretStorageException(Exception):
"""Base exception class for all SecretStorage errors."""
class SecretServiceNotAvailableException(SecretStorageException):
"""Secret Service API is not available."""
class LockedException(SecretStorageException):
"""Collection or item is locked."""
class ItemNotFoundException(SecretStorageException):
"""Item does not exist or has been deleted."""
class PromptDismissedException(ItemNotFoundException):
"""Authentication prompt was dismissed by user."""Handles cryptographic sessions for secure data transfer between client and Secret Service daemon, including Diffie-Hellman key exchange and AES encryption.
class Session:
"""Cryptographic session for secure data transfer."""
object_path: Optional[str] # D-Bus object path
encrypted: bool # Whether session uses encryption
aes_key: Optional[bytes] # AES encryption key (when encrypted)from typing import Dict, Iterator, Optional
# From jeepney.io.blocking (external dependency)
class DBusConnection:
"""D-Bus connection for communicating with system services."""
def close(self) -> None:
"""Close the D-Bus connection."""
# From secretstorage.dhcrypto
class Session:
"""Cryptographic session for secure data transfer."""
object_path: Optional[str]
encrypted: bool
aes_key: Optional[bytes]
my_private_key: int
my_public_key: int
def set_server_public_key(self, server_public_key: int) -> None:
"""Sets server's public key and derives shared AES key."""
# Secret Service Constants (from defines.py)
SS_PREFIX: str = 'org.freedesktop.Secret.'
SS_PATH: str = '/org/freedesktop/secrets'
ALGORITHM_PLAIN: str = 'plain'
ALGORITHM_DH: str = 'dh-ietf1024-sha256-aes128-cbc-pkcs7'Install with Tessl CLI
npx tessl i tessl/pypi-secretstorage