0Pricing
AI Engineering Academy · Pelajaran

Keamanan dan Autentikasi MCP

Tambahkan autentikasi ke server MCP menggunakan token OAuth 2.0, terapkan validasi masukan untuk mencegah serangan injeksi, dan gunakan prinsip hak akses minimum pada izin alat.

Keamanan dan Autentikasi MCP adalah pelajaran AI Engineering Academy gratis di CoddyKit. Ini adalah pelajaran 4 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar AI Engineering Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus AI Engineering Academy mencakup 4 pelajaran total.

Mengapa Keamanan MCP Penting

Server MCP adalah gerbang menuju sistem Anda. Tanpa keamanan yang tepat, klien AI yang telah disusupi atau perintah berbahaya dapat membaca data sensitif, memicu operasi yang merusak, atau mengeksfiltrasi informasi melalui kanal pemanggilan alat. Keamanan untuk server MCP harus menerapkan pertahanan berlapis: autentikasi pada lapisan transportasi, otorisasi pada tingkat alat, dan validasi input pada setiap pemanggilan.

Keamanan Server Lokal vs. Jarak Jauh

Transportasi stdio yang digunakan oleh Claude Desktop memiliki keamanan bawaan: server berjalan sebagai proses lokal dan hanya dapat diakses oleh pengguna yang menjalankannya. Server MCP yang terekspos melalui jaringan menggunakan HTTP/SSE menghadapi seluruh ragam ancaman keamanan web: pengelakan autentikasi, serangan injeksi, dan akses tanpa izin. Persyaratan keamanan sangat berbeda bergantung pada mode penerapan.

  • stdio lokal: Percayai pengguna lokal; fokus pada validasi input
  • HTTP/SSE jarak jauh: Autentikasi lengkap, TLS, pembatasan laju, sanitasi input

Autentikasi Kunci API untuk Server Jarak Jauh

Autentikasi paling sederhana untuk server MCP jarak jauh adalah validasi kunci API melalui header HTTP. Periksa header Authorization: Bearer <token> pada setiap permintaan masuk dan tolak permintaan yang tidak terautentikasi dengan HTTP 401. Simpan kunci API yang valid dalam basis data bersama metadata pengguna agar Anda dapat mencabut kunci secara individual.

# For HTTP/SSE MCP servers using FastAPI or similar:
from fastapi import FastAPI, HTTPException, Depends, Header
from typing import Optional
import secrets

app_http = FastAPI()

# In production: store in database with user_id, created_at, last_used
VALID_KEYS = {'sk-mcp-abc123': {'user': 'alice', 'scopes': ['read']},
              'sk-mcp-def456': {'user': 'bob', 'scopes': ['read', 'write']}}

async def verify_api_key(authorization: Optional[str] = Header(None)) -> dict:
    if not authorization or not authorization.startswith('Bearer '):
        raise HTTPException(status_code=401, detail='Missing API key')
    key = authorization.removeprefix('Bearer ')
    if key not in VALID_KEYS:
        raise HTTPException(status_code=401, detail='Invalid API key')
    return VALID_KEYS[key]  # Returns user context

# Use in route handlers:
# @app_http.get('/sse')
# async def sse_endpoint(user=Depends(verify_api_key)):

OAuth 2.0 untuk Server MCP Perusahaan

Untuk penerapan di perusahaan, gunakan OAuth 2.0 agar pengguna melakukan autentikasi dengan penyedia identitas perusahaan mereka (Okta, Azure AD, Google Workspace). Klien MCP memperoleh token akses OAuth dan menyertakannya dalam permintaan pemanggilan alat. Server Anda memvalidasi tanda tangan token terhadap kunci publik penyedia identitas menggunakan python-jose atau authlib.

from jose import jwt, JWTError
import httpx

AUTH_DOMAIN = 'your-tenant.auth0.com'
AUDIENCE = 'https://api.your-mcp-server.com'

async def get_jwks():
    async with httpx.AsyncClient() as client:
        resp = await client.get(f'https://{AUTH_DOMAIN}/.well-known/jwks.json')
        return resp.json()

async def verify_oauth_token(token: str) -> dict:
    jwks = await get_jwks()
    try:
        payload = jwt.decode(
            token,
            jwks,
            algorithms=['RS256'],
            audience=AUDIENCE,
            issuer=f'https://{AUTH_DOMAIN}/'
        )
        return payload  # Contains sub (user ID), scope, exp, etc.
    except JWTError as e:
        raise ValueError(f'Invalid token: {e}')

Otorisasi Berbasis Scope

Tidak semua alat MCP seharusnya tersedia bagi semua pengguna. Gunakan scope OAuth atau klaim peran dalam token JWT untuk menentukan alat yang boleh dipanggil oleh pengguna yang telah diautentikasi. Periksa otorisasi di awal setiap eksekusi alat, sebelum panggilan basis data atau API apa pun dilakukan.

TOOL_REQUIRED_SCOPES = {
    'list_products': ['read:products'],
    'search_products': ['read:products'],
    'create_order': ['write:orders'],
    'delete_order': ['admin:orders']
}

def check_authorization(tool_name: str, token_payload: dict):
    '''Raise ValueError if user lacks required scope for the tool.'''
    required = TOOL_REQUIRED_SCOPES.get(tool_name, [])
    if not required:
        return  # No scope required

    user_scopes = set(token_payload.get('scope', '').split())
    missing = [s for s in required if s not in user_scopes]
    if missing:
        raise ValueError(
            f'Access denied. Tool "{tool_name}" requires scopes: {missing}. '
            f'Your token has: {list(user_scopes)}'
        )

# In call_tool handler:
# check_authorization(name, current_user_token)
# ... then execute the tool

Validasi Input dan Pencegahan Injeksi

Semua input alat pada akhirnya adalah string yang dihasilkan oleh LLM—perlakukan input tersebut sebagai tidak tepercaya. Validasi setiap input berdasarkan tipe dan pola yang diharapkan sebelum digunakan. Secara khusus, lindungi dari: injeksi SQL dengan menggunakan kueri berparameter dan tidak pernah menyusun SQL melalui interpolasi string, injeksi perintah dengan tidak pernah meneruskan input pengguna ke perintah shell, serta traversal jalur dengan menormalkan dan memvalidasi jalur file.

import re
from pathlib import Path

BASE_DATA_DIR = Path('/data/mcp-files')

def safe_file_path(user_input: str) -> Path:
    '''Validate and normalize a file path to prevent traversal attacks.'''
    # Remove any path traversal sequences
    clean = re.sub(r'\.\./', '', user_input)
    clean = re.sub(r'\.\.\\\\', '', clean)
    path = (BASE_DATA_DIR / clean).resolve()

    # Ensure the resolved path is still within the allowed base directory
    if not str(path).startswith(str(BASE_DATA_DIR)):
        raise ValueError(f'Path traversal detected: {user_input}')

    return path

def safe_identifier(value: str) -> str:
    '''Validate a database identifier (table/column name).'''
    if not re.match(r'^[a-z_][a-z0-9_]{0,63}$', value, re.IGNORECASE):
        raise ValueError(f'Invalid identifier: {value}')
    return value

Pembatasan Laju Pemanggilan Alat

Agen LLM dalam sebuah perulangan dapat memanggil alat yang mahal ratusan kali per menit, sehingga menghabiskan koneksi basis data, kuota API pihak ketiga, atau anggaran komputasi Anda. Terapkan batas laju per pengguna menggunakan algoritme bucket token di Redis. Tolak pemanggilan alat yang melebihi batas dengan error deskriptif agar agen mengetahui bahwa ia harus menunggu.

import redis
import time

r = redis.Redis.from_url('redis://localhost:6379')

def check_rate_limit(user_id: str, tool_name: str, limit: int = 60, window: int = 60) -> None:
    '''Allow at most `limit` calls per `window` seconds per user per tool.'''
    key = f'rate:{user_id}:{tool_name}'
    pipe = r.pipeline()
    pipe.incr(key)
    pipe.expire(key, window)
    count, _ = pipe.execute()

    if count > limit:
        retry_after = r.ttl(key)
        raise ValueError(
            f'Rate limit exceeded for {tool_name}. '
            f'Limit: {limit} calls/{window}s. '
            f'Retry after {retry_after} seconds.'
        )

Prinsip Hak Akses Minimum

Terapkan prinsip hak akses minimum pada setiap lapisan server MCP Anda. Pengguna basis data hanya boleh memiliki akses SELECT pada tabel yang dibutuhkan server. Proses server harus berjalan sebagai pengguna OS non-root. Alat hanya boleh meminta izin yang diperlukan. Kunci API harus memiliki scope minimum sesuai tujuannya. Setiap izin yang Anda batasi adalah potensi serangan yang tidak dapat berhasil.

-- PostgreSQL: Create a dedicated read-only database user for your MCP server
CREATE ROLE mcp_reader LOGIN PASSWORD 'strong_random_password';

-- Grant SELECT on only the tables the server needs
GRANT SELECT ON products, categories, public_content TO mcp_reader;

-- Explicitly deny access to sensitive tables
REVOKE ALL ON users, api_keys, payment_methods FROM mcp_reader;

-- Never grant: INSERT, UPDATE, DELETE, TRUNCATE, or DDL permissions

TLS dan Keamanan Transportasi

Server MCP jarak jauh harus menggunakan TLS untuk melindungi data saat transit. Konfigurasikan server agar hanya menerima koneksi HTTPS. Dalam produksi, gunakan proksi terbalik seperti nginx atau Caddy untuk menangani terminasi TLS dan menjaga sertifikat tetap terbaru melalui perpanjangan otomatis, misalnya Let's Encrypt melalui Certbot atau dukungan ACME bawaan Caddy.

# Example Caddyfile for TLS-terminating MCP server at a subdomain:
#
# mcp.yourcompany.com {
#     reverse_proxy localhost:8080
#     encode gzip
#     tls internal  # Use Let's Encrypt in production
#     header {
#         Strict-Transport-Security 'max-age=31536000; includeSubDomains'
#         X-Content-Type-Options nosniff
#         X-Frame-Options DENY
#     }
# }

Injeksi Prompt melalui Resource MCP

Berikut vektor serangan yang halus: jika server MCP Anda membaca konten dari sumber eksternal seperti halaman web, file yang diunggah pengguna, atau basis data tidak tepercaya lalu mengembalikannya sebagai hasil alat, penyerang dapat menyisipkan instruksi berbahaya ke dalam konten tersebut. Model mungkin mematuhi instruksi yang tersembunyi dalam data yang diambil—ini disebut injeksi prompt tidak langsung. Sanitasi konten yang diambil dan jangan pernah mengembalikan teks mentah yang tidak tepercaya secara langsung sebagai keluaran alat.

import re

def sanitize_for_mcp_output(text: str) -> str:
    '''Remove patterns that look like instructions to the LLM.'''
    # Remove common injection patterns
    dangerous_patterns = [
        r'ignore previous instructions',
        r'ignore all prior instructions',
        r'system:',
        r'<\|.*?\|>',  # Special tokens
        r'\[INST\]',
        r'<s>',
    ]
    for pattern in dangerous_patterns:
        text = re.sub(pattern, '[FILTERED]', text, flags=re.IGNORECASE)
    return text[:10000]  # Also cap length to prevent context stuffing

Audit dan Pemantauan Keamanan

Catat semua peristiwa yang relevan dengan keamanan: keberhasilan dan kegagalan autentikasi, pelanggaran batas laju, penolakan otorisasi, kesalahan validasi, dan pola akses yang tidak biasa. Siapkan peringatan untuk: beberapa upaya autentikasi yang gagal (serangan dengan mencoba berulang kali), satu pengguna yang memanggil alat destruktif dengan cepat, dan setiap pemanggilan alat dengan input yang sangat besar. Tinjau catatan audit secara berkala dan otomatisasi pendeteksian anomali.

Pemeriksaan Singkat

Uji pemahaman Anda tentang keamanan dan konsep autentikasi MCP.

Ringkasan Pelajaran

Dalam pelajaran ini, Anda mempelajari bahwa: server MCP jarak jauh memerlukan autentikasi OAuth 2.0 atau kunci API pada setiap permintaan, otorisasi berbasis cakupan mengontrol alat mana yang dapat dipanggil oleh setiap pengguna terautentikasi, dan semua input alat harus divalidasi untuk mencegah serangan injeksi dan traversal jalur. Modul MCP ini selesai — selanjutnya kita akan mempelajari strategi pemotongan lanjutan untuk pengambilan RAG berpresisi tinggi.

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Keamanan dan Autentikasi MCP” gratis?

Ya — teks lengkap “Keamanan dan Autentikasi MCP” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus AI Engineering Academy, upgrade ke CoddyKit PRO. Kursus AI Engineering Academy mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Keamanan dan Autentikasi MCP”?

Tambahkan autentikasi ke server MCP menggunakan token OAuth 2.0, terapkan validasi masukan untuk mencegah serangan injeksi, dan gunakan prinsip hak akses minimum pada izin alat. Kamu berlatih AI Engineering Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai AI Engineering Academy?

Tidak diperlukan pengalaman sebelumnya. AI Engineering Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 4 dari 4.

Berapa lama pelajaran “Keamanan dan Autentikasi MCP” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran AI Engineering Academy ini?

Ya. Setiap pelajaran AI Engineering Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Apa Itu MCP dan Mengapa Penting
  2. Membangun Server MCP Pertama Anda
  3. Menyediakan Sumber Daya Basis Data melalui MCP
  4. Keamanan dan Autentikasi MCP
← Kembali ke AI Engineering Academy