## 経緯
`data.json` に秘密情報を書くのは危険すぎるので、もっと安全に管理したい。
## 前提条件
- [[Obsidian]] および [[Obsidian]]プラグイン はtrusted とする
- **[[Obsidian]]の仕様上、これはどうしようもないので受け入れるしかない**
- [[Obsidian]]以外のアプリケーションから取得されるリスクを下げる
## 安全ではない[[Keychain]]利用方法
[[Keychain]]から取得はできるものの
- GUIでのパスワード認証が必要
- これ自体はsecureでよい... が
- 毎回確認するのは非現実的
- **オンメモリに乗せればギリギリ許容できそう**
- **[[Obsidianプラグイン]]で使う時だけパスワード入力すれば、他に疑わしいプラグインがあっても防げるのはこの方法だけな気がする**
- 許可してしまうと `セキュリティ(security)` 全体が許可されてしまい、**[[Obsidian]]以外からもアクセス可能** になってしまう
- これは本末転倒
コードは以下。
```ts
import { execFile } from "child_process";
async function readKeychain(service: string, account: string): Promise<string> {
return new Promise((resolve, reject) => {
execFile(
"/usr/bin/security",
["find-generic-password", "-a", account, "-s", service, "-w"],
{ timeout: 30 * 1000, windowsHide: true },
(err, stdout) => {
if (err) return reject(new Error("Keychain read failed"));
resolve(stdout.replace(/\s+$/, "")); // 末尾改行除去
},
);
});
}
async function readKeychainObsidian(
key: string,
): Promise<{ value: string; error: null } | { value: null; error: string }> {
try {
const value = await readKeychain("net.mamansoft.Obsidian.Carnelian", key);
return { value, error: null };
} catch (e: any) {
return { value: null, error: e.message };
}
}
```
## ベストな方法
[[Keychain]]で[[Obsidian]]だけ確認なしで利用できるようにするのがよさそう。
ただ、ちゃんとやるには[[Obsidian]]の[[Electron]]バイナリに対して署名が必要でありしんどそう。クリティカルな認証情報ではないためそこまではしたくない。
## 妥協案
環境変数名を設定で指定可能にし、[[Obsidian]]起動時のみ環境変数を有効にする方法。デメリットは以下。
- wrapperを自前で用意する必要がある
- wrapperを参照されたら意味がない
- これをいい始めると何をしても駄目になってしまう気がする...
## 結局のところ
- [[Keychain]]を使う
- [[Obsidian]]起動後に使うときだけパスワードを尋ねる
- 再起動とかは融通きかせたい気もするが... 今はいい
- [[Keychain]]への登録は以下のコマンドで
```
security add-generic-password \
-s net.mamansoft.Obsidian.Carnelian \
-a <設定のキー名> \
-w <秘密情報>
```