Agent Harness
Uruchamiaj Claude Code i Codex na własnej maszynie zgodnie z polityką organizacji: nadzorowany ruch modeli, nadzorowane narzędzia, jeden mierzony i pieczętowany ślad audytowy.
Nic z agenta nie przenosi się do chmury. Claude Code i Codex nadal działają na maszynie programisty, z własnymi procesami, plikami, wbudowanymi narzędziami i własną pętlą agenta. Sluis nadzoruje ruch, który wychodzi na zewnątrz: żądania do modelu i wywołania narzędzi.
Region nie jest wymuszany dla agentów koduAgent kodu rozmawia z Twoją własną subskrypcją dostawcy (Anthropic, OpenAI lub Cursor), a to dostawca decyduje, gdzie żądanie jest obsługiwane. Sluis nie może ustalić regionu obsługi, więc na płaszczyźnie agentów rezydencja jest zapisywana, a nie wymuszana: tura agenta nigdy nie jest odrzucana z powodu jurysdykcji, a jej wiersz audytu zapisuje region jako niezweryfikowany, zamiast go deklarować. Wszystko inne nadal obowiązuje: klucze agenta o wydzielonym przeznaczeniu, stopniowe wdrażanie per organizacja, skanowanie DLP i pseudonimizacja (także na protobufowym łączu Cursora), zarządzanie wtyczkami i narzędziami, limity budżetu i tempa oraz zapieczętowany audyt.
Lokalny klient uwierzytelnia się w Sluis kluczem agenta i korzysta z wejścia właściwego dla swojego protokołu: /agent/claude udostępnia API Anthropic dla Claude Code, /agent/codex/v1 udostępnia API OpenAI Responses dla Codex, /agent/cursor obsługuje protokół Connect Cursora na protobufie, a /agent/mcp to bezstanowy endpoint MCP Streamable HTTP z nadzorowanymi narzędziami.
Claude Code i Codex to przykłady, nie zamknięta lista. Pi, T3 Code i każdy klient przyjmujący URL i klucz Anthropic Messages, OpenAI Responses lub MCP korzysta z tego samego Agent Harness.
Cała konfiguracja ma jedną kolejność, a każdy krok potrzebuje poprzedniego:
- 1. Podłącz subskrypcję. Claude albo Codex, podłączany raz na konto dostawcy.
- 2. Utwórz klucz agenta. Sekret jest pokazywany raz, przy tworzeniu.
- 3. Powiąż klucz z tym kontem. Klucz wydaje tylko konta, z którymi jest powiązany.
- 4. Skonfiguruj lokalnego klienta. Klucz trzymasz w
SLUIS_AGENT_KEY, a base URL wskazuje/agent/claudedla Claude Code,/agent/codex/v1dla Codex albo/agent/cursordla Cursora, który przenosi ten sam klucz w Authorization: Bearer. - 5. Zarejestruj endpoint narzędzi. Narzędzia docierają wyłącznie przez
/agent/mcp, rejestrowany osobno: base URL nie dodaje żadnych.
Podłącz subskrypcję
Organizacja podłącza jedno lub więcej kont subskrypcji Claude i Codex w widoku Agent Harness. Claude podłączasz tokenem z claude setup-token, Codex przez autoryzację urządzenia OpenAI. Sluis sprawdza poświadczenie u dostawcy, zanim cokolwiek zapisze.
Claude: token konfiguracyjny
Potrzebujesz Claude Code na swojej maszynie, zalogowanego do subskrypcji Claude, która pozwala na żądania do modelu.
- 1. Uruchom
claude setup-tokenw terminalu. Polecenie wypisuje długowieczny token, ważny około roku, zaczynający się odsk-ant-oat. - 2. Wklej go w pole Claude w Konsoli. Pole jest maskowane, a autouzupełnianie wyłączone.
- 3. Po zatwierdzeniu Sluis sprawdza token u Anthropic, zanim cokolwiek zapisze.
- 4. Sprawdzony token zostaje zapieczętowany, zaszyfrowany, w sejfie bramy: nigdy nie jest pokazywany ponownie, nigdy nie wraca do klienta i nie trafia nigdzie poza Anthropic.
Token, którego Anthropic nie potwierdzi, zostaje odrzucony kodem 422: żadne konto nie powstaje, nic nie jest zapisywane i nic nie jest naliczane. Ponowne podłączenie tej samej subskrypcji później użyje istniejącego konta, a nie doda drugiego płatnego.
Codex: autoryzacja urządzenia
Potrzebujesz planu ChatGPT, który obejmuje Codex.
- 1. Rozpocznij logowanie urządzenia w Konsoli. Sluis pyta OpenAI i pokazuje adres weryfikacji oraz kod użytkownika.
- 2. Otwórz ten adres przyciskiem, zaloguj się w OpenAI, wpisz kod i zatwierdź. OpenAI może poprosić o MFA.
- 3. Konsola odpytuje serwer, kiedy zatwierdzasz. Wymiana zachodzi w tej karcie przeglądarki: opuszczenie strony albo przejście na inną kartę widoku anuluje logowanie i nic nie zapisuje, dokładnie jak akcja Anuluj.
- 4. Po zatwierdzeniu Sluis zapisuje tokeny dostępu i odświeżania zaszyfrowane w sejfie bramy i sam je odświeża; rotacja tokenu odświeżania jest szeregowana między replikami.
Kod użytkownika wygasa. Wygasły przepływ raportuje expired i trzeba go zacząć od nowa — podobnie konto, którego zapisane poświadczenie OpenAI później odrzuci: nie obsługuje żądań, dopóki człowiek go nie podłączy ponownie.
Sluis szyfruje te poświadczenia, przechowuje je w sejfie bramy i tam je odświeża. Token dostawcy nigdy nie dociera do lokalnego klienta, logów, zapisów audytu ani śladów: Claude Code i Codex mają wyłącznie swój klucz agenta Sluis.
Podłączanie jest samoobsługowe, więc członek może dodać własną subskrypcję. Właściciele i administratorzy widzą wszystkie konta organizacji; członek widzi i odłącza tylko swoje.
Utwórz klucz agenta
Klucze agenta tworzysz w tym samym widoku, oddzielnie od kluczy API, bo oba przeznaczenia są odseparowane. Klucz agenta uwierzytelnia się tylko na /agent/*, zwykły klucz API tylko na /v1/*. Każdy z nich na niewłaściwej powierzchni daje 401, a odmowa nigdy nie ujawnia przeznaczenia klucza.
Sekret jest pokazywany raz, przy tworzeniu, a przechowywany jest tylko jego skrót. Każdy klucz korzysta z kont dostawcy, które mu wskażesz, więc podłączenie subskrypcji drugiego członka nigdy nie przekieruje działającego już klucza.
Klucz zapisuje też pułap organizacji dla wbudowanych narzędzi lokalnego klienta, w gramatyce narzędzi Claude Code, sprawdzany przy tworzeniu. Tę listę wymusza klient programisty na maszynie; Sluis nigdy nie czyta jej w trakcie żądania, więc nikt nie rozszerzy własnego klucza, a pusta lista oznacza po prostu brak zapisanego pułapu.
Narzędzia, które Sluis kontroluje sam, przy każdym żądaniu, to udostępniane przez niego narzędzia MCP: patrz wtyczki poniżej.
Skieruj klienty na Sluis
Claude Code potrzebuje jednego base URL i jednego poświadczenia. Ustaw ANTHROPIC_BASE_URL na wejście Claude tej bramy, a ANTHROPIC_API_KEY na klucz agenta trzymany w SLUIS_AGENT_KEY. Konsola generuje poniższy blok z już wpisanym publicznym adresem twojej bramy.
Base URL nie dodaje narzędzi: protokół Anthropic nie ma wykrywania wtyczek, więc narzędzia docierają wyłącznie przez endpoint MCP, który rejestrujesz sam, poleceniem claude mcp add albo wpisem .mcp.json. Oba odwołują się do ${SLUIS_AGENT_KEY}, a nie do klucza, żeby żaden sekret nie trafił do pliku w repozytorium.
Codex czyta blok dostawcy z ~/.codex/config.toml. Ustaw base_url na wejście Responses /agent/codex/v1, podaj wire_api = "responses" i env_key = "SLUIS_AGENT_KEY", a następnie dodaj ten sam endpoint MCP w [mcp_servers.sluis].
# the agent key is shown once, at creation: keep it in the environment export SLUIS_AGENT_KEY='sluis-9f2c…' export ANTHROPIC_BASE_URL='https://api.sluis.ai/agent/claude' export ANTHROPIC_API_KEY="$SLUIS_AGENT_KEY"
# a base URL adds no tools: register the MCP endpoint separately claude mcp add --transport http sluis 'https://api.sluis.ai/agent/mcp' \ --header 'Authorization: Bearer ${SLUIS_AGENT_KEY}'
// .mcp.json: the same registration, kept with the project { "mcpServers": { "sluis": { "type": "http", "url": "https://api.sluis.ai/agent/mcp", "headers": { "Authorization": "Bearer ${SLUIS_AGENT_KEY}" } } } }
# Codex reads the key from SLUIS_AGENT_KEY, never from the config file codex exec -m openai/gpt-5.4 'tighten the retry test'
# ~/.codex/config.toml model = "openai/gpt-5.4" model_provider = "sluis" [model_providers.sluis] name = "Sluis" base_url = "https://api.sluis.ai/agent/codex/v1" env_key = "SLUIS_AGENT_KEY" wire_api = "responses" [mcp_servers.sluis] url = "https://api.sluis.ai/agent/mcp" bearer_token_env_var = "SLUIS_AGENT_KEY" default_tools_approval_mode = "approve"
Cursor wskazuje na tę samą bramę. Ustaw jego bazowy URL na wejście Cursora tej bramy, /agent/cursor, z kluczem agenta w nagłówku Authorization. Udokumentowana trasa to POST /agent/cursor/agent.v1.AgentService/Run, przenoszona przez Connect z typem treści application/connect+proto. Klient, który nie potrafi ustawić bazowego URL, może wskazać samo origin, bo protokół Cursora ustala ścieżkę absolutną.
Sluis przechodzi te ramki Connect bez schematu i stosuje do zawartego w nich tekstu promptu tryb ochrony danych organizacji: tokenize zamienia wykryte wartości na odwracalne zastępniki i przywraca oryginały w strumieniowanej odpowiedzi, mask usuwa je całkowicie, block odrzuca turę, zanim cokolwiek dotrze do Cursora, a ramka, której Sluis nie potrafi zdekodować, zostaje odrzucona, a nie przesłana dalej. Tylko allow_log ją przesyła, a ślad audytu zapisuje, że nie dała się zbadać.
Dwa ograniczenia należą do tego transportu. Wykrywanie nazwisk i zabezpieczenie przed wstrzykiwaniem promptu czytają treść żądania w JSON, a Connect protobuf nią nie jest: dlatego nie działają, wiersz audytu zapisuje je jako nieuruchomione, a organizacja, która uczyniła wykrywanie nazwisk obowiązkowym, dostaje odmowę zamiast niezbadanego przesłania. Protokół Connect nie raportuje też zużycia tokenów, więc tura Cursora jest pieczętowana w śladzie audytu bez liczby tokenów.
Każda powierzchnia przyjmuje poświadczenie w dokładnie jednej formie: x-api-key na wejściu Claude, bo tak wysyłają klienty Anthropic, oraz Authorization: Bearer na wejściach Codex, Cursor i MCP. Ten sam klucz w drugim nagłówku zostanie odrzucony.
Wtyczki MCP
Nadzorowane narzędzia docierają jednym bezstanowym endpointem, POST /agent/mcp. Nie utrzymuje sesji: każde żądanie od nowa wyprowadza cały łańcuch autoryzacji, więc odwołanie klucza, wtyczki lub klucza podpisującego działa od następnego wywołania.
Są dwie klasy. Wtyczki utrzymywane przez Sluis to skompilowany kod Sluis, dostępny dla całej organizacji, bez wykonywania kodu klienta. Wtyczki organizacji są twoje: manifest TOML podpisany kluczem Ed25519.
Manifest zostaje przyjęty tylko wtedy, gdy jego podpis weryfikuje się kluczem podpisującym zarejestrowanym przez twoją organizację, i jest niezmienny w obrębie (organisation, id, version): zmieniona definicja narzędzia to nowa wersja, nigdy cicha korekta. Każda wtyczka jest przypięta do jednego nadzorowanego serwera MCP po HTTPS, którego adres musi dokładnie odpowiadać adresowi w podpisanym manifeście.
Praca operatora to trzy kroki. Właściciel rejestruje klucz podpisujący organizacji. Właściciel lub administrator rejestruje podpisany manifest wobec nadzorowanego serwera MCP. Potem wtyczkę wiąże się z kluczami agenta, które mogą jej używać, a wtyczka bez powiązań nie jest widoczna dla nikogo.
Adresy serwerów, manifesty, podpisy i poświadczenia upstream nigdy nie docierają do klienta. Programista widzi nazwy narzędzi i schematy, nic więcej.
Kontekst i umiejętności wstrzykiwane przez bramę
Twoje standardy inżynierskie są polityką tylko wtedy, gdy programista nie może o nich zapomnieć. CLAUDE.md wrzucony do repozytorium jest sugestią: można go zmienić, usunąć albo po prostu nie przeczytać, a nic nie zapisuje, co się z tego stało. Ten sam tekst, który brama wstawia do każdego nadzorowanego żądania agenta, jest decyzją organizacji — najpierw napisz test, który nie przechodzi, nie dodawaj zależności bez zatwierdzonego ADR, to repozytorium zawiera dane osobowe, więc pseudonimizuj przed wklejeniem. To ta połowa harnessu, która rządzi tym, jak agent pracuje, a nie tym, do jakiego modelu i jakich narzędzi sięga.
Przenoszą to dwa rodzaje wtyczek i żaden nie nadaje własnych uprawnień:
- Kontekst. Tekst dosłowny, wstrzykiwany przed własnym promptem programisty, do 16 KiB na wersję.
- Umiejętność. Nazwa, jej instrukcje i nazwy narzędzi, których oczekuje. Te nazwy są przecinane z pułapem narzędzi zapisanym na kluczu: umiejętność deklaruje, czego potrzebuje, i nigdy nie może rozszerzyć klucza — narzędzie, którego pułap nie zawiera, po prostu nie jest wymieniane modelowi.
Wersja jest powiązana w jednym z trzech zakresów, a każde żądanie rozwiązuje wszystkie trzy:
- Organizacja. Każdy klucz agenta w organizacji, także te utworzone po powiązaniu. To zakres dla reguły, o której dopinaniu nikt nie powinien musieć pamiętać.
- Użytkownik. Każdy klucz agenta jednego członka — wprowadzenie dla nowej osoby albo surowsza postawa dla kogoś jednego.
- Klucz. Dokładnie jeden klucz agenta, czyli to, co powiązanie robiło do tej pory.
Rozwiązywanie jest deterministyczne, bo kolejność wstrzyknięcia zmienia prompt. Sluis bierze sumę trzech zakresów, weryfikuje każdą wtyczkę ponownie tak samo jak przy narzędziach, odrzuca powtórzone wersje i porządkuje: najpierw organizacja, potem użytkownik, na końcu klucz — reguła ogólna czytana jest pierwsza, a wąski wyjątek ostatni. Kontekst wstrzykiwany jest dosłownie, umiejętność jako nazwana sekcja. Na wejściu Claude bloki poprzedzają system, w obu postaciach, na które to API pozwala; na wejściu Codex poprzedzają instructions, albo trafiają jako początkowa instrukcja developer, gdy żądanie żadnej nie ma.
Wszystko wstrzyknięte do jednego żądania mieści się w 32 KiB. Powyżej tego żądanie zostaje odrzucone przez 422 z nazwami wtyczek, które przekroczyły limit. Nic nie jest po cichu obcinane: pół instrukcji jest gorsze niż żadna, a organizacja przekonana, że reguła obowiązuje, musi się dowiedzieć, kiedy tak nie jest.
Wstrzykniętego tekstu nie przepisuje ochrona danych, a kolejność jest jednokierunkowa: najpierw prompt programisty jest skanowany i pseudonimizowany, potem dopisywana jest twoja polityka. Te bloki to twoja własna nadzorowana treść, napisana w twojej Konsoli, więc nie ma przed kim ich chronić — a tokenizacja zniszczyłaby to, co mówią. „Eskaluj do security@example.com przed wklejeniem” zamienione na „eskaluj do «EMAIL_1» przed wklejeniem” przestaje być instrukcją, którą da się wykonać.
Te dwa rodzaje pisze się w Konsoli i nie noszą podpisu. Podpis istnieje po to, by manifest nie skierował nadzorowanego poświadczenia na endpoint, którego nikt nie zatwierdził; blok tekstu nie kieruje się nigdzie. Wszystko inne, co czyni rejestrację godną zaufania, obowiązuje dalej: wersja jest niezmienna, jej dokładne bajty są zahaszowane, a wiersz zapisuje, kto i kiedy ją napisał. Manifest z wpisem MCP zachowuje obowiązkowy podpis i sprawdzenie zarejestrowanego podpisującego przy każdym żądaniu. Zakładka Plugins pokazuje, którym z dwóch jest dana wersja, więc „napisane w Konsoli” jest stwierdzonym faktem, a nie brakującym polem, i podgląda rozwiązane bloki w kolejności, w jakiej brama je wstrzykuje dla wybranego klucza albo członka.
Każdy wstrzyknięty blok zostawia jeden znacznik w zaplombowanym wierszu audytu, context:<plugin_id>@<version>#<digest8>, gdzie skrót to pierwszych osiem znaków hasza tej wersji. Ponieważ wersja jest niezmienna, znacznik wystarcza, by odtworzyć dokładny tekst przekazany modelowi: sam ślad audytowy odpowiada, czy agent podlegał danej regule w chwili, gdy działał.
Cursor to uczciwie nazwana luka. Jego transport /agent/cursor to zamknięty schemat binarny: Sluis potrafi znaleźć i przepisać tekst wewnątrz tych ramek — tak działa tam ochrona danych — ale nie może stwierdzić, które pole jest promptem systemowym, a zapis do zgadniętego pola uszkodziłby żądanie, zamiast je nadzorować. Na tym wejściu nic więc nie jest wstrzykiwane, a tura Cursora nosi twój kontekst tylko wtedy, gdy wyśle go klient samego programisty. Podgląd w Konsoli mówi to samo.
Nadzór, który nadal obowiązuje
Ruch agenta to zwykły ruch Sluis, z jednym wyjątkiem. Pseudonimizacja i DLP działają przed wysłaniem, także w ramkach protobuf Cursora, limity tempa i budżetu klucza obowiązują w każdym żądaniu, narzędzia MCP są dopuszczane wywołanie po wywołaniu, a każde wywołanie modelu i narzędzia jest audytowane i mierzone. Wyjątkiem jest rezydencja: na płaszczyźnie agentów polityka jest zapisywana, a nie wymuszana, z powodu opisanego w ramce na początku tej strony.
Obowiązują te same reguły co w Ochrona danych i Budżety i cache, i są polityką organizacji: klucz agenta nie może ich rozluźnić.
Rozliczenia
Każde aktywne konto dostawcy zarządzane przez Sluis kosztuje 16,50 € ceny katalogowej za miesiąc kalendarzowy, naliczane najwyżej raz na konto w miesiącu. Opłata trafia do twojego nadrzędnego korzenia rozliczeniowego i pojawia się jako osobna pozycja faktury, oddzielona od mierzonego użycia. VAT i dopłata za metodę płatności działają dokładnie tak jak na resztę faktury.
Odłączenie konta zatrzymuje kolejne miesiące. Ponowne podłączenie tej samej subskrypcji upstream używa istniejącego konta, a nie tworzy drugiego płatnego, więc odłączenie i ponowne podłączenie w tym samym miesiącu kosztuje raz.
Samo korzystanie z bramy pozostaje rozliczane według zużycia, tak jak przy kluczach API.
Dostępność
Widok Agent Harness pojawia się w Konsoli, gdy flaga wdrożenia agent_harness jest włączona dla twojej organizacji. Poproś nas o włączenie, jeśli go nie widzisz.
Rozwiązywanie problemów
| Objaw | Przyczyna i rozwiązanie |
|---|---|
| 401 przy wywołaniu /agent/* | Klucz jest na niewłaściwej powierzchni albo w niewłaściwym nagłówku. Klucz API nic nie daje na trasach agenta, a klucz agenta nic nie daje na płaszczyźnie modeli; każde wejście przyjmuje tylko jedną formę nagłówka. |
| 502 no credential configured for provider | Klucz agenta wskazuje dostawcę, dla którego nie ma powiązanego konta. Klucz wydaje tylko powiązane z nim subskrypcje i nigdy nie sięga po inne poświadczenia organizacji: powiąż konto tego dostawcy albo wskaż model obsługiwany przez powiązane konto. |
| Odświeżenie subskrypcji odrzucone | Dostawca trwale odrzucił odświeżenie, więc konto nie obsługuje żądań, dopóki człowiek nie podłączy go ponownie. Podłącz je ponownie w Konsoli; ta sama subskrypcja użyje istniejącego konta i jego istniejącej opłaty miesięcznej. |
| 400 mcp_servers is not supported | Deklaracja zdalnego MCP w treści Responses jest odrzucana przed wysłaniem, bo serwer osiągany z modelu ominąłby śluzę narzędzi. Zarejestruj serwer w Sluis i korzystaj z niego przez wejście MCP. |
| Brak fragmentów konfiguracji w Konsoli | Wdrożenie nie ma zweryfikowanego publicznego adresu bramy, więc gotowej konfiguracji nie da się pokazać. Ustaw SLUIS_GATEWAY_PUBLIC_URL, a potem odczytaj endpointy w zakładce Connections. |