Gittonがこだわるセキュリティ設計
OSキーチェーンによる暗号化、プラグインサンドボックス、CSPによるXSS対策など、Gittonが実装するセキュリティ機能をソースコードとともに解説します。

AIがコードを書く時代のセキュリティ
Gittonを開発するにあたり、セキュリティは最初から設計の中心に据えた。
AIコーディングツールを使う開発者にとって、Gitクライアントは開発フローの要だ。リポジトリの認証情報、APIキー、コードの差分。これらすべてがGitクライアントを通過する。だからこそ、セキュリティには妥協しない。
この記事では、Gittonが実装しているセキュリティ機能を、実際のソースコードとともに解説する。
1. OSキーチェーンによるAPIキーの暗号化
AIプロバイダーのAPIキーは、平文でファイルに保存すべきではない。Gittonでは、ElectronのsafeStorage APIを使って、OS固有のセキュアストレージに保存している。
// src/main/crypto.ts
import { safeStorage } from 'electron'
export function encryptString(plainText: string): string {
if (!plainText) return ''
if (!safeStorage.isEncryptionAvailable()) {
console.warn('Encryption is not available on this system')
return Buffer.from(plainText).toString('base64')
}
const encrypted = safeStorage.encryptString(plainText)
return encrypted.toString('base64')
}
macOSではKeychain、LinuxではlibSecret、WindowsではDPAPIが使われる。つまり、OSが提供する最も安全なストレージを利用している。
仮にGittonのデータベースファイルが流出しても、APIキーは暗号化されているため、そのままでは使えない。復号にはOSの認証が必要だ。
2. プラグインの権限システム
Gittonはプラグインで拡張できる。しかし、プラグインは潜在的なセキュリティリスクだ。悪意のあるプラグインがAPIキーを盗んだり、コードを外部に送信する可能性がある。
そこで、Androidアプリのようなパーミッションシステムを導入した。
// src/main/plugins/types.ts
export const PluginPermission = z.enum([
'ui:sidebar', // サイドバーにUIを追加
'ui:settings', // 設定タブを追加
'settings:read', // 設定の読み取り
'settings:write', // 設定の書き込み
'network:fetch', // HTTPリクエストの実行
'git:read', // リポジトリファイルの読み取り
'git:write', // リポジトリファイルの書き込み
'git:hooks' // Git hooksの管理
])
プラグインはpackage.jsonで必要な権限を宣言しなければならない。そして、新しくインストールされたプラグインはデフォルトで無効になる。
// src/main/plugins/manager.ts
// Register as a new plugin (disabled by default for security)
await queries.addPlugin({
id,
name: packageName,
// ...
enabled: false // セキュリティのためデフォルトは無効
})
ユーザーが明示的に有効化しない限り、プラグインは動作しない。権限を確認してから有効化できる。
さらに、プラグインのアップデートで権限が変更された場合も検知する。
// 権限の変更を検出
const permissionChanged = !this.arePermissionsEqual(
currentManifest.permissions,
dbManifest.permissions
)
権限に変更がない場合は自動アップデート、権限が増えた場合はユーザーの再承認が必要になる。
3. CSPによるプラグインのサンドボックス
プラグインのUIはiframe内で動作する。ここでContent Security Policy(CSP)を適用し、悪意のあるスクリプトの実行を防いでいる。
// src/main/plugins/ui-server.ts
function generateNonce(): string {
return crypto.randomBytes(16).toString('base64')
}
function buildCSPHeader(nonce: string): string {
const allowedDomains = pluginManager.getAllAllowedDomains()
// nonce-basedのCSPで、許可されたスクリプトのみ実行可能
const scriptSrc = ["'self'", `'nonce-${nonce}'`, ...allowedDomains.script].join(' ')
const connectSrc = ["'self'", 'https://api.github.com', ...allowedDomains.connect].join(' ')
return [
"default-src 'self'",
`script-src ${scriptSrc}`,
// ...
].join('; ')
}
ポイントはnonce-based CSPを使っていること。'unsafe-inline'は使わない。
各リクエストごとに一意のnonceを生成し、そのnonceを持つスクリプトのみ実行を許可する。これにより、XSS攻撃でインラインスクリプトを注入されても実行されない。
4. パストラバーサル対策
プラグインがファイルにアクセスする際、プラグインディレクトリ外へのアクセスを防止している。
// src/main/plugins/ui-server.ts
// Security: ensure file is within plugin directory
const resolvedPath = path.resolve(filePath)
const pluginRoot = path.resolve(plugin.path)
if (!resolvedPath.startsWith(pluginRoot)) {
res.writeHead(403, { 'Content-Type': 'text/plain' })
res.end('Access denied')
return
}
../../etc/passwdのようなパストラバーサル攻撃を試みても、プラグインディレクトリ外へのアクセスは403で拒否される。
5. contextBridgeによる安全なIPC
Electronアプリのセキュリティで最も重要なのが、メインプロセスとレンダラープロセス間の通信だ。Gittonでは、Electronが推奨するcontextBridge APIを使用している。
// src/preload/index.ts
import { contextBridge, ipcRenderer } from 'electron'
contextBridge.exposeInMainWorld('electronAPI', {
minimize: () => ipcRenderer.invoke('window:minimize'),
maximize: () => ipcRenderer.invoke('window:maximize'),
// ...
})
contextBridge.exposeInMainWorld('terminalAPI', {
create: (sessionId: string, cwd: string, shell?: string) =>
ipcRenderer.invoke('terminal:create', { sessionId, cwd, shell }),
// ...
})
直接ipcRendererをレンダラーに公開するのではなく、必要な機能だけをラップして公開している。これにより、レンダラープロセスが侵害されても、任意のIPCコールを実行することはできない。
6. AIコードレビューのセキュリティフォーカス
GittonのAIコードレビュー機能は、デフォルトでセキュリティ脆弱性の検出に焦点を当てている。
// src/main/ai/index.ts
export const DEFAULT_CODE_REVIEW_PROMPT = `You are an expert code reviewer...
## Focus areas:
- Security vulnerabilities (SQL injection, XSS, etc.)
- Potential bugs or logic errors
- Performance issues
- Missing error handling
- Resource leaks
- Race conditions
- Null/undefined safety
`
AIがコードを書く時代だからこそ、AIにセキュリティチェックをさせる。人間が見落としがちな脆弱性も、AIは見逃さない。
7. ローカルAI対応によるプライバシー保護
機密性の高いコードを外部APIに送信したくない場合もある。GittonはOllamaに対応しており、完全にローカルでAI機能を使用できる。
// src/main/ai/index.ts
case 'ollama': {
const ollama = createOllama({
baseURL: settings.ollamaBaseUrl || 'http://localhost:11434/api'
})
return ollama(modelName) as unknown as LanguageModel
}
Ollamaを使えば、コミットメッセージ生成もコードレビューも、すべてローカルで完結する。ネットワーク接続がなくても、AIによるセキュリティチェックが可能だ。
セキュリティは継続的な取り組み
これらのセキュリティ機能は、一度実装して終わりではない。
- 依存パッケージの脆弱性スキャン
- Electronのセキュリティアップデートの追従
- 新しい攻撃手法への対応
セキュリティは継続的な取り組みだ。Gittonは、開発者が安心して使えるツールであり続けるために、セキュリティを最優先に開発を続けていく。

