Przejdź do głównej zawartości

Jedna polityka dla wszystkich agentów kodujących

Zarządzana polityka agentów to jeden zestaw reguł organizacji (logowanie, modele, uprawnienia, serwery MCP, pluginy, hooki, wersje) spisany raz i przełożony na plik egzekwujący każdego narzędzia: managed-settings.json w Claude Code i GitHub Copilot, requirements.toml w Codeksie oraz ustawienia administracyjne w Cursorze. Programista nie może nadpisać kontroli, które te pliki egzekwują; kontrole, których narzędzie nie potrafi wyrazić (wymienione niżej), wymagają kontroli zastępczej.

Dział bezpieczeństwa zatwierdził Claude Code w marcu, z listą dozwolonych serwerów MCP. Od tego czasu zespół platformowy przeszedł na Codeksa, frontend pracuje w Cursorze, a Copilot włączył swoich agentów Claude i Codex. Cztery narzędzia czytają cztery pliki konfiguracyjne i nikt nie wie, które serwery MCP dopuszcza dziś konkretny laptop.

Ta strona jest dla CTO, który odpowiada za politykę agentów, i dla tech leada, który ją wdraża. To krok 11 ścieżki CTO. Poprzedza go strona o tożsamości, poświadczeniach i sekretach agentów, której reguły deny i zakresy MCP stają się tutaj ustawieniami zarządzanymi. Kolejny krok to zespół platformowy agentów, który prowadzi tę politykę jak produkt.

Co daje jedna zarządzana polityka dla wielu dostawców

Dział zatytułowany „Co daje jedna zarządzana polityka dla wielu dostawców”
  • Bazę dziesięciu kontroli zapisaną jako intencja, a nie jako klucze jednego dostawcy.
  • Jak Claude Code, Codex, Cursor i GitHub Copilot dostarczają i weryfikują politykę zarządzaną oraz jak kontrolować agentów chmurowych.
  • Pliki polityki sprawdzone 2026-09-26 w Claude Code 2.1.283, Codeksie 0.157.1 i w dokumentacji Copilota od GitHuba.
  • Repozytorium polityki, test parytetu list MCP w CI, wdrożenie kanarkowe, weryfikację i typowe awarie.

Co powinna mówić polityka, zanim dotkniesz konfiguracji?

Dział zatytułowany „Co powinna mówić polityka, zanim dotkniesz konfiguracji?”

Najpierw zapisz intencję, w jednym pliku podpisanym przez szefa bezpieczeństwa. Klucze dostawców zmieniają się z wydania na wydanie, intencja tylko wtedy, gdy zmienia się twój apetyt na ryzyko. Ta baza jest umiarkowana: blokuje drogi, którymi agent na laptopie wynosi dane albo omija review, a codzienne pytania o uprawnienia zostawia zespołom, jak opisuje strona o uprawnieniach i sandboksach dla agentów.

#KontrolaReguła bazowaDlaczego to poziom organizacji, a nie zespołu
1LogowanieAgenci logują się wyłącznie kontem firmowym, w organizacji firmyKonto prywatne omija warunki danych i audyt
2ModeleTylko modele objęte twoją umową; domyślny ustalany centralnieInny model to naruszenie zasad przetwarzania danych
3Minimalny poziom uprawnieńTryby bypass i „allow all” są wyłączone na maszynach programistówJedna flaga wyłącza wszystkie pozostałe kontrole
4Odczyt sekretówAgent nie czyta .env* ani secrets/**Model zagrożeń wymaga sekretów poza kontekstem
5Serwery MCPTylko zatwierdzone serwery, dopasowane po URL lub dokładnym poleceniuNiezweryfikowany serwer to cudzy kod z twoimi tokenami
6Pluginy i marketplace’yTylko oficjalny marketplace i wasz własnyJeden plugin to hooki, serwery MCP i skille
7Reguły poleceńPolecenia destrukcyjne, np. force-push, są zakazaneTanie do egzekwowania, drogie do odkręcenia
8Minimalna wersjaKlient starszy niż zatwierdzona wersja nie startujePoprawki bezpieczeństwa i nowe klucze polityki przychodzą w nowych wersjach
9TelemetriaZdarzenia użycia trafiają do waszego kolektoraAudyt i raporty kosztów potrzebują jednego źródła danych
10Agenci chmurowiPR-y agentów przechodzą te same wymagane kontrole co PR-y ludziIch polityka żyje na hostingu Git

Kontrole 3 i 4 są obowiązkowe dla każdego narzędzia. Kontrole 5 i 6 rozjeżdżają się najczęściej, bo każde narzędzie konfiguruje MCP i pluginy po swojemu. Weryfikację serwerów opisuje strona o rejestrach i bramkach MCP.

Jak każde narzędzie egzekwuje politykę zarządzaną?

Dział zatytułowany „Jak każde narzędzie egzekwuje politykę zarządzaną?”

Claude Code i GitHub Copilot mówią w dużej mierze tym samym dialektem managed-settings.json: permissions.deny, disableBypassPermissionsMode, strictKnownMarketplaces i allowedMcpServers. Codex używa osobnego pliku ograniczeń w TOML.

Claude Code (2.1.283)Codex (0.157.1)CursorGitHub Copilot
Plik politykimanaged-settings.json (plus managed-settings.d/*.json, managed-mcp.json)requirements.tomlPanel administracyjnymanaged-settings.json w .github-private/copilot/
DostarczanieKonsola administracyjna claude.ai (ustawienia zarządzane z serwera, server-managed), MDM (domena preferencji zarządzanych com.anthropic.claudecode na macOS, HKLM\SOFTWARE\Policies\ClaudeCode na Windowsie, wg dokumentacji ustawień zarządzanych Anthropic) lub plik systemowyWarstwa dostarczana z workspace’u, MDM na macOS lub /etc/codex/requirements.tomlIstnieją źródła ustawień team i mdm (@cursor/sdk 1.0.32)Zarządzane z serwera z .github-private, MDM lub plik systemowy (MDM tylko macOS i Windows)
Ścieżka pliku (Linux)/etc/claude-code/managed-settings.json/etc/codex/requirements.toml—/etc/github-copilot/managed-settings.json
Kilka źródełDomyślnie wygrywa pierwsze źródło z kluczem polityki; managedSourcesBehavior: "merge" je łączyŹródła się składają; /debug-config pokazuje, które ustawiło dane ograniczenie—MDM > zarządzane z serwera > plik > użytkownik, per klucz; permissions.deny/ask/allow i sandbox składają się najbardziej restrykcyjnie; allowedMcpServers to część wspólna
LogowanieforceLoginMethod, forceLoginOrgUUIDallowed_login_methods + allowed_chatgpt_workspacesSSO (potwierdź)forceLoginOrgs (MDM lub plik systemowy)
ModeleavailableModels + enforceAvailableModels; deniedModels (od v2.1.283, kanał latest)Przypięcie model_provider; [models.new_thread] ustawia domyślnyZgłaszane: listy dozwolonych i blokowanych modeli w Routerze; Privacy Mode wymaga zgody na modele z retencją (potwierdź)AI Controls: włącz, wyłącz lub deleguj każdy model; klucz model ustawia tylko domyślny
Minimalny poziom uprawnieńpermissions.disableBypassPermissionsMode, permissions.disableAutoModeallowed_approval_policies, allowed_sandbox_modesZgłaszane: uprawnienia agentów per grupa (potwierdź)permissions.disableBypassPermissionsMode
Telemetriaenv ze zmiennymi OTEL_*Brak klucza w wymaganiach; [otel] w rozsyłanym config.toml albo MDMNiezweryfikowanetelemetry (CLI, VS Code, JetBrains)
Lista dozwolonych MCPallowedMcpServers + allowManagedMcpServersOnly[mcp_servers.<name>.identity]NiezweryfikowaneallowedMcpServers / deniedMcpServers
Pluginy i hookistrictKnownMarketplaces, blockedMarketplaces; allowManagedHooksOnly[marketplaces] z restrict_to_allowed_sources; allow_managed_hooks_onlyZgłaszane: marketplace zespołu z pluginami Default On lub Required (potwierdź)strictKnownMarketplaces, enabledPlugins; hooki bez klucza zarządzanego
Polityka per grupaOsobne pliki albo Claude apps gateway per grupa z IdPJedna warstwa workspace’u; osobne pliki per grupa urządzeńZgłaszane: Organizations › Teams › Groups (potwierdź)Nadpisania zespołowe przez overridable i team-mappings.json
Sprawdzenie na maszynie/status → Setting sources; claude doctor/debug-config w TUIPanel administracyjnyWalidator na karcie Agents w AI Controls

Każda zakładka zawiera jeden plik realizujący każdą kontrolę, którą dane narzędzie potrafi wyrazić; luki są wymienione pod plikiem. Lista MCP jest wszędzie ta sama: zdalne serwery GitHuba i Sentry oraz lokalny Playwright. Przypnij wersję, którą zweryfikowałeś; @latest zatwierdza wszystko, co wyjdzie w następnym wydaniu. Podmień UUID organizacji, repozytorium marketplace’u i adres kolektora na własne.

Wdróż go przez konsolę administracyjną claude.ai, MDM albo ścieżkę systemową: /Library/Application Support/ClaudeCode/ na macOS, /etc/claude-code/ na Linuksie i WSL oraz C:\Program Files\ClaudeCode\ na Windowsie.

{
"forceLoginMethod": "claudeai",
"forceLoginOrgUUID": ["00000000-0000-0000-0000-000000000000"],
"availableModels": ["opus", "sonnet"],
"enforceAvailableModels": true,
"permissions": {
"deny": ["Read(./.env)", "Read(./.env.*)", "Read(./secrets/**)"],
"disableBypassPermissionsMode": "disable"
},
"allowedMcpServers": [
{ "serverUrl": "https://api.githubcopilot.com/*" },
{ "serverUrl": "https://mcp.sentry.dev/*" },
{ "serverCommand": ["npx", "@playwright/mcp@0.0.83"] }
],
"allowManagedMcpServersOnly": true,
"strictKnownMarketplaces": [
{ "source": "github", "repo": "anthropics/claude-plugins-official" },
{ "source": "github", "repo": "acme/agent-plugins" }
],
"disableSideloadFlags": true,
"requiredMinimumVersion": "2.1.274",
"env": {
"CLAUDE_CODE_ENABLE_TELEMETRY": "1",
"OTEL_METRICS_EXPORTER": "otlp",
"OTEL_LOGS_EXPORTER": "otlp",
"OTEL_EXPORTER_OTLP_PROTOCOL": "grpc",
"OTEL_EXPORTER_OTLP_ENDPOINT": "https://otel.acme.internal:4317"
}
}

Co robią mniej oczywiste klucze:

  • Samo availableModels zostawia opcję Default na domyślnym modelu konta; enforceAvailableModels podporządkowuje liście także Default. Klucz model to tylko wybór początkowy.
  • allowManagedMcpServersOnly nie pozwala użytkownikom poszerzyć listy. Gdy istnieje choć jeden wpis serverUrl, każdy zdalny serwer musi pasować do wzorca URL. Wpis serverName nigdy nie jest kontrolą bezpieczeństwa, bo nazwę wybiera użytkownik.
  • disableSideloadFlags odrzuca przy starcie --plugin-dir, --plugin-url, --agents i --mcp-config (od v2.1.193), więc runnery CI, które przekazują --mcp-config, potrzebują własnego pliku polityki.
  • OTEL_EXPORTER_OTLP_PROTOCOL jest obowiązkowy: Claude Code nie ma domyślnego protokołu OTLP, więc bez niego nic nie jest eksportowane, a kontrola 9 zawodzi bez żadnego błędu. Port 4317 to gRPC; dla punktu końcowego na 4318 użyj http/protobuf.
  • requiredMinimumVersion to 2.1.274, kanał stable z 2026-09-26. Blokuje starsze binaria tylko przy starcie.
  • Stały zestaw MCP, którego użytkownik nie rozszerzy, wdrażasz jako managed-mcp.json przez MDM albo ścieżkę systemową; konsola go nie dostarczy.

Wariant ostrzejszy dodaje allowManagedPermissionRulesOnly i allowManagedHooksOnly. Oba wyłączają reguły i hooki projektu, których zespoły używają jako bramek jakości, więc zostaw je dla danych regulowanych.

Jak kontrolować agentów chmurowych, którzy tylko otwierają pull requesty?

Dział zatytułowany „Jak kontrolować agentów chmurowych, którzy tylko otwierają pull requesty?”

Copilot cloud agent, agenci Claude i Codex w Copilocie, Jules i Devin pracują na zdalnych maszynach, więc nic wdrożonego na laptop do nich nie dociera. Sesja Claude Code w chmurze również czyta tylko ustawienia zarządzane z serwera. Tych agentów kontrolujesz tam, gdzie ląduje ich praca: na hostingu Git.

KontrolaGdzie żyjeKogo dotyczy
Którzy agenci mogą działaćPolityki Copilota w AI Controls, per agent; repozytoria, do których ma dostęp aplikacja GitHub danego dostawcyWszyscy
Co może zostać scaloneRulesety albo ochrona gałęzi: wymagane review, wymagane kontrole stanu (status checks), brak obejścia dla tożsamości botówKażdy agent otwierający PR
Jakie sekrety widzi uruchomienieSekrety środowiska i repozytorium ograniczone do workflow; GitHub Action Julesa czyta klucz z sekretu repozytorium JULES_API_KEYAgenci uruchamiani z GitHub Actions
Co zostało zrobioneLog audytu enterprise, w tym zdarzenia agentowe w AI Controls; logi CIAgenci Copilota; każdy agent przez CI

Dokumentacja administracyjna Julesa i Devina była niedostępna 2026-09-26, więc ta strona nie twierdzi nic o ich ustawieniach w produkcie. Granica na hostingu Git działa dla każdego dostawcy, dlatego kontrola 10 brzmi „PR-y agentów przechodzą te same wymagane kontrole co PR-y ludzi”. Pakiet dowodów pozwala scalić PR bez człowieka czytającego każdą linię.

Jak dystrybuować i wersjonować jedną politykę dla wielu dostawców?

Dział zatytułowany „Jak dystrybuować i wersjonować jedną politykę dla wielu dostawców?”

Traktuj politykę jak każdą inną konfigurację produkcyjną: jedno repozytorium, zmiany przez review, bramki w CI i wdrożenie etapami.

  1. Załóż repozytorium polityki. Jeden katalog na narzędzie, wygenerowany z tabeli intencji.

    agent-policy/
    ├── POLICY.md # tabela intencji dziesięciu kontroli, podpisana przez bezpieczeństwo
    ├── CHANGELOG.md # jeden wpis na wersję: co i dlaczego
    ├── CODEOWNERS # zatwierdzają bezpieczeństwo + zespół platformowy
    ├── claude-code/managed-settings.json
    ├── claude-code/ci/managed-settings.json # runnery CI: bez disableSideloadFlags
    ├── codex/requirements.toml
    ├── copilot/managed-settings.json # synchronizowany do .github-private/copilot/
    ├── cursor/EVIDENCE.md # datowane odpowiedzi z zakładki Cursor
    └── tests/mcp_parity.py
  2. Blokuj każdą zmianę w CI. Sparsuj każdy plik, a potem oznacz kontrolę jako nieudaną, gdy listy dozwolonych MCP się różnią. Ten skrypt, uruchomiony na trzech plikach z tej strony, kończy się kodem 1, gdy Claude Code i Copilot się różnią albo gdy Codex i Claude Code nie zgadzają się w którąkolwiek stronę.

    """Fail CI when the MCP allowlists disagree across tools."""
    import fnmatch
    import json
    import sys
    import tomllib
    claude = json.load(open("claude-code/managed-settings.json"))
    copilot = json.load(open("copilot/managed-settings.json"))
    with open("codex/requirements.toml", "rb") as f:
    codex = tomllib.load(f)
    def allowlist(settings):
    entries = settings.get("allowedMcpServers", [])
    urls = {e["serverUrl"] for e in entries if "serverUrl" in e}
    cmds = {tuple(e["serverCommand"]) for e in entries if "serverCommand" in e}
    return urls, cmds
    problems = []
    if allowlist(claude) != allowlist(copilot):
    problems.append(f"Claude Code and Copilot differ: {allowlist(claude)} vs {allowlist(copilot)}")
    codex_urls, codex_cmds = {}, {}
    for name, req in codex.get("mcp_servers", {}).items():
    ident = req.get("identity", {})
    if isinstance(ident.get("url"), str):
    codex_urls[ident["url"]] = name
    cmd = ident.get("command")
    if isinstance(cmd, dict):
    argv = (cmd["executable"], *(a.get("value", "") for a in cmd.get("args", [])))
    codex_cmds[argv] = name
    claude_urls, claude_cmds = allowlist(claude)
    for url, name in codex_urls.items():
    if not any(fnmatch.fnmatch(url, p) for p in claude_urls):
    problems.append(f"Codex allows {name} at {url}; Claude Code does not")
    for argv, name in codex_cmds.items():
    if argv not in claude_cmds:
    problems.append(f"Codex allows {name} as {' '.join(argv)}; Claude Code does not")
    for pattern in claude_urls:
    if not any(fnmatch.fnmatch(url, pattern) for url in codex_urls):
    problems.append(f"Claude Code allows {pattern}; Codex has no matching server")
    for argv in claude_cmds - codex_cmds.keys():
    problems.append(f"Claude Code allows {' '.join(argv)}; Codex has no matching server")
    print("\n".join(problems) or "MCP allowlists agree across Claude Code, Codex and Copilot")
    sys.exit(1 if problems else 0)

    Uruchamiaj go jako wymaganą kontrolę CI poleceniem python3 tests/mcp_parity.py (Python 3.11 lub nowszy, ze względu na tomllib), obok python3 -m json.tool na każdym pliku JSON.

  3. Najpierw wdróż na grupę kanarkową. Dostarcz nową wersję na maszyny zespołu platformowego na dwa dni robocze. Zmiany w ustawieniach zarządzanych z serwera docierają do Claude Code i Copilota w około godzinę; MDM Claude Code sprawdza co 30 minut, a Copilot co godzinę; zmiana pliku wymaga restartu Copilota.

  4. Wypromuj na wszystkich i przypnij wersję. Otaguj wydanie (agent-policy v1.4) i wpisz wersję w komentarzu na górze każdego pliku, żeby zgłoszenie do supportu mogło ją podać.

  5. Najpierw zapowiadaj usunięcia. Nowa reguła deny albo usunięty serwer MCP psuje komuś pracę; opublikuj wpis w changelogu przed wdrożeniem i podaj zamiennik.

Repozytorium i wdrożenie należą do zespołu platformowego; szef bezpieczeństwa zatwierdza każdą zmianę w POLICY.md i podpisuje kwartalny audyt. Pełną macierz RACI zawiera model operacyjny.

Plik konfiguracyjny dowodzi tylko tego, że ktoś go napisał. Egzekwowanie udowadniasz na prawdziwych maszynach, według harmonogramu.

  1. Odczytaj efektywne źródło na próbce maszyn. W Claude Code /status musi pokazać Enterprise managed settings ze źródłem, które wdrożyłeś, np. (remote) albo (file); Skipped sources oznacza, że wygrało źródło o wyższym priorytecie, a claude doctor wypisuje wpisy odrzucone jako niepoprawne. W Codeksie /debug-config pokazuje, które źródło ustawiło każde ograniczenie. W Copilocie walidator na karcie Agents nie może pokazywać problemów.
  2. Uruchom testy negatywne. Dodaj na maszynie kanarkowej serwer MCP spoza listy i potwierdź, że każde narzędzie go odrzuca. Uruchom Claude Code z --dangerously-skip-permissions, co musi zostać odrzucone, i Codeksa z -a never, a potem potwierdź, że wypisał ostrzeżenie startowe i że /debug-config pokazuje on-request.
  3. Obserwuj strumień audytu. Claude Code wysyła do twojego kolektora OpenTelemetry zdarzenia claude_code.plugin_installed i claude_code.plugin_loaded; nazwy pluginów zewnętrznych są zamaskowane, dopóki nie ustawisz OTEL_LOG_TOOL_DETAILS=1. Log audytu enterprise w Copilocie zapisuje zdarzenia agentowe. Kieruj oba do potoku opisanego w obserwowalności agentów.
  4. Audytuj co kwartał. Porównaj repozytorium, dostarczone ustawienia i testy negatywne; niewyjaśniona różnica to ustalenie z właścicielem i terminem.

Co się psuje, gdy egzekwujesz jedną politykę u wielu dostawców?

Dział zatytułowany „Co się psuje, gdy egzekwujesz jedną politykę u wielu dostawców?”

Plik polityki Claude Code jest po cichu ignorowany. Wdrożyłeś plik przez MDM, a ktoś ustawił jeden klucz w konsoli administracyjnej. Domyślnie Claude Code używa tylko źródła o najwyższym priorytecie, które dostarcza klucz polityki. Naprawa: przeczytaj Skipped sources w /status, a potem użyj jednego źródła albo ustaw managedSourcesBehavior na "merge" (od v2.1.242).

Uszkodzony plik blokuje ludzi. Claude Code nie startuje, gdy plik zarządzany nie jest poprawnym JSON-em; Copilot traktuje uszkodzoną listę dozwolonych jak pustą, co blokuje każdy serwer MCP poza wbudowanymi. Naprawa: wróć do poprzedniego tagu; parsowanie w CI zapobiega powtórce.

Codex wyłącza zatwierdzony serwer. Jego nazwa różni się od klucza w wymaganiach albo zarejestrowano go z npx -y wobec tożsamości bez -y. Naprawa: publikuj dokładne polecenie codex mcp add dla każdego zatwierdzonego serwera, z nazwami i argv z requirements.toml (sprawdzone z codex mcp add --help, 0.157.1):

Okno terminala
codex mcp add github --url https://api.githubcopilot.com/mcp/
codex mcp add sentry --url https://mcp.sentry.dev/mcp
codex mcp add playwright -- npx @playwright/mcp@0.0.83

Zadania CI przestają działać po wdrożeniu. disableSideloadFlags odrzuca --mcp-config. codex exec prosi o politykę zatwierdzania never; jeśli lista jej nie zawiera, Codex startuje z ostrzeżeniem i wraca do pierwszej dozwolonej polityki, więc uruchomienie bez nadzoru dostaje prośby o zatwierdzenie, na które nikt nie odpowie (sprawdzone w codex-cli 0.157.1). Naprawa: daj runnerom CI własny plik polityki, którego allowed_approval_policies zawiera never, i utrzymuj je na utwardzonych workflow z poprzedniego kroku.

Agenci Copilota ignorują listę dozwolonych MCP. GitHub oznacza allowedMcpServers, deniedMcpServers i permissions.deny jako nieobsługiwane w Copilot cloud agent, a agenci Claude i Codex w Copilocie mają własne polityki. Naprawa: skonfiguruj serwery MCP cloud agenta per repozytorium albo w profilach agentów niestandardowych enterprise i przejrzyj wiersz polityki każdego agenta w AI Controls.

Nowe modele pojawiają się u wszystkich. Polityka Default availability w Copilocie i availableModels w Claude Code bez enforceAvailableModels przepuszczają modele spoza listy. Naprawa: ustaw oba świadomie i sprawdzaj listę modeli w kwartalnym audycie; aktualne modele wymienia przegląd modeli.

Długo działające sesje nie nadążają za wdrożeniem. requiredMinimumVersion blokuje tylko nowe starty. Naprawa: ogłoś okno restartu, a potem sprawdź wersje w telemetrii.