Skip to content

Documentation / @agentick/secrets

@agentick/secrets

Platform-native secret storage for Agentick agents. Stores credentials in the OS keychain on macOS and Linux, with env var fallback everywhere else.

Install

sh
pnpm add @agentick/secrets

Quick Start

typescript
import { createSecretStore } from "@agentick/secrets";

const secrets = await createSecretStore();

await secrets.set("telegram.token", "bot123:ABC-xyz");
const token = await secrets.get("telegram.token");

createSecretStore() auto-detects the best backend for the current platform.

How It Works

createSecretStore()
    |
    v
Platform detection
    |
    +-- macOS ------> Keychain (security CLI)
    +-- Linux ------> libsecret (secret-tool CLI)
    +-- Fallback ---> Environment variables

All keychain operations use execFile with argument arrays — no shell interpolation, no injection risk.

Backends

Keychain (macOS)

Stores secrets in the macOS Keychain via the security CLI. Secrets are encrypted at rest, protected by the login keychain, and accessible to Keychain Access.app.

typescript
import { createKeychainStore } from "@agentick/secrets";

const secrets = createKeychainStore({ service: "my-agent" });

The service parameter scopes secrets (default: "agentick"). A manifest key tracks all stored keys for list().

libsecret (Linux)

Stores secrets via secret-tool, the CLI for GNOME Keyring / KWallet. Requires libsecret and a running secret service.

typescript
import { createLibsecretStore } from "@agentick/secrets";

const secrets = createLibsecretStore({ service: "my-agent" });

list() uses secret-tool search natively — no manifest needed.

Environment Variables

Reads from process.env. Dot-path keys are normalized to UPPER_SNAKE_CASE.

typescript
import { createEnvStore } from "@agentick/secrets";

const secrets = createEnvStore({ prefix: "MYAGENT" });

// secrets.get("telegram.token") → process.env.MYAGENT_TELEGRAM_TOKEN

Without a prefix, keys map directly: telegram.tokenTELEGRAM_TOKEN.

Memory

In-memory Map. For testing.

typescript
import { createMemoryStore } from "@agentick/secrets";

const secrets = createMemoryStore({ "api.key": "test-value" });

Explicit Backend Selection

Override auto-detection when needed.

typescript
const secrets = await createSecretStore({ backend: "env", envPrefix: "MYAPP" });
const secrets = await createSecretStore({ backend: "keychain", service: "my-agent" });
const secrets = await createSecretStore({ backend: "memory" });

Use with Connectors

Pass a secret store to connectors instead of hardcoding tokens.

typescript
import { createSecretStore } from "@agentick/secrets";
import { TelegramPlatform } from "@agentick/connector-telegram";

const secrets = await createSecretStore();
const token = await secrets.get("telegram.token");

const platform = new TelegramPlatform({ token: token! });

SecretStore Interface

Defined in @agentick/shared so any package can accept it as a dependency.

typescript
interface SecretStore {
  get(key: string): Promise<string | null>;
  set(key: string, value: string): Promise<void>;
  delete(key: string): Promise<boolean>;
  has(key: string): Promise<boolean>;
  list(): Promise<string[]>;
  readonly backend: string;
}

Exports

typescript
// Factory (auto-detects backend)
export { createSecretStore } from "./create-secret-store.js";
export type { CreateSecretStoreOptions, SecretStoreBackend } from "./create-secret-store.js";

// Backends
export { createKeychainStore } from "./keychain-store.js";
export { createLibsecretStore } from "./libsecret-store.js";
export { createEnvStore } from "./env-store.js";
export { createMemoryStore } from "./memory-store.js";
export type { KeychainStoreOptions } from "./keychain-store.js";
export type { LibsecretStoreOptions } from "./libsecret-store.js";
export type { EnvStoreOptions } from "./env-store.js";

// Interface (re-exported from @agentick/shared)
export type { SecretStore } from "@agentick/shared";

Interfaces

Type Aliases

Functions

Released under the ISC License.