# Werden Zugangsgrenzen für API-Subdomains tatsächlich durchgesetzt?

Ein Hostname ist kein Hinweis auf Eigentum. Er ist Teil der Zielidentität und entscheidet, wohin ein API-Zugangsschlüssel gesendet wird. Wenn ein Client einen Bearer-Token besitzt und `api.example.com`, `files.example.com`, `api.eu.example.com` und `customer.example.com` wegen ihres gemeinsamen Suffixes für im Grunde gleichwertig hält, hat der Client bereits die gefährliche Entscheidung getroffen.

Dieser Fehler versteckt sich hinter einer scheinbar übersichtlichen Architektur. Ein Unternehmen kann jeden Namen unter einer übergeordneten Domain besitzen. DNS kann mehrere Namen an denselben Load Balancer senden. Zertifikate können für alle Namen gelten. Nichts davon bedeutet, dass ein für eine API ausgestellter Zugangsschlüssel einen anderen Hostnamen erreichen sollte. Zugangsdaten brauchen eine ausdrückliche Zielregel. Für diese Regel braucht es Tests, die fehlschlagen, wenn sie später unbemerkt erweitert wird.

## Hostnamen übernehmen kein Vertrauen von einer übergeordneten Domain

`api.example.com` und `admin.example.com` können dieselbe registrierbare Domain haben, sind aber getrennte Origins. Ein Origin umfasst Schema, Host und Port. Auch `https://api.example.com` und `https://api.example.com:8443` sind getrennte Origins. Das ist wichtig, weil ein Client das Netzwerkziel anhand dieser Autorität auswählt, nicht anhand der Marketingbeziehung zwischen den Diensten.

RFC 9110 definiert einen HTTP-Authentifizierungsschutzbereich anhand des Origins und, falls vorhanden, einer Realm. Der Standard warnt außerdem davor, sich allein auf Realms zu verlassen, weil dadurch Zugangsdaten anderen Ressourcen auf einem Origin zugänglich werden können. Wenn verschiedene Parteien getrennt werden müssen, empfiehlt er separate Hostnamen oder Ports. Das ist ein nützlicher Hinweis, aber keine Erlaubnis, alle Namen unter einem Suffix als einen einzigen Schutzbereich zu behandeln.

Ingenieure vermischen häufig drei verschiedene Begriffe:

- Eine übergeordnete Domain benennt einen DNS-Namensraum.
- Eine Site gruppiert verwandte Web-Origins für bestimmte Browser-Sicherheitsregeln.
- Ein Origin identifiziert ein Schema, einen Host und einen Port für ein HTTP-Ziel.

Nur die ersten beiden lassen Subdomains verbunden wirken. Dein API-Zugangsschlüssel-Verteiler sollte das dritte Konzept verwenden.

Das gilt auch, wenn der Aussteller des Zugangsschlüssels einen breiten `aud`-Claim in einen Token schreibt. Ein breiter Audience-Claim sagt dem empfangenden Dienst, was er akzeptieren darf. Er weist deinen Client nicht an, den Token jedem Endpoint anzubieten, der ihn möglicherweise akzeptiert. Der Absender bleibt dafür verantwortlich, die Verteilung zu minimieren.

Ich habe diesen Fehler immer wieder in ähnlicher Form gesehen. Ein Team startet mit einem einzelnen Endpoint, fügt `api.staging.example.com` hinzu und behält einen Helfer namens `getApiKey()`. Sechs Monate später wird der Helfer von fünf Diensten verwendet. Er hat kein Host-Argument, keine Allowlist und keinen Grund, einen Aufruf abzulehnen. Der Schlüssel wurde nicht durch einen exotischen Exploit unsicher. Er wurde unsicher, weil der Code nicht mehr festhielt, dass der Schlüssel zu einem bestimmten Ziel gehörte.

Mache die Hostbindung in der Konfiguration und bei Code-Reviews sichtbar. Ein Zugangsschlüssel-Auswähler, der nur einen Namen für den Zugangsschlüssel akzeptiert, hat bereits die Hälfte seiner Eingabe verloren.

## Die vier Hostnamen-Formen scheitern auf unterschiedliche Weise

Benachbarte, Vanity-, regionale und kundenspezifische Domains brauchen eigene Testfälle, weil sie aus unterschiedlichen Gründen problematisch werden. Eine vage Zusicherung, dass ein Token innerhalb „unserer Domains“ bleibt, wird mindestens eine dieser Varianten übersehen.

Ein **benachbarter Host** liegt neben dem vorgesehenen Host: `metrics.example.com` statt `api.example.com`. Das kann einen gemeinsamen Ingress, einen alten Dienst oder ein internes Werkzeug offenlegen, das Produktionszugangsdaten nie sehen sollte. Besonders gefährlich wird ein solcher Host, wenn ein generischer Proxy Header unverändert an ein Upstream-System weiterleitet, das über die Routing-Konfiguration ausgewählt wurde.

Ein **Vanity-Host** ist ein freundlicher Alias wie `api.brand.example` oder `developer.example.com`. Anbieter führen solche Namen bei Umbenennungen, Übernahmen oder Migrationen ein. Der Alias kann an einem anderen Edge enden, eine andere Telemetrie verwenden oder auf einen kanonischen Host weiterleiten. Gewähre ihm keinen Zugriff auf Zugangsdaten, nur weil du einmal eine Weiterleitung in einem Browser gesehen hast.

Ein **regionaler Host** verändert den Standort und häufig auch den Besitz des Dienstes: `api.us.example.com`, `api.eu.example.com` oder `api.ap-southeast.example.com`. Die Anfrage kann bereits Geschäftsdaten enthalten, bevor die Anwendung den Token ablehnt. Eine 401-Antwort beweist nicht, dass es akzeptabel war, die Zugangsdaten und den Body an diese Region zu senden.

Ein **kundenspezifischer Host** verschärft Fehler in Multi-Tenant-Systemen: `acme.vendor.example` und `northwind.vendor.example` können über dieselbe Infrastruktur aufgelöst werden, doch jeder Hostname steht für eine Mandantengrenze. Ein Token, der an beiden funktioniert, kann für eine zentrale Steuerung absichtlich so breit sein. Er darf niemals zum Standard-Zugangsschlüssel für mandantenspezifische Anfragen werden.

Nimm jede Kategorie in dein Verzeichnis auf. Fasse sie nicht in einem Feld namens `allowed_domains` zusammen und nimm nicht an, dass eine Wildcard die Richtlinie einfacher macht. Die Wildcard verschiebt die schwierige Entscheidung nur aus dem Sichtfeld.

## Binde die Auswahl des Zugangsschlüssels an die vollständige Autorität

Ein sicherer Client ordnet einer Anfrageautorität genau einen Datensatz für Zugangsdaten zu und lehnt die Anfrage ab, wenn kein Datensatz passt. Die vollständige Autorität umfasst Schema, normalisierten Hostnamen und den tatsächlich verwendeten Port. Bei einer gewöhnlichen HTTPS-API auf Port 443 kann die sichtbare Konfiguration einfach bleiben. Die Implementierung muss einen unerwarteten Port aber trotzdem ablehnen, statt den Token stillschweigend wiederzuverwenden.

Ein brauchbares Verzeichnis sieht so aus:

```yaml
credentials:
  billing-production:
    allowed:
      - https://api.billing.example.com:443
    header: Authorization
    scheme: Bearer

  telemetry-eu:
    allowed:
      - https://ingest.eu.example.net:443
    header: X-Write-Key
```

Es geht nicht um YAML. Entscheidend ist, dass der Name des Tokens nicht für sich allein steht. `billing-production` hat ein ausdrücklich festgelegtes Ziel. `telemetry-eu` kann nicht an einen US-Endpoint gelangen, nur weil ein Aufrufer eine Hostnamen-Zeichenfolge geändert hat.

Vermeide dieses Muster:

```js
const headers = {
  Authorization: `Bearer ${process.env.PRODUCTION_API_TOKEN}`
};

await fetch(userSuppliedUrl, { headers });
```

Der Code verbindet ein uneingeschränktes Ziel mit einer privilegierten Zugangsinformation. Entwickler verteidigen das manchmal mit dem Hinweis, dass die URL aus einer vertrauenswürdigen Konfigurationsdatei stammt. Auch diese Datei ist eine Eingabegrenze. Deployment-Werkzeuge, Umgebungsüberschreibungen, Pull Requests, Feature-Flags und ein kompromittierter Build-Job können sie verändern.

Verwende einen Request-Builder, der authentifizierte Anfragen erst erstellt, nachdem er ein normalisiertes Ziel gefunden hat. Die Normalisierung des Hostnamens sollte streng und unspektakulär bleiben:

1. Analysiere die URL mit einem echten URL-Parser, nicht mit Zeichenketten- oder Suffixprüfungen.
2. Verlange `https:`, sofern keine dokumentierte Ausnahme für die lokale Entwicklung existiert.
3. Schreibe den Hostnamen klein und kanonisiere ihn über den Parser.
4. Vergleiche Schema, Host und Port mit exakt freigegebenen Autoritäten.
5. Füge den Authentifizierungs-Header erst hinzu, wenn der Abgleich erfolgreich war.

Schreibe nicht `host.endsWith("example.com")`. Dadurch wird `notexample.com` akzeptiert. Repariere das auch nicht einfach mit `endsWith(".example.com")` und erkläre die Arbeit für erledigt. Dieser Ausdruck gibt weiterhin jeder aktuellen und zukünftigen Subdomain den Token, auch Namen, die an einen Kunden, einen Anbieter oder eine vergessene Entwicklungsumgebung delegiert wurden.

Die Unterscheidung zwischen der Autorisierung des Ziels und der Autorisierung des Zugangsschlüssels muss klar bleiben. Eine empfangende API kann einen nicht passenden Token ablehnen. Dein Absender sollte verhindern, dass der Token diese API überhaupt erreicht. Die erste Kontrolle begrenzt die Offenlegung. Die zweite entscheidet über den Zugriff. Du brauchst beide.

## Eine Weiterleitung ist ein neues Ziel, keine Fortsetzung der alten Anfrage

Die Behandlung von Weiterleitungen schafft eine zweite Grenze für Zugangsdaten. Der erste Host kann genehmigt sein und anschließend einen `Location`-Header mit einem Vanity-Namen, einem regionalen Endpoint, Objektspeicher oder einem Host zurückgeben, den ein Angreifer über eine offene Weiterleitung kontrolliert. Folgt der Client automatisch, muss er die Zielautorisierung erneut ausführen, bevor er Zugangsdaten oder den Request-Body sendet.

libcurl macht den Unterschied besonders deutlich. Standardmäßig sendet es bei Weiterleitungen keine intern erzeugten Authentifizierungs- oder ausdrücklich gesetzten Cookie-Header an einen anderen Host. Die Option `CURLOPT_UNRESTRICTED_AUTH` ändert dieses Verhalten und kann Zugangsdaten an Hosts senden, die durch Weiterleitungsantworten ausgewählt wurden. Das curl-Projekt warnt, dass benutzerdefinierte Header besondere Vorsicht erfordern, weil die Bibliothek nicht erkennen kann, welche beliebigen Header Geheimnisse enthalten.

Gerade dieses Detail überrascht auch erfahrene Teams. Sie testen die Basic-Authentifizierung mit einem Standard-Client und sehen, dass sich eine hostübergreifende Weiterleitung sicher verhält. Dann verwendet ihre Produktionsintegration `X-Api-Key`, `Authorization: Bearer` oder `X-Signature` als generischen Header. Eine Bibliothek kann diesen Header beibehalten, wenn die Anwendung ihn nicht entfernt. Ein bestandener Test für einen Authentifizierungsmechanismus sagt nichts über einen anderen aus.

Behandle Weiterleitungen je nach Anfrageklasse:

- Lehne Weiterleitungen bei Schreibvorgängen ab, sofern der API-Vertrag sie nicht verlangt.
- Prüfe bei Lesevorgängen jedes Weiterleitungsziel und erstelle die Header anhand des für das Ziel genehmigten Datensatzes neu.
- Erstelle bei signierten Anfragen die Signatur erst nach der Autorisierung des endgültigen Ziels neu. Leite niemals eine für den ersten Host erstellte Signatur weiter.
- Leite bei Uploads den ursprünglichen Authorization-Header nicht an eine vorab signierte Speicher-URL weiter. Die Query-Signatur oder die Formularfelder enthalten bereits die begrenzte Berechtigung, die dieser Storage-Endpoint erwartet.

Ein Weiterleitungstest muss die Anfrage untersuchen, die am zweiten Server ankommt. Nur den finalen Statuscode zu prüfen, reicht nicht. Eine 200-Antwort von einem harmlosen Testempfänger kann verbergen, dass dieser den Produktions-Header erhalten hat, den du schützen wolltest.

Für Wiederholungen gilt dieselbe Disziplin. Manche HTTP-Wrapper bauen Anfragen aus einer zwischengespeicherten Header-Map neu auf. Wenn eine Wiederholung durch Service Discovery zu einer neuen Autorität führt, verwerfe die zwischengespeicherte Map und frage den Zugangsschlüssel-Auswähler erneut. Header wiederzuverwenden ist schneller. So verschwindet aber auch der Kontext des Ziels.

## Baue eine negative Testumgebung, bevor du der Allowlist vertraust

Der wichtige Test ist negativ: Ein Zugangsschlüssel muss am vorgesehenen Host auftauchen und darf nicht an jedem plausiblen falschen Host erscheinen. Du kannst das mit zwei lokalen HTTPS-Testservern ausführen. Der Empfänger darf jedoch nur erfassen, ob sensible Header vorhanden sind und wie sie heißen. Verwende in Testprotokollen keine echten Werte.

Für eine Prüfung auf Shell-Ebene kannst du harmlose Namen mit der curl-Option `--resolve` lokalen Servern zuordnen und einen Wegwerf-Token verwenden. Starte einen Empfänger auf Port 8443 für den genehmigten Host und einen zweiten auf Port 9443 für den benachbarten Host. Jeder Empfänger sollte einen Datensatz wie diesen ausgeben:

```text
host=api.test.example
path=/v1/ping
authorization=present
x-api-key=absent
```

Der Empfänger des benachbarten Hosts sollte das umgekehrte Ergebnis ausgeben:

```text
host=metrics.test.example
path=/v1/ping
authorization=absent
x-api-key=absent
```

Führe anschließend den tatsächlichen HTTP-Client-Wrapper aus, nicht eine isolierte Version seiner Logik. Eine curl-Prüfung kann die grundlegende Verdrahtung sichtbar machen:

```bash
curl --silent --show-error \\
  --resolve api.test.example:8443:127.0.0.1 \\
  --header 'Authorization: Bearer test-token-do-not-use' \\
  https://api.test.example:8443/v1/ping
```

Dieser Befehl setzt den Header absichtlich auf der Anfrage. Er beweist daher nur, was der Empfänger protokolliert. Er beweist nicht, dass deine Anwendung Zugangsdaten sicher auswählt. Dein Anwendungstest sollte die normale Funktion `request()` mit derselben genehmigten Autorität aufrufen, dann mit jeder falschen Autorität wiederholt werden und prüfen, dass vor dem Öffnen einer Verbindung ein Fehler ausgelöst wird.

Verwende eine Matrix, die Entscheidungen erzwingt, die sonst oft stillschweigend vorausgesetzt werden:

| Angeforderte Autorität | Erwartetes Verhalten bei Zugangsdaten |
| --- | --- |
| `https://api.test.example` | Den vorgesehenen Test-Zugangsschlüssel senden |
| `https://metrics.test.example` | Vor dem Senden ablehnen |
| `https://api.eu.test.example` | Ablehnen, sofern nicht separat konfiguriert |
| `https://tenant-a.test.example` | Ablehnen, sofern die Mandantenbindung nicht ausdrücklich festgelegt ist |
| Genehmigter Host leitet an benachbarten Host weiter | Nur nach erneuter Autorisierung folgen, normalerweise ohne die ursprünglichen Zugangsdaten |

Verwende für diesen Test keinen externen Request-Bin-Dienst. Du würdest deinem Team beibringen, Testgeheimnisse an einen Dritten zu senden, während es prüft, ob es Geheimnisse an Dritte sendet. Ein lokaler Empfänger ist trivial und hält die Belege unter deiner Kontrolle.

Nimm die Matrix in die kontinuierliche Integration auf. Ein Unit-Test für `isAllowedHost()` ist hilfreich. Ein Integrationstest erfasst jedoch die häufige Regression: Jemand fügt einer tieferen HTTP-Schicht einen Standard-Header hinzu, nachdem die Hostprüfung bereits stattgefunden hat.

## Browserregeln gelten nicht automatisch für Agenten

Die Sprache des Browsers führt in Agenten- und Backend-Code zu falschen Annahmen. „Same-Site“ kann Subdomains einschließen, „Same-Origin“ dagegen nicht. MDN verwendet `https://example.org` und `https://login.example.org` als Beispiel für zwei Origins, die zur selben Site gehören. Diese Unterscheidung gibt es auch deshalb, weil eine kompromittierte Subdomain einen benachbarten Host über Same-Site-Pfade angreifen kann.

Fetch verwendet standardmäßig `credentials: "same-origin"`. Dadurch werden Zugangsdaten bei Cross-Origin-Anfragen nicht automatisch mitgesendet. Ein Entwickler kann diesen Standard sehen, einen Frontend-Aufruf testen und daraus schließen, dass ein Bearer-Token nicht von einer Subdomain zu einer anderen gelangen kann. Diese Schlussfolgerung gilt nicht für serverseitigen Code. Ein Backend-Fetch-Wrapper kann jeden Header anhängen, den sein Autor vorgibt. Eine CLI kann dasselbe tun. Ein autonomer Agent kann ein generisches HTTP-Werkzeug mit URL und Headern aufrufen, sofern das Werkzeug die Zugangsdaten nicht außerhalb seiner Reichweite hält.

CORS behebt das nicht. CORS steuert hauptsächlich, ob JavaScript im Browser eine Antwort lesen kann. Es macht aus einem breit angelegten serverseitigen Header-Injektor keinen sicheren Zugangsschlüssel-Verteiler. Bei manchen Browseranfragen kann der Browser die Zugangsdaten senden und anschließend verhindern, dass das Skript die Antwort sieht. Das ist keine akzeptable Kontrolle zur Vermeidung von Datenverlust.

Cookies sorgen für eine weitere Verwechslung. Domain-Attribute von Cookies können erlauben, dass ein Cookie Subdomains erreicht, während hostgebundene Cookies das nicht tun. Bearer-Header haben keinen vergleichbaren eingebauten Domainbereich. Wenn dein Client `Authorization` anhängt, hat er für diese Anfrage eine ausdrückliche Entscheidung getroffen. Übertrage keine Cookie-Denkmodelle auf API-Schlüssel.

## Kundendomains brauchen eine Ausstellergrenze, keine Namenskonvention

Eine zentrale API kann berechtigt sein, viele Kunden-Endpoints aufzurufen. Sie braucht dafür aber Zugangsdaten, aus denen hervorgeht, warum der Aufruf Mandantengrenzen überschreiten darf. Am sichersten ist ein eigener, eng begrenzter Datensatz für Zugangsdaten pro Kunden-Host. Die zweitbeste Lösung verwendet einen kurzlebigen Token mit Audience- und Mandanten-Claims, die das Ziel prüft, sowie einer Client-Allowlist, in der weiterhin jeder zulässige Host genannt wird.

Ein globaler Token mit einer breiten Rolle ist beliebt, weil das Onboarding einfach wird. Mandanten hinzufügen, die Integration auf die Subdomain zeigen lassen und der Aufruf funktioniert. Dieselbe Bequemlichkeit ermöglicht es aber, dass ein Tippfehler, eine bösartige Konfigurationsänderung oder ein verwirrter Agent den Dienst eines anderen Kunden mit Zugangsdaten erreicht, die keine sinnvolle Zielbegrenzung haben.

Löse das nicht mit `*.customers.example.com` als genehmigtem Muster und der Annahme, jeder Treffer sei ein Kunde. Frage, wer diese Namen anlegen kann, wer DNS delegieren darf, welche Hosts zu Vorschauumgebungen routen und ob Namen nach der Kündigung eines Kunden bestehen bleiben. Eine Wildcard macht all diese Fragen zu Sicherheitsentscheidungen, meist ohne einen Prüfvermerk zu hinterlassen.

Es gibt Fälle, in denen eine kontrollierte Wildcard angemessen ist. Ein Anbieter kann mandantenbezogene Token ausstellen, die einen Mandanten-Identifier enthalten. Der Dienst lehnt Abweichungen ab, und ein internes Verzeichnis prüft den Mandanten-Host, bevor der Client sendet. In diesem Design ist die Wildcard nicht die Autorisierungsregel. Sie ist nur eine begrenzte Vereinfachung hinter einem maßgeblichen Mandantenverzeichnis. Wenn du dieses Verzeichnis und sein Fehlerverhalten nicht benennen und testen kannst, verwende exakte Einträge.

Private DNS erzeugt dasselbe Problem innerhalb eines Unternehmens. `payments.prod.internal` und `payments.dev.internal` sind möglicherweise keine öffentlichen Namen, aber unterschiedliche Ziele mit unterschiedlichen betrieblichen Kontrollen. Internes DNS ersetzt keine Begrenzung von Zugangsdaten.

## Hostprüfungen müssen vor Discovery und nach der Normalisierung erfolgen

Service Discovery, benutzerdefiniertes Routing und Proxy-Konfigurationen können eine ansonsten sinnvolle Allowlist unbemerkt umgehen. Prüft der Code die ursprüngliche URL und ersetzt ein Resolver anschließend das interne Ziel, kann die Anwendung Zugangsdaten an eine andere Autorität senden. Umgekehrt kann eine Prüfung, die einen veränderbaren `Host`-Header verwendet, eine Anfrage genehmigen, deren Netzwerkverbindung woanders endet.

Verwende die Autorität der geparsten URL als Richtlinieneingabe. Stelle die TLS-Verbindung für diese Autorität her und prüfe das Zertifikat wie üblich. Deaktiviere die Zertifikatsprüfung nicht, um eine interne Route oder ein Test-Fixture zum Laufen zu bringen. Die Sicherheitshinweise von curl sagen ausdrücklich, dass ein Client, der die Gegenstelle nicht authentifizieren kann, nicht wissen kann, ob er den vorgesehenen Server erreicht hat.

Entscheide anschließend, was dein Vertrauensmodell über Proxys sagt. Ein Forward-Proxy ist eine Transportentscheidung und kein neues Ziel für Zugangsdaten, wenn der Client darüber eine TLS-Verbindung zum genehmigten Origin herstellt. Ein Reverse-Proxy, der TLS beendet, gehört zur Servicegrenze und muss genauso sorgfältig geprüft werden wie die API selbst. Ein HTTP-Proxy, der unverschlüsselte Authorization-Header erhält, hat Zugriff auf die Zugangsdaten. Nenne dieses Detail nicht einfach „Infrastruktur“.

Normalisiere internationalisierte Hostnamen über eine standardkonforme URL-Implementierung und vergleiche das kanonische Ergebnis. Lehne Userinfo in URLs wie `https://token@api.example.com/` ab. Zugangsdaten in URLs gelangen in Protokolle, den Verlauf und Debugging-Ausgaben. Lehne Fragmente bei HTTP-Anfragen ab und entscheide ausdrücklich, ob Query-Strings vorab signierte Zugangsdaten enthalten dürfen. Eine allgemeine Bereinigungsfunktion kann kein Design retten, das jede URL akzeptiert und erst später versucht, schlechte URLs zu erkennen.

Die entscheidende Reihenfolge ist einfach: parsen, normalisieren, Ziel autorisieren, Zugangsschlüssel auswählen, Header erstellen, verbinden. Wenn eine spätere Operation die Autorität ändert, beginne wieder bei der Zielautorisierung.

## Die Entscheidung protokollieren, nicht das Geheimnis

Ein Audit-Eintrag sollte belegen, welches Ziel der Client betrachtet und welche Regel für Zugangsdaten er ausgewählt hat, ohne das Geheimnis zu speichern. Du brauchst diesen Eintrag, wenn jemand wissen möchte, ob ein Token nach einer Deployment-Änderung einen benachbarten Host hätte erreichen können.

Speichere Felder wie Request-ID, Zeitpunkt, normalisierte Autorität, ID des Zugangsschlüsseldatensatzes, Autorisierungsergebnis, Quelle und Ziel einer Weiterleitung sowie einen Ergebnisc code. Hash oder maskiere Pfade, wenn sie Kundenkennungen enthalten. Protokolliere weder `Authorization`, benutzerdefinierte Schlüssel-Header, Query-Strings mit Signaturen noch vollständige Request-Bodies, nur weil sie beim Debugging hilfreich wären.

Ein guter Audit-Eintrag beantwortet eine konkrete Frage:

```text
request_id=01J...
authority=https://api.billing.example.com:443
credential=billing-production
destination_check=allowed
redirect_count=0
result=201
```

Bei einer abgelehnten Anfrage an einen benachbarten Host sollte der Eintrag `credential=none` und `destination_check=denied` zeigen. Dieser Unterschied belegt, dass der Client die Anfrage ablehnte, bevor er ein Geheimnis auswählte. Wenn das Protokoll stattdessen einen Namen für die Zugangsdaten nennt und anschließend einen 403 vom falschen Host meldet, hat das System bereits mehr gesendet, als es sollte.

Sallyport hält das Geheimnis in seinem verschlüsselten Tresor und bewertet eine Aktion, bevor der Agent Zugangsdaten erhält. Das Aktivitätsjournal und das Sitzungsjournal geben Teams die Möglichkeit, den Aktionspfad zu prüfen und eine laufende Agentensitzung zu widerrufen, wenn eine hostgebundene Anfrage schiefgeht.

Beginne mit dem Verzeichnis. Schreibe für jeden Zugangsschlüssel eine vorgesehene Autorität auf und nenne anschließend einen benachbarten, einen Vanity- oder Migrationsnamen, einen regionalen und einen kundenspezifischen Namen, die ihn nicht erhalten dürfen. Wenn dein Client diese negativen Aussagen heute nicht treffen kann, besitzt er keine Grenze für Zugangsdaten. Er hat nur eine hoffnungsvolle Konvention.
