Skip to main content

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

(Note: Currently in pre-release. Install via local path or pip git URL depending on your distribution method)

pip install lanyard

Quick Start: The "Link & Fetch" Flow

Integrating Lanyard into your app involves a two-step process:

  1. The Link Request (First Setup): Prompt the user to select a key from their vault.
  2. 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 on_app_startup():
    """Triggered every time your application boots."""
    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: int = 49152)

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.

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".
  • Returns: A dictionary containing the target_id (UUID) and the decrypted data dictionary.

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) -> 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 if get_field requests 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. You should only save the Lanyard UUID (target_id) to your configuration files.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

lanyard-0.1.0.tar.gz (5.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

lanyard-0.1.0-py3-none-any.whl (6.2 kB view details)

Uploaded Python 3

File details

Details for the file lanyard-0.1.0.tar.gz.

File metadata

  • Download URL: lanyard-0.1.0.tar.gz
  • Upload date:
  • Size: 5.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for lanyard-0.1.0.tar.gz
Algorithm Hash digest
SHA256 7266f96ab2f0d0e236f68480c17a2fc03ff5fbacc4ecd96202b67559efd99661
MD5 96b7349cf5c6e65869c7d8856c08a357
BLAKE2b-256 b05be162d38d5fe81b03f7c9b9fd4cab19cb9ef34f7cf12a73a49c0dc025c696

See more details on using hashes here.

File details

Details for the file lanyard-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: lanyard-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 6.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for lanyard-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 bb4e538a9c66c53cdf18040a2c580edba09df3e6eef2fec1e81ddfbfa0c4d689
MD5 7c42c27edd84c25fc7335f126188a596
BLAKE2b-256 3be5fe2a98cc29bd3183a1fbb70066eef005a6185205450bd481d772b8b89b62

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page