Files
Shutong Wu e728c35adb feat(asset-gen): SecureKeyStore — theft-resistant at-rest key storage (Phase 1)
OS secure store per platform: macOS Keychain (/usr/bin/security), Windows Credential
Manager (advapi32 P/Invoke), Linux secret-tool; AES-256-CBC+HMAC encrypt-then-MAC
fallback (CI-safe, master secret + machine id via PBKDF2, ciphertext under user
app-data, never in repo). Env override (MCPFORUNITY_<P>_API_KEY, read-only) layered on
top; SecretRedactor scrubs auth tokens. Keys never touch EditorPrefs/bridge/logs/git.
EditMode tests for fallback round-trip, encryption-at-rest, env override, redaction.
Compiles clean on Unity 2021.3.45f2 (floor).

Claude-Session: https://claude.ai/code/session_01Tjpb5gYgUe2AUJuRdXr7Lv
2026-06-28 19:25:20 -07:00

26 lines
1.1 KiB
C#

namespace MCPForUnity.Editor.Security
{
/// <summary>
/// At-rest storage for AI asset-generation provider API keys.
///
/// Keys are written ONLY to the OS secure store (Keychain / Credential Manager /
/// libsecret) or an encrypted-file fallback. They are never placed in EditorPrefs,
/// never sent over the MCP bridge, never returned by any MCP tool, and never logged.
/// <see cref="Has"/> reports existence only — there is no API that returns all keys.
/// </summary>
public interface ISecureKeyStore
{
/// <summary>Resolve the key for a provider id (e.g. "tripo"). Returns false when absent.</summary>
bool TryGet(string providerId, out string apiKey);
/// <summary>Store (or overwrite) the key for a provider id. Empty/null deletes it.</summary>
void Set(string providerId, string apiKey);
/// <summary>Remove the stored key for a provider id (no-op when absent).</summary>
void Delete(string providerId);
/// <summary>True when a key exists for the provider id. Never returns the value.</summary>
bool Has(string providerId);
}
}