Skip to main content
Glama
sedattavukcu

entraid-mcp

by sedattavukcu
README.md
# Entra ID MCP Sunucusu

Microsoft Entra ID (Azure AD) hakkında salt-okunur bir
[Model Context Protocol](https://modelcontextprotocol.io) sunucusu.
[ArubaCentralMCP](https://github.com/sedattavukcu/aruba-central-mcp) /
[JamfMCP](https://github.com/sedattavukcu/jamf-pro-mcp) /
[DefenderCloudAppsMCP](https://github.com/sedattavukcu/defender-cloud-apps-mcp) /
[TeamsCallsMCP](https://github.com/sedattavukcu/teams-calls-mcp) /
[IntuneMCP](https://github.com/sedattavukcu/intune-mcp) ile aynı mimari
desenle yazılmıştır ve NetRadar Copilot Studio ajan ailesinin bir parçasıdır.

## Mimari

```mermaid
flowchart LR
    A["MCP İstemcisi<br/>(Copilot Studio / Claude Code)"] -->|"HTTPS<br/>Authorization: Bearer &lt;token&gt;"| B["Caddy<br/>(aruba-mcp-vm üzerinde,<br/>altıncı site block'u)"]
    B -->|"127.0.0.1:8425"| C["entraid-mcp.service<br/>Python / mcp.server.MCPServer"]
    C -->|"OAuth2 client_credentials<br/>Bearer &lt;access_token&gt;"| D["Microsoft Graph API<br/>graph.microsoft.com<br/>/auditLogs/signIns, /users/{id}/memberOf, /subscribedSkus"]
```

**Barındırma:** Ayrı bir VM açılmadı — `aruba-mcp-vm` (Azure, `ArubaMCP`
resource group) üzerinde **altıncı bir systemd servisi**
(`entraid-mcp.service`, port `8425`) ve Caddy'de **altıncı bir site
block'u** (ayrı subdomain, ayrı bearer token) olarak çalışır. Dedike,
ayrıcalıksız `entraidmcp` sistem kullanıcısı altında.

## Kimlik Doğrulama

Microsoft Entra ID, Doğuş Grubu tenant'ı (`dogusgrubu.onmicrosoft.com`).
Ayrı bir Entra ID App Registration (`EntraIDMCP`), OAuth2
`client_credentials` akışı, 4 application permission (hepsi admin consent
almış):

| İzin | Neden |
|---|---|
| `AuditLog.Read.All` | Sign-in (oturum açma) logları |
| `Directory.Read.All` | Başka bir kullanıcının grup üyeliği (`/users/{id}/memberOf`) — Microsoft'un app-only erişimde sunduğu en dar seçenek budur, daha kısıtlı bir alternatif yok |
| `User.Read.All` | Temel kullanıcı profili + `assignedLicenses` alanı |
| `LicenseAssignment.Read.All` | `/subscribedSkus` (tenant lisans kataloğu) |

**Not — lisans bilgisi neden `/subscribedSkus` üzerinden geliyor:**
`/users/{id}/licenseDetails` uç noktası Microsoft Graph'ta **uygulama
(app-only) izniyle hiç desteklenmiyor**, yalnızca delegated (kullanıcı
oturumu) erişimle çalışıyor. Bu yüzden `get_user_licenses` tool'u, tenant'ın
SKU kataloğunu (`/subscribedSkus`, 1 saat önbelleklenir) kullanıcının
`assignedLicenses` alanıyla eşleştirerek çalışıyor — servis planı bazında
ayrıntı yok, yalnızca üst seviye SKU adı (örn. `ENTERPRISEPREMIUM`).

## Araçlar

| Tool | Açıklama |
|---|---|
| `list_signins_by_user` | Kullanıcının sign-in geçmişi — başarı/hata, Conditional Access sonucu, cihaz/uygulama, IP + şehir/ülke (yalnızca şehir/ülke düzeyinde — geoCoordinates hiç döndürülmez) |
| `get_user_groups` | Kullanıcının doğrudan grup/rol üyelikleri (transitif değil) |
| `get_user_licenses` | Kullanıcıya atanmış Microsoft 365 lisansları (üst seviye SKU adı) |

## Gizlilik / Kapsam Notları

- Sign-in loglarında hassas `geoCoordinates` (enlem/boylam) alanı bilinçli
  olarak hiç döndürülmez — yalnızca şehir/ülke düzeyi tutulur.
- Risk alanları (`riskLevelDuringSignIn`, `riskDetail`) yalnızca Entra ID P2
  lisansında dolu gelir; P1/Free'de Graph "hidden" döndürür.
- Yazma/aksiyon işlemi (parola sıfırlama, hesap kilitleme, grup üyeliği
  değiştirme, sign-in riskli/güvenli işaretleme vb.) hiç içermez.