feat(ai): encrypt MCP env and headers at rest and mask them in the admin API

env/headers are sealed into secretCipher with the BYOK AES-GCM/HKDF box.
The admin GET returns masked values; a mask posted back for the same
server and key keeps the stored value, any other mask is a 400. The chat
and the test button use the stored values. upgradeAiData seals plaintext
v1 rows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Lucas WintherandClaude Opus 5.5 committed 2026-10-30 20:33:56 +01:00
1 parent a995900fba
commit ddc66f5be5
8 files changed
+261 -12

No files matched your search

+1 -1
View File
@@ -157,7 +157,7 @@ export default function AdminAiPage() {
</div>
)}
{s.transport === "stdio" ? (
<Field label="Environment" hint="One NAME=value per line. The command gets only PATH, HOME, LANG and these; server secrets are never passed on.">
<Field label="Environment" hint="One NAME=value per line. The command gets only PATH, HOME, LANG and these; server secrets are never passed on. Values are stored encrypted and shown masked; leave a masked value as it is to keep it.">
<textarea className="ai-input ai-mono" rows={2} value={s.env} onChange={(e) => setServer(i, { env: e.target.value })} placeholder="API_TOKEN=…" />
</Field>
) : null}