Skip to content

Secret Management

Chazona Baum edited this page Jun 24, 2026 · 1 revision

Relevant source files

The secrets.rs module provides a secure bridge between the Lodestar application and the host operating system's native keychain. Unlike application data, which is stored in the user's Obsidian vault, sensitive credentials (API keys) are never written to disk in plaintext.

Overview

Lodestar utilizes the keyring crate with apple-native features to manage secrets src-tauri/Cargo.toml#28 The system is designed with a "write-only" philosophy for the frontend: the UI can set secrets and check for their existence, but it can never read a secret's value back src-tauri/src/secrets.rs#1-3

Whitelisted Keys

Only specific keys defined in the SECRET_KEYS whitelist are permitted. Any attempt to access or set a key outside this list results in an error src-tauri/src/secrets.rs#28-34

Key Purpose
scrapingbee_api_key Used by the ScrapingBeeScraper for job discovery and JD fetching.
openrouter_api_key Used by the OpenRouterLlm for structured data extraction and scoring.

Sources:src-tauri/src/secrets.rs#15src/lib/secrets.ts#5-8

Implementation Architecture

The module addresses a critical UX challenge on macOS: repeated authorization prompts. By default, accessing the keychain for decryption triggers a system dialog. Lodestar minimizes this through two mechanisms:

  1. In-Memory Caching: A OnceLock protected HashMap caches values after the first successful decryption src-tauri/src/secrets.rs#20-25
  2. Silent Existence Checks: The is_present check uses metadata queries that do not require decryption, avoiding prompts src-tauri/src/secrets.rs#9-11

Data Flow: Secret Resolution

This diagram illustrates how a pipeline step (e.g., LLM call) resolves an API key.

flowchart TD
    H["Return Value"]
    I["Update Cache"]
    subgraph subGraph1 ["Natural Language Space"]
        E["In-Memory Cache Check"]
        F["OS Keychain Access"]
        G["Authorization Prompt (macOS)"]
    end
    subgraph subGraph0 ["Code Entity Space"]
        A["get_secret(key)"]
        B["cache() OnceLock"]
        C["entry(key) keyring::Entry"]
        D["keyring::Entry::get_password()"]
    end
    A --> E
    E --> B
    B --> H
    B --> F
    F --> C
    C --> D
    D -.-> G
    D --> I
    I --> H
Loading

Sources:src-tauri/src/secrets.rs#49-57src-tauri/src/secrets.rs#22-25

Key Functions and Commands

Backend API

  • set_secret_value(key, value): Validates the key against the whitelist, writes to the OS keychain, and updates the in-memory cache src-tauri/src/secrets.rs#40-45
  • get_secret(key): Retrieves a secret for internal use by scrapers or LLM clients. It checks the cache() first before hitting the keychain src-tauri/src/secrets.rs#49-57
  • is_present(key): Returns a boolean indicating if a secret exists. It uses a fast-path cache check before calling is_present_uncachedsrc-tauri/src/secrets.rs#66-74

Tauri IPC Commands

These functions are exposed to the SvelteKit frontend:

Sources:src-tauri/src/secrets.rs#111-119src/lib/secrets.ts#11-18

Platform-Specific Implementation

Lodestar uses conditional compilation (cfg branches) to optimize behavior across platforms and during testing.

macOS Production Path

In production builds on macOS, is_present_uncached utilizes the security-framework crate to perform a SecItemCopyMatching search src-tauri/src/secrets.rs#84-98

  • Attributes: kSecClassGenericPassword, kSecAttrService, and kSecAttrAccount.
  • Optimization: It explicitly omits kSecReturnData. This allows the OS to confirm the item exists without needing to decrypt the payload, thus bypassing the user authorization prompt src-tauri/src/secrets.rs#78-80

Fallback & Test Path

For non-macOS platforms or during test execution, the system falls back to a standard keyring lookup src-tauri/src/secrets.rs#102-109

flowchart LR
    F["Silent Success/Fail"]
    G["Success/Fail"]
    subgraph subGraph1 ["Platform Branches"]
        D["target_os = 'macos' AND NOT test"]
        E["NOT target_os = 'macos' OR test"]
    end
    subgraph subGraph0 ["Code Entity Space"]
        A["is_present_uncached(k)"]
        B["security_framework::item::ItemSearchOptions"]
        C["keyring::Entry::get_password()"]
    end
    A --> D
    D --> B
    B --> F
    A --> E
    E --> C
    C --> G
Loading

Sources:src-tauri/src/secrets.rs#84-109src-tauri/Cargo.toml#36-37

Testing Infrastructure

The module includes a comprehensive test suite using a mock keychain to ensure secrets are handled correctly without interacting with the developer's actual OS keychain.

Sources:src-tauri/src/secrets.rs#121-150

Clone this wiki locally