Skip to main content
This section describes the security infrastructure of Palyra, focusing on the palyra-vault crate for secret management, the palyra-identity crate for device trust and mTLS, and the palyra-auth crate for managing authenticated service profiles.

Vault and Secret Management

The palyra-vault crate provides a scoped, encrypted storage system for sensitive material such as API keys, tokens, and browser state keys crates/palyra-vault/src/lib.rs#1-7. It utilizes envelope encryption to ensure that secrets are never stored in plaintext on disk or in system keystores.

Envelope Encryption and Backends

The vault seals secrets using a device-bound Key Encryption Key (KEK) derived from the palyra-identity CA key crates/palyra-vault/src/lib.rs#3-5. Secrets are stored as sealed envelopes containing ciphertext and authenticated additional data (AAD) crates/palyra-vault/src/lib.rs#9-16. The BlobBackend trait abstracts the physical storage of these envelopes crates/palyra-vault/src/backend.rs#116-125. The system supports several backends, pinning the choice in a backend.kind marker file to prevent silent switching crates/palyra-vault/src/backend.rs#4-6:
Backend KindPlatformImplementation
MacosKeychainmacOSUses the security command-line tool crates/palyra-vault/src/backend.rs#60-60.
LinuxSecretServiceLinuxUses secret-tool (freedesktop.org Secret Service) crates/palyra-vault/src/backend.rs#63-63.
WindowsDpapiWindowsUses DPAPI-protected files crates/palyra-vault/src/backend.rs#66-66.
EncryptedFileAllPortable JSON object store with owner-only permissions crates/palyra-vault/src/backend.rs#57-57.

VaultScope and Referencing

Secrets are partitioned by VaultScope, which prevents cross-component access crates/palyra-vault/src/scope.rs#25-25. Supported scopes include:
  • global: Shared across the entire installation crates/palyra-cli/src/args/secrets.rs#9-9.
  • principal:<id>: Specific to a user/identity.
  • channel:<name>:<account_id>: Specific to a communication platform account.
  • skill:<skill_id>: Specific to a Wasm plugin or skill.

SecretResolver

The SecretResolver is responsible for dereferencing SecretRef objects into SensitiveBytes crates/palyra-vault/src/secret_resolver.rs#1-5. It supports multiple sources:
  1. Vault: Retrieves from the local encrypted vault.
  2. Env: Reads from environment variables (subject to allowlisting).
  3. File: Reads from the filesystem (enforcing trusted-directory and symlink checks).
  4. Exec: Executes a command to obtain the secret (with strict timeouts) crates/palyra-vault/src/secret_resolver.rs#26-29.

Data Flow: Secret Resolution

The following diagram illustrates how a component (like a Model Provider) resolves a secret reference through the SecretResolver. Title: Secret Resolution Flow Sources: crates/palyra-vault/src/secret_resolver.rs#32-44, crates/palyra-vault/src/api.rs#151-158, crates/palyra-vault/src/backend.rs#116-125

Identity and mTLS

The palyra-identity crate manages the device Certificate Authority (CA), mTLS certificates, and the pairing handshake protocol crates/palyra-identity/src/lib.rs#1-10.

Device CA and Store

Every Palyra node initializes a local CA. The state is stored in a SecretStore, typically the FilesystemSecretStore which encrypts payloads with ChaCha20-Poly1305 crates/palyra-identity/src/store.rs#3-5. On Windows, the store encryption key is DPAPI-wrapped crates/palyra-identity/src/store.rs#9-14.

Pairing Handshake

Pairing is the process of establishing trust between two nodes (e.g., a CLI and a Daemon).
  1. Minting: An admin node generates a NodePairingCode crates/palyra-cli/src/commands/pairing.rs#83-89.
  2. Request: The joining node submits a NodePairingRequest using the code as proof crates/palyra-cli/src/commands/pairing.rs#69-72.
  3. Approval: An admin approves the request, causing the CA to sign a certificate for the new node crates/palyra-cli/src/commands/pairing.rs#108-115.

Certificate Rotation and Revocation

Title: Identity Pairing and mTLS Setup Sources: crates/palyra-identity/src/ca.rs#1-10, crates/palyra-identity/src/store.rs#127-143, crates/palyra-cli/src/commands/pairing.rs#25-37

Auth Profile Registry

The palyra-auth crate manages service-specific credentials (e.g., OpenAI, Anthropic) without storing secrets directly in the registry crates/palyra-auth/src/lib.rs#1-6.

Registry and Runtime State

The AuthProfileRegistry persists two documents as TOML under the daemon state root crates/palyra-auth/src/registry.rs#52-58:
  1. Registry Document: Contains static configuration like profile_id, provider_kind, and vault_references for credentials crates/palyra-auth/src/registry.rs#78-89.
  2. Runtime State Document: Tracks dynamic data such as token expiry, health records, and OAuth refresh states crates/palyra-auth/src/registry.rs#94-106.

OAuth Refresh Pipeline

For OAuth-based profiles, the registry manages the refresh lifecycle crates/palyra-auth/src/refresh.rs#1-5:

Profile Selection and Health

The registry provides an AuthProfileSelectionRequest API used by the daemon’s model router crates/palyra-auth/src/models.rs#17-25. It filters candidates based on:
EntityRoleSource
AuthProfileRecordStatic config (ID, Name, Scope)crates/palyra-auth/src/models.rs#26-26
AuthCredentialReference to Vault keys (API Key, OAuth)crates/palyra-auth/src/models.rs#18-18
AuthProfileHealthStateCurrent status (Healthy, Degraded, Failed)crates/palyra-auth/src/models.rs#20-20
AuthTokenExpiryStateTracks when tokens need refreshcrates/palyra-auth/src/models.rs#24-24
Sources: crates/palyra-auth/src/registry.rs#1-6, crates/palyra-auth/src/models.rs#17-30, crates/palyra-auth/src/refresh.rs#27-36