SecretStorage provides a secure way to store and manage sensitive data like API keys and tokens in Obsidian plugins. Instead of storing secrets directly in your plugin's `data.json` file, SecretStorage offers a centralized key-value store that allows users to share secrets across multiple plugins. In this guide, you'll learn how to use SecretStorage and SecretComponent to securely handle secrets in your plugin settings. ## What you'll learn After you've completed this guide, you'll be able to: - Replace direct secret input with the SecretComponent. - Retrieve stored secrets using the SecretStorage API. - Understand why SecretStorage improves security and user experience. ## Before you start This guide assumes you're familiar with creating plugin settings in Obsidian. If you haven't already, read [[Settings]] to understand how to create a settings tab and save plugin configuration. ## Why use SecretStorage? When plugins store secrets directly in `data.json`, several problems arise: - **Security**: Secrets are stored in plaintext alongside other plugin data. - **Duplication**: Users must copy the same API key into every plugin that needs it. - **Maintenance**: If a token changes, users must update every plugin manually. SecretStorage addresses these issues by providing a central store for secrets. Users save each secret with a name, and any plugin can reference it by that name. [](/en/Assets/settings-secret-list.png) ## Step 1: Update your settings interface Start with a typical plugin settings setup. The `mySetting` property will store the *name* of a secret, not the secret value itself. ```ts import { App, PluginSettingTab, Setting } from "obsidian"; import MyPlugin from "./main"; export interface MyPluginSettings { mySetting: string; } ``` ## Step 2: Add the SecretComponent to your settings tab Replace the standard text input with a `SecretComponent`. Import `SecretComponent` from `obsidian` and use the `addComponent` method on your `Setting`: ```ts import { App, PluginSettingTab, SecretComponent, Setting } from "obsidian"; import MyPlugin from "./main"; export class SampleSettingTab extends PluginSettingTab { plugin: MyPlugin; constructor(app: App, plugin: MyPlugin) { super(app, plugin); this.plugin = plugin; } display(): void { const { containerEl } = this; containerEl.empty(); new Setting(containerEl) .setName('API key') .setDesc('Select a secret from SecretStorage') .addComponent(el => new SecretComponent(this.app, el) .setValue(this.plugin.settings.mySetting) .onChange(value => { this.plugin.settings.mySetting = value; this.plugin.saveSettings(); })); } } ``` The `SecretComponent` presents users with an interface to select from existing secrets or create a new one. When saved, your plugin settings contain the *name* of the secret, not the actual secret value. [](/en/Assets/settings-secretcomponent.png) ## Step 3: Retrieve the secret value When your plugin needs the actual secret value, use the `SecretStorage` API: ```ts const secret = app.secretStorage.get(this.settings.mySetting); if (secret) { // secret value might be null } ``` This retrieves the secret value associated with the name stored in your settings. The actual secret is stored in local storage, keyed to the specific vault. ## Complete example Here's the full settings tab implementation: ```ts import { App, PluginSettingTab, SecretComponent, Setting } from "obsidian"; import MyPlugin from "./main"; export interface MyPluginSettings { mySetting: string; } export class SampleSettingTab extends PluginSettingTab { plugin: MyPlugin; constructor(app: App, plugin: MyPlugin) { super(app, plugin); this.plugin = plugin; } display(): void { const { containerEl } = this; containerEl.empty(); new Setting(containerEl) .setName('API key') .setDesc('Select a secret from SecretStorage') .addComponent(el => new SecretComponent(this.app, el) .setValue(this.plugin.settings.mySetting) .onChange(value => { this.plugin.settings.mySetting = value; this.plugin.saveSettings(); })); } } ``` ## FAQ ### Why does SecretComponent use `addComponent` instead of having its own method like `addText`? Unlike other setting components, `SecretComponent` requires the `App` instance in its constructor to access the SecretStorage API. The standard `addText`, `addToggle`, and similar methods don't pass `App` to their callbacks. The `Setting#addComponent` method gives you full control over component instantiation, allowing you to pass the required `App` reference.