> ## Documentation Index
> Fetch the complete documentation index at: https://docs-code.palyra.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Vault, Secrets, and Identity

<details>
  <summary>Relevant source files</summary>

  The following files were used as context for generating this wiki page:

  * crates/palyra-auth/src/constants.rs
  * crates/palyra-auth/src/error.rs
  * crates/palyra-auth/src/lib.rs
  * crates/palyra-auth/src/models.rs
  * crates/palyra-auth/src/refresh.rs
  * crates/palyra-auth/src/registry.rs
  * crates/palyra-auth/src/storage.rs
  * crates/palyra-auth/src/tests.rs
  * crates/palyra-auth/src/validation.rs
  * crates/palyra-browserd/src/persistence/state\_store.rs
  * crates/palyra-cli/src/args/secrets.rs
  * crates/palyra-cli/src/commands/pairing.rs
  * crates/palyra-cli/src/commands/secrets.rs
  * crates/palyra-cli/tests/help\_snapshots/secrets-help.txt
  * crates/palyra-cli/tests/secrets\_cli.rs
  * crates/palyra-daemon/src/transport/http/handlers/console/config.rs
  * crates/palyra-identity/benches/pairing\_handshake.rs
  * crates/palyra-identity/src/ca.rs
  * crates/palyra-identity/src/device.rs
  * crates/palyra-identity/src/error.rs
  * crates/palyra-identity/src/lib.rs
  * crates/palyra-identity/src/mtls.rs
  * crates/palyra-identity/src/pairing/handshake.rs
  * crates/palyra-identity/src/pairing/helpers.rs
  * crates/palyra-identity/src/pairing/mod.rs
  * crates/palyra-identity/src/pairing/models.rs
  * crates/palyra-identity/src/pairing/persistence.rs
  * crates/palyra-identity/src/pairing/revocation.rs
  * crates/palyra-identity/src/pairing/tests.rs
  * crates/palyra-identity/src/store.rs
  * crates/palyra-identity/tests/mtls\_pairing\_flow\.rs
  * crates/palyra-vault/Cargo.toml
  * crates/palyra-vault/src/api.rs
  * crates/palyra-vault/src/backend.rs
  * crates/palyra-vault/src/crypto.rs
  * crates/palyra-vault/src/envelope.rs
  * crates/palyra-vault/src/filesystem.rs
  * crates/palyra-vault/src/lib.rs
  * crates/palyra-vault/src/metadata.rs
  * crates/palyra-vault/src/scope.rs
  * crates/palyra-vault/src/secret\_resolver.rs
  * crates/palyra-vault/src/tests.rs
</details>

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](http://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](http://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](http://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](http://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](http://crates/palyra-vault/src/backend.rs#4-6):

| Backend Kind         | Platform | Implementation                                                                                                                                      |
| :------------------- | :------- | :-------------------------------------------------------------------------------------------------------------------------------------------------- |
| `MacosKeychain`      | macOS    | Uses the `security` command-line tool [crates/palyra-vault/src/backend.rs#60-60](http://crates/palyra-vault/src/backend.rs#60-60).                  |
| `LinuxSecretService` | Linux    | Uses `secret-tool` (freedesktop.org Secret Service) [crates/palyra-vault/src/backend.rs#63-63](http://crates/palyra-vault/src/backend.rs#63-63).    |
| `WindowsDpapi`       | Windows  | Uses DPAPI-protected files [crates/palyra-vault/src/backend.rs#66-66](http://crates/palyra-vault/src/backend.rs#66-66).                             |
| `EncryptedFile`      | All      | Portable JSON object store with owner-only permissions [crates/palyra-vault/src/backend.rs#57-57](http://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](http://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](http://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](http://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](http://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

```mermaid theme={null}
graph TD
    subgraph "Code Entity Space"
        A["SecretRef"] --> B["SecretResolver::resolve()"]
        B --> C{"Source Kind?"}
        C -- "vault" --> D["Vault::get_secret()"]
        C -- "env" --> E["std::env::var()"]
        C -- "file" --> F["std::fs::read()"]
        C -- "exec" --> G["std::process::Command"]

        D --> H["BlobBackend::get_blob()"]
        H --> I["envelope::open()"]
        I --> J["SensitiveBytes"]
        E --> J
        F --> J
        G --> J
    end

    subgraph "Natural Language Space"
        J --> K["Exposure-controlled Memory"]
        B --> L["Redacted Metadata"]
    end
```

Sources: [crates/palyra-vault/src/secret\_resolver.rs#32-44](http://crates/palyra-vault/src/secret_resolver.rs#32-44), [crates/palyra-vault/src/api.rs#151-158](http://crates/palyra-vault/src/api.rs#151-158), [crates/palyra-vault/src/backend.rs#116-125](http://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](http://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](http://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](http://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](http://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](http://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](http://crates/palyra-cli/src/commands/pairing.rs#108-115).

### Certificate Rotation and Revocation

* **Rotation**: Certificates have a defined validity period (`DEFAULT_CERT_VALIDITY`) and are automatically rotated by the `IdentityManager` [crates/palyra-identity/src/pairing/mod.rs#9-10](http://crates/palyra-identity/src/pairing/mod.rs#9-10).
* **Revocation**: The system supports node revocation, which invalidates the node's identity and prevents future mTLS connections [crates/palyra-identity/src/pairing/revocation.rs#1-5](http://crates/palyra-identity/src/pairing/revocation.rs#1-5).

Title: Identity Pairing and mTLS Setup

```mermaid theme={null}
graph LR
    subgraph "palyra-identity Crate"
        CA["CertificateAuthority"]
        IM["IdentityManager"]
        SS["FilesystemSecretStore"]
    end

    subgraph "Handshake Protocol"
        CODE["NodePairingCode"]
        REQ["NodePairingRequest"]
        DEC["NodePairingDecision"]
    end

    IM --> CA
    CA --> SS
    REQ --> IM
    IM -- "sign_node_certificate()" --> REQ
    DEC -- "Approve/Reject" --> IM
```

Sources: [crates/palyra-identity/src/ca.rs#1-10](http://crates/palyra-identity/src/ca.rs#1-10), [crates/palyra-identity/src/store.rs#127-143](http://crates/palyra-identity/src/store.rs#127-143), [crates/palyra-cli/src/commands/pairing.rs#25-37](http://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](http://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](http://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](http://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](http://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](http://crates/palyra-auth/src/refresh.rs#1-5):

* **Heuristics**: `should_attempt_oauth_refresh` determines if a token is nearing expiry [crates/palyra-auth/src/registry.rs#31-36](http://crates/palyra-auth/src/registry.rs#31-36).
* **Adapter**: `HttpOAuthRefreshAdapter` performs the network request to the provider's token endpoint [crates/palyra-auth/src/refresh.rs#27-30](http://crates/palyra-auth/src/refresh.rs#27-30).
* **Persistence**: New access tokens are written back to the `Vault`, and expiry metadata is updated in the `RuntimeStateDocument` [crates/palyra-auth/src/registry.rs#3-5](http://crates/palyra-auth/src/registry.rs#3-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](http://crates/palyra-auth/src/models.rs#17-25). It filters candidates based on:

* **Eligibility**: Checks if the profile is enabled and matches the requested scope [crates/palyra-auth/src/models.rs#19-19](http://crates/palyra-auth/src/models.rs#19-19).
* **Health**: Evaluates `AuthProfileHealthRecord` to skip profiles with recent circuit-breaker trips or transport failures [crates/palyra-auth/src/models.rs#21-21](http://crates/palyra-auth/src/models.rs#21-21).

| Entity                   | Role                                       | Source                                                                                  |
| :----------------------- | :----------------------------------------- | :-------------------------------------------------------------------------------------- |
| `AuthProfileRecord`      | Static config (ID, Name, Scope)            | [crates/palyra-auth/src/models.rs#26-26](http://crates/palyra-auth/src/models.rs#26-26) |
| `AuthCredential`         | Reference to Vault keys (API Key, OAuth)   | [crates/palyra-auth/src/models.rs#18-18](http://crates/palyra-auth/src/models.rs#18-18) |
| `AuthProfileHealthState` | Current status (Healthy, Degraded, Failed) | [crates/palyra-auth/src/models.rs#20-20](http://crates/palyra-auth/src/models.rs#20-20) |
| `AuthTokenExpiryState`   | Tracks when tokens need refresh            | [crates/palyra-auth/src/models.rs#24-24](http://crates/palyra-auth/src/models.rs#24-24) |

Sources: [crates/palyra-auth/src/registry.rs#1-6](http://crates/palyra-auth/src/registry.rs#1-6), [crates/palyra-auth/src/models.rs#17-30](http://crates/palyra-auth/src/models.rs#17-30), [crates/palyra-auth/src/refresh.rs#27-36](http://crates/palyra-auth/src/refresh.rs#27-36)
