Official Python client for the Lanyard BYOK Vault.
Project description
Lanyard Python SDK (lanyard-py)
Lanyard is a local Bring Your Own Key (BYOK) manager that stores sensitive data (API Keys, Passwords, Cryptographic pairs) securely inside the native OS Keychain.
This SDK allows your Python applications to seamlessly request access to a user's Lanyard vault. It acts like a local OAuth flow: your app asks for a key, the Lanyard Desktop UI pops up to ask the user for consent, and the decrypted key is returned directly to your application's memory.
Features
- Zero Dependencies: Built entirely on Python standard libraries (
urllib,json). - Secure by Default: Keys are never saved to disk by your app. They remain in the OS secure enclave.
- Context-Aware UI: Ask for specific types of data (e.g., only "Passwords") and provide custom prompt text.
- Drop-in Integration: Implement secure key fetching in under 10 lines of code.
Installation
pip install lanyard
Quick Start: The "Link & Fetch" Flow
Integrating Lanyard into your app involves a two-step process:
- The Link Request (First Setup): Prompt the user to select a key from their vault.
- The Direct Fetch (Every subsequent boot): Use the saved UUID to quietly fetch the key.
from lanyard import LanyardClient
from lanyard.exceptions import LanyardNotRunningError, LanyardAccessDeniedError
# 1. Initialize the client with your application's name
client = LanyardClient(app_name="YourApp")
def first_time_setup():
"""Triggered when the user clicks 'Connect Lanyard' in your app."""
try:
# Prompts the Lanyard UI drop-down menu
response = client.request_link(
reason="Required: OpenAI API Key",
category="api_key"
)
# Save this UUID to your app's local settings/database
lanyard_uuid = response["target_id"]
save_to_settings("openai_lanyard_id", lanyard_uuid)
print("Successfully linked! Key data:", response["data"])
except LanyardNotRunningError:
print("Please download and open the Lanyard Desktop application.")
except LanyardAccessDeniedError:
print("User cancelled the request.")
def fetch_key():
"""Triggered when you need to fetch data from lanyard."""
saved_uuid = load_from_settings("openai_lanyard_id")
if saved_uuid:
try:
# Fetches the specific field. (If the user checked 'Always Allow'
# in the past, this returns instantly without a UI popup!)
openai_key = client.get_field(saved_uuid, "Private/Secret Key")
# Apply to your environment
import openai
openai.api_key = openai_key
except LanyardAccessDeniedError:
print("Access revoked by user.")
API Reference
LanyardClient(app_name: str, port: Optional[int] = None)
Initializes the SDK.
app_name: The name of your application. This is displayed prominently in the Lanyard Desktop UI to ensure the user knows who is requesting their data.port: (Optional) Lanyard dynamically manages ports. If left asNone, the SDK will automatically read the~/.lanyard/portfile to find the active server.
client.request_link(reason: str = None, category: str = None, timeout: int = 300) -> dict
Wakes up the Lanyard Desktop UI and presents the user with a dropdown menu to select a key.
reason: (Optional) Italicized subtext displayed in the UI to give the user context (e.g., "Requires an AWS root key").category: (Optional) Filters the dropdown to only show specific data types. Valid options:"api_key","password","env","crypto","license","recovery".- Returns: A dictionary containing the
target_id(UUID) and the decrypteddatadictionary.
client.get_secret(target_id: str, timeout: int = 300) -> dict
Requests a specific key by its UUID. If the user previously checked "Always Allow" for your app, this returns instantly. Otherwise, it prompts the UI for explicit approval.
- Returns: A dictionary containing all fields inside the requested Lanyard item.
client.get_field(target_id: str, field_name: str, timeout: int = 300) -> str
A helper method that calls get_secret() and extracts a single string field.
field_name: The exact string name of the field you want (e.g.,"Endpoint URL").
Error Handling
Lanyard provides explicit exceptions so your application can gracefully degrade if the user rejects a request or doesn't have Lanyard installed.
LanyardNotRunningError: Raised when the local Lanyard HTTP server cannot be reached.LanyardAccessDeniedError: Raised when the user clicks "Deny", enters the wrong Master PIN, or cancels the request.LanyardTimeoutError: Raised if the user ignores the prompt and the request times out (default 300s).LanyardKeyNotFoundError: Raised ifget_fieldrequests a field name that doesn't exist in the returned payload.LanyardError: Base exception for malformed requests or unexpected HTTP errors.
Security Model
Lanyard does not provide encrypted keys to your application. When an access request is approved, Lanyard decrypts the data using the user's Master PIN and passes the plaintext data to your application's memory via localhost IPC.
It is the responsibility of the integrating application to use this data securely in memory and never write it to disk outside of the OS Credentials Manager. You should only save the Lanyard UUID (target_id) to your configuration files.
Changelogs
0.1.2 - Updated README.md
0.1.2 - Added "recovery" as a valid category option. Used for storing recovery keys.
0.1.1 - Updated README.md
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file lanyard-0.1.2.tar.gz.
File metadata
- Download URL: lanyard-0.1.2.tar.gz
- Upload date:
- Size: 5.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ca3bda76f786b825816a69100773bc9c07d6c8bba779502f3cf1634198e251bb
|
|
| MD5 |
3947ea9b6065fab2904d5a0569963467
|
|
| BLAKE2b-256 |
526662c2b2bf82ba4e5e22b92b6d4d92d7cdb9958683338a07a5cb03e25e807f
|
File details
Details for the file lanyard-0.1.2-py3-none-any.whl.
File metadata
- Download URL: lanyard-0.1.2-py3-none-any.whl
- Upload date:
- Size: 6.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1184cdb53b1f911f0d6597a3ee40d2c745113e78740422c17c74fe094fa977d5
|
|
| MD5 |
a960e053b0e8d3e99a70aeddefe63440
|
|
| BLAKE2b-256 |
e208a119282b7501d8f0b6718beb940661c83865318b5db63f6e0a75aacd2482
|