MCP 서버의 API 키를 안전하게 보호하는 방법 (작동 데모 포함)

발행: (2026년 2월 16일 오전 03:07 GMT+9)
5 분 소요
원문: Dev.to

Source: Dev.to

모든 MCP 개발자가 무시하는 문제

MCP 서버를 구축합니다. GitHub 토큰이 필요합니다. 혹은 OpenAI 키가 필요할 수도 있죠. 이들은 어디에 두나요?

{
  "mcpServers": {
    "my-server": {
      "command": "node",
      "args": ["server.js"],
      "env": {
        "GITHUB_TOKEN": "ghp_XXXXXXXXXXXX",
        "OPENAI_API_KEY": "sk-XXXXXXXXXXXX"
      }
    }
  }
}

평문으로. JSON 파일에. 디스크에. git에 커밋될 수도 있습니다.

대부분의 MCP 서버가 오늘날 비밀을 다루는 방식입니다. 그리고 이는 시한폭탄과 같습니다.

더 나은 방법: 암호화된 볼트 + 런타임 복호화

저는 이를 다르게 처리하는 데모 MCP 서버를 만들었습니다. 환경 변수에서 비밀을 읽는 대신, Janee — MCP 서버용으로 설계된 암호화된 볼트 — 에서 가져옵니다.

흐름:

flowchart LR
    A[Claude Desktop] --> B[MCP Protocol] --> C[Your Server] --> D[Janee Vault] --> E[API Call]
    D -->|AES-256-GCM encrypted| C

디스크에 평문 비밀이 전혀 없습니다. 절대.

직접 해보기 (5분)

git clone https://github.com/lucamorettibuilds/janee-mcp-demo
cd janee-mcp-demo
npm install

# 암호화된 볼트 설정
npx janee init          # 암호화된 볼트 생성
npx janee add github    # GitHub 토큰을 저장 (암호화)
npx janee add openai    # OpenAI 키를 저장 (암호화)

# 실행
export JANEE_MASTER_PASSWORD="your-password"
npm start

서버는 세 가지 MCP 도구를 제공합니다:

  • github_create_issue — 볼트 자격 증명을 사용해 GitHub 이슈 생성
  • openai_complete — 볼트 자격 증명을 사용해 OpenAI 호출
  • list_secrets — 볼트에 무엇이 들어 있는지 표시 (이름만, 값은 절대 표시되지 않음)

코드 작동 방식

비밀을 다루는 핵심은 작은 통합 레이어(src/secrets.js)입니다:

import { execSync } from "child_process";

export async function getSecret(service, field) {
  try {
    const result = execSync(
      `npx janee get ${service} ${field} 2>/dev/null`,
      { encoding: "utf-8", env: { ...process.env } }
    ).trim();
    return result || null;
  } catch {
    return null;
  }
}

그 다음 MCP 도구 핸들러에서 process.env.GITHUB_TOKEN 대신:

const token = await getSecret("github", "token");

비밀은 런타임에 볼트에서 복호화되어 API 호출에 사용되고, 필요 이상으로 메모리에 남지 않습니다.

Claude Desktop 설정

{
  "mcpServers": {
    "janee-demo": {
      "command": "node",
      "args": ["/path/to/janee-mcp-demo/src/server.js"],
      "env": {
        "JANEE_MASTER_PASSWORD": "your-master-password"
      }
    }
  }
}

하나의 비밀번호가 모든 API 키를 보호합니다. 더 이상 흩어진 env 변수가 없습니다.

.env 파일을 사용하지 않나요?

기능.env 파일Janee 볼트
저장 방식평문AES‑256‑GCM 암호화
접근 제어없음세션 기반, TTL 지원
회전수동 찾기‑바꾸기janee add service (덮어쓰기)
감사없음내장 로깅
Git 안전성.gitignore 규칙 필요볼트 파일을 커밋해도 안전

직접 서비스 추가하기

데모에는 GitHub와 OpenAI가 포함되어 있지만, 원하는 어떤 서비스든 추가할 수 있습니다:

npx janee add stripe
npx janee add anthropic
npx janee add postgres

그런 다음 도구 핸들러에서 getSecret("stripe", "api_key") 를 사용하면 됩니다.

코드 받기

  • 데모 레포:
  • Janee (비밀 관리자):
  • MCP 사양:

MCP 서버를 구축한다면 비밀에 충분한 존중을 주세요. ⭐ 유용하다면 Janee에 ⭐를 주세요.

0 조회
Back to Blog

관련 글

더 보기 »