API-Server-Konfiguration
Der Bencher API-Server erfordert eine JSON-Konfiguration beim Start. Die Konfiguration kann auf drei Arten bereitgestellt werden:
BENCHER_CONFIGUmgebungsvariable: Der Wert sollte auf die JSON-Konfiguration gesetzt seinBENCHER_CONFIG_PATHUmgebungsvariable: Der Wert sollte auf den Pfad einer Datei gesetzt sein, die die JSON-Konfiguration enthält/etc/bencher/bencher.jsonDatei: Eine Datei an diesem Ort, die die JSON-Konfiguration enthält
Wenn keine Konfiguration gefunden wird, wird eine Standardkonfiguration geladen.
Beispiel einer JSON-Konfiguration:
{ "console": { "url": "https://bencher.example.com" }, "security": { "issuer": "https://api.bencher.example.com", "secret_key": "UJu7Cpxb-zFaJYqXD-3mDDSDyj-ZvfxZFZs-X58xjxPy" }, "server": { "bind_address": "0.0.0.0:6610", "request_body_max_bytes": 1048576, "tls": { "type": "as_file", "cert_file": "/path/to/cert.pem", "key_file": "/path/to/key.pem" } }, "logging": { "name": "Bencher API", "log": { "stderr_terminal": { "level": "info" } } }, "database": { "file": "/var/lib/bencher/data/bencher.db", "busy_timeout": 5000, "cache_size": 65536 }, "smtp": { "hostname": "mailbonobo.com", "port": 587, "starttls": true, "username": "bencher", "secret": "WM3F2u9cqSNdBPLfy9sJ5kk9", "from_name": "Bencher", "from_email": "info@bencher.example.com" }, "plus": { "disaster_recovery": { "replica": { "scheme": "s3", "bucket": "my-bucket", "path": "path/to/replicate", "access_key_id": "ABC123DoRemMiABC123", "secret_access_key": "AA3Chr-JSF5sUQqKwayx-FvCfZKsMev-5BqPpcFC3m7" } }, "registry": { "url": "https://registry.bencher.example.com", "storage": { "scheme": "s3", "bucket": "my-bucket", "path": "registry", "endpoint": "https://s3.example.com", "region": "auto", "access_key_id": "AKIAIOSFODNN7EXAMPLE", "secret_access_key": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", "chunk_size": 5242880 }, "upload_timeout": 3600, "max_body_size": 1073741824 }, "runners": { "heartbeat_timeout": 90, "job_timeout_grace_period": 60, "update_base_url": "https://github.com/bencherdev/bencher/releases/download/" }, "rate_limiting": { "window": 86400, "unclaimed_limit": 255, "claimed_limit": 65536, "plus_limit": 1048576, "public": { "requests": { "minute": 1024, "hour": 4096, "day": 8192 }, "attempts": { "minute": 32, "hour": 64, "day": 128 }, "runs": { "minute": 64, "hour": 128, "day": 256 } }, "user": { "requests": { "minute": 2048, "hour": 8192, "day": 16384 }, "attempts": { "minute": 2, "hour": 4, "day": 8 }, "credentials": { "minute": 4, "hour": 8, "day": 16 }, "organizations": { "minute": 2, "hour": 4, "day": 8 }, "invites": { "minute": 8, "hour": 16, "day": 32 }, "runs": { "minute": 64, "hour": 1024, "day": 4096 } }, "project": { "requests": { "minute": 2048, "hour": 8192, "day": 16384 }, "runs": { "minute": 64, "hour": 1024, "day": 4096 } }, "runner": { "requests": { "minute": 16, "hour": 256, "day": 4096 } }, "oci_bandwidth": { "unclaimed": 1073741824, "free": 10737418240, "plus": 107374182400 } }, "stats": { "offset": 11242, "enabled": true }, "mcp": { "openai_apps_challenge": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6" }, "oauth": { "issuer": "https://api.bencher.example.com", "resources": [ "https://mcp.bencher.example.com/mcp", "https://api.bencher.example.com/mcp" ], "signing_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASC...\n-----END PRIVATE KEY-----\n" } }}console
| Name | Beispiel | Standard | Erforderlich | Beschreibung |
|---|---|---|---|---|
| url | “https://bencher.example.com” | “http://localhost:3000” | Ja | Legt die URL für den Bencher UI-Konsolenhost fest. |
security
| Name | Beispiel | Standard | Erforderlich | Beschreibung |
|---|---|---|---|---|
| issuer | “https://api.bencher.example.com” | “bencher.dev” | Nein | Gibt den JWT (JSON Web Token) Aussteller an. WARNUNG Änderungen dieses Wertes führen dazu, dass alle zuvor generierten JWTs nicht mehr validiert werden. |
| secret_key | “UJu7Cpxb-zFaJYqXD-3mDDSDyj-ZvfxZFZs-X58xjxPy” | Zufällige UUID v4 | Ja | Gibt den Schlüssel an, der zur Generierung aller Tokens und zum Versiegeln ausstehender Callbacks verwendet wird. ES SOLLTE SEHR SICHER SEIN! Der Standardwert ist eine zufällig generierte UUID v4. Jedes Mal, wenn es protokolliert wird, wird es als ************ verschleiert dargestellt. |
server
Dieser Abschnitt basiert auf der Dropshot-Serverkonfiguration.
| Name | Beispiel | Standard | Erforderlich | Beschreibung |
|---|---|---|---|---|
| bind_address | “0.0.0.0:6610” | “0.0.0.0:6610” | Ja | Legt fest, dass der Server an die angegebene IP-Adresse und den TCP-Port gebunden sein sollte. Im Allgemeinen können Server an mehr als eine IP-Adresse und Port gebunden sein, dies wird jedoch (noch?) nicht unterstützt. |
| request_body_max_bytes | 1048576 | 1048576 | Ja | Gibt die maximale Anzahl von Bytes an, die in einem Anforderungskörper zulässig sind. Größere Anfragen erhalten einen 400 Fehler. |
| tls.type | “als_datei” | — | Nein | Gibt an, ob und wie TLS-Zertifikat- und Schlüsselinformationen bereitgestellt werden. Gültige Werte sind “als_datei” und “als_bytes”. |
| tls.cert_file | “/path/to/cert.pem” | — | Nur wenn tls.type = as_file | Gibt den Pfad zu einer PEM-Datei an, die eine Zertifikatskette enthält, mit der sich der Server identifiziert. Das erste Zertifikat ist das End-Entity-Zertifikat und die verbleibenden sind Zwischenzertifikate auf dem Weg zu einer vertrauenswürdigen CA. Wenn angegeben, hört der Server nur auf TLS-Verbindungen. |
| tls.key_file | “/path/to/key.pem” | — | Nur wenn tls.type = as_file | Gibt den Pfad zu einer PEM-kodierten PKCS #8-Datei an, die den privaten Schlüssel enthält, den der Server verwenden wird. Wenn angegeben, hört der Server nur auf TLS-Verbindungen. |
| tls.certs | — | — | Nur wenn tls.type = as_bytes | Identisch mit tls.cert_file, jedoch als Array von Bytes von Zertifikatsdaten bereitgestellt. |
| tls.key | — | — | Nur wenn tls.type = as_bytes | Identisch mit tls.key_file, jedoch als Array von Bytes von Schlüsseldaten bereitgestellt. |
logging
Dieser Abschnitt basiert auf der Dropshot Logging Konfiguration.
| Name | Beispiel | Standard | Erforderlich | Beschreibung |
|---|---|---|---|---|
| name | “Bencher API” | “Bencher API” | Ja | Gibt den Namen des Loggers an. |
| log.level | “info” | “info” | Ja | Gibt an, wie schwerwiegend die Protokollnachrichten sein sollten, die im Protokoll enthalten sind. Gültige Werte sind “trace”, “debug”, “info”, “warn”, “error” und “critical”, die in aufsteigender Reihenfolge der Schweregrad sind. Protokollnachrichten der angegebenen Stufe und schwerwiegendere Stufen werden im Protokoll enthalten sein. |
| log.path | — | — | Nur wenn log.mode = “file” | Wenn log.mode “file” ist, bestimmt diese Eigenschaft den Pfad zur Protokolldatei. Siehe auch log.if_exists. |
| log.if_exists | — | — | Nur wenn log.mode = “file” | Wenn log.mode “file” ist, wird durch diese Eigenschaft festgelegt, was passieren soll, wenn die Zielprotokolldatei bereits existiert. Gültige Werte sind “append” (hierbei wird zur vorhandenen Datei hinzugefügt), “truncate” (hierbei wird die vorhandene Datei abgeschnitten und dann verwendet, als ob sie gerade erstellt worden wäre) und “fail” (hierbei beendet der Server sofort mit einem Fehler). |
database
| Name | Beispiel | Standard | Erforderlich | Beschreibung |
|---|---|---|---|---|
| file | “pfad/zu/database.db” | “/var/lib/bencher/data/bencher.db” | Ja | Legt fest, wo die Serverdatenbank hingehen soll. |
| busy_timeout | 5000 | 5000 | Nein | Gibt den Busy-Timeout für die Datenbank in Millisekunden an. Verhindert sofortige SQLITE_BUSY-Fehler bei Sperrkonflikten. |
| cache_size | 65536 | 65536 | Nein | Gibt die Seiten-Cache-Größe in KiB für die Schreibverbindung der Datenbank an. Ein größerer Cache vermeidet das erneute Lesen verdrängter Seiten bei großen Report-Importen und -Löschungen. Muss größer als 0 sein. |
smtp
Dieser Abschnitt spezifiziert eine SMTP-Dienstkonfiguration. Der gesamte Abschnitt ist optional. Wenn nicht angegeben, werden alle Nachrichten stattdessen an logging gesendet.
| Name | Beispiel | Standard | Erforderlich | Beschreibung |
|---|---|---|---|---|
| hostname | “mailbonobo.com” | — | Ja | Spezifiziert den SMTP-Hostname. |
| port | 587 | 587 | Nein | Spezifiziert den SMTP-Port. |
| insecure_host | — | false | Nein | Bestimmt, ob die SMTP-Verbindung ungültige TLS-Zertifikate zulassen kann. |
| starttls | true | true | Nein | Bestimmt, ob die SMTP-Verbindung das STARTTLS-Protokoll verwendet. |
| username | “bencher” | — | Ja | Spezifiziert den Benutzernamen beim SMTP-Host. |
| secret | “WM3F2u9cqSNdBPLfy9sJ5kk9” | — | Ja | Spezifiziert das Geheimnis für den Benutzernamen beim SMTP-Host. Wann immer es protokolliert wird, erscheint es verschleiert als ************. |
| from_name | “Bencher” | — | Ja | Spezifiziert den Namen, der im Absender-Bereich aller E-Mails angezeigt wird. |
| from_email | “info@bencher.example.com” | — | Ja | Spezifiziert die E-Mail-Adresse, die im Absender-Bereich aller E-Mails angezeigt wird. |
plus
Dieser Abschnitt betrifft Funktionen, die von der Bencher Plus-Lizenz abgedeckt sind.
plus.github
Dieser Abschnitt spezifiziert die Konfiguration für eine GitHub App, die für die OAuth2-Authentifizierung verwendet wird. Sie müssen eine gültige Bencher Plus Enterprise Lizenz für mindestens eine Organisation auf dem Server haben. Der gesamte Abschnitt ist optional. Wenn er nicht angegeben ist, wird die Authentifizierung mit GitHub nicht aktiviert.
| Name | Beispiel | Standard | Erforderlich | Beschreibung |
|---|---|---|---|---|
| client_id | Iv1.12864abcd1232048 | — | Ja | Gibt die Client-ID für Ihre GitHub App an. Die Client-ID unterscheidet sich von der App-ID. Sie können die Client-ID auf der Einstellungsseite für Ihre App finden. Weitere Informationen zur Navigation zur Einstellungsseite für Ihre GitHub App finden Sie unter Ändern einer GitHub App-Registrierung. |
| client_secret | 00000abcd12345wxyz123456789abcdefgh0000 | — | Ja | Das Client-Geheimnis für Ihre GitHub App. Sie können ein Client-Geheimnis auf der Einstellungsseite für Ihre App generieren. |
plus.google
Dieser Abschnitt legt die Konfiguration für einen Google-Client zur OAuth2-Authentifizierung fest. Sie müssen für mindestens eine Organisation auf dem Server über eine gültige Bencher Plus Enterprise-Lizenz verfügen. Der gesamte Abschnitt ist optional. Wird er nicht angegeben, wird die Authentifizierung mit Google nicht aktiviert.
| Name | Beispiel | Standard | Erforderlich | Beschreibung |
|---|---|---|---|---|
| client_id | 0123456789-abcdefg0112358envs.apps.googleusercontent.com | — | Ja | Gibt die Client-ID für Ihren Google-OAuth2-Client an. |
| client_secret | GOCSPX-xyz987654321 | — | Ja | Das Client-Secret für Ihren Google-OAuth2-Client. |
plus.disaster_recovery
Dieser Abschnitt spezifiziert die Konfiguration der Notfallwiederherstellung. Bencher unterstützt das kontinuierliche Replizieren aller Datenbankänderungen.
Es gibt zwei Replikations-schemes:
file: Replikation zu einem lokalen Dateipfadpath: Pfad, zu dem repliziert wird
s3: Replikation zu einem S3-kompatiblen Blob-Speicherbucket: Bucket-Namepath: (Optional) Pfad im Bucketendpoint: (AWS: Optional | Nicht-AWS: Erforderlich) Replikationsendpunktregion: (Optional) Bucket-Regionaccess_key_id: S3-Zugangsschlüsselsecret_access_key: S3-Geheimzugangsschlüssel
Beide Replikations-schemes haben die folgenden zusätzlichen Optionen:
snapshot.interval: (Optional) Gibt an, wie oft neue Schnappschüsse erstellt werden. Dies wird verwendet, um die Zeit für die Wiederherstellung zu verkürzen, da neuere Schnappschüsse weniger WAL-Frames zum Anwenden haben. Die Aufbewahrung gilt auch für diese Schnappschüsse. Wenn Sie kein Schnappschussintervall festlegen, wird ein neuer Schnappschuss erstellt, wann immer die Aufbewahrung durchgeführt wird. Die Aufbewahrung erfolgt standardmäßig alle 24 Stunden.snapshot.retention: (Optional) Die Dauer, die Schnappschuss- und WAL-Dateien aufbewahrt werden. Nach dem Ablauf der Aufbewahrungsfrist wird ein neuer Schnappschuss erstellt und der alte entfernt. WAL-Dateien, die vor dem ältesten Schnappschuss existieren, werden ebenfalls entfernt. Standardwert ist24h.validation.interval: (Optional) Wenn angegeben, wird Bencher automatisch wiederherstellen und validieren, dass die Daten auf der Replik mit der lokalen Kopie übereinstimmen. Standardmäßig deaktiviert. Das Aktivieren kann die Kosten für den Betrieb von Bencher erheblich erhöhen, da die meisten Cloud-Services Gebühren für Downloads erheben.sync_interval: (Optional) Häufigkeit, mit der Frames zur Replik übertragen werden. Standardwert ist1s. Eine höhere Frequenz kann die Kosten für Cloud-Speicher erheblich erhöhen.checkpoint.interval: (Optional) Wie häufig Litestream einen nicht-blockierenden PASSIVE-Checkpoint durchführt, unabhängig von der Seitenanzahl. Litestream überspringt den Checkpoint, wenn Leser oder Schreiber aktiv sind. Standardwert ist1m.checkpoint.min_page_count: (Optional) Mindestanzahl an WAL-Seiten, bevor ein nicht-blockierender PASSIVE-Checkpoint ausgelöst wird (~4KB pro Seite). Litestream überspringt den Checkpoint, wenn Leser oder Schreiber aktiv sind. Standardwert ist1000(~4MB).checkpoint.truncate_page_n: (Optional) Schwellenwert der Seitenanzahl für einen blockierenden TRUNCATE-Checkpoint. Wenn dieser Schwellenwert erreicht wird, führt Litestream einen blockierenden Checkpoint durch, der auf den Abschluss aller Leser und Schreiber wartet, was zudatabase is locked-Fehlern unter Last führen kann. Standardwert ist0(deaktiviert). Setzen Sie diesen Wert nur dann auf einen Wert ungleich Null, wenn Sie eine Obergrenze für die WAL-Dateigröße benötigen und die Auswirkungen der Blockierung verstehen.
| Name | Beispiel | Standardwert | Erforderlich | Beschreibung |
|---|---|---|---|---|
| replica | { … } | — | Ja | Gibt ein Replikationsobjekt an. |
| replica.scheme | “s3” | — | Ja | Gibt das Replikationsschema an. Für alle anderen replica-Schlüssel siehe die obige Liste. |
| snapshot.interval | “1h” | — | Nein | Wie oft neue Schnappschüsse erstellt werden. Verkürzt die Wiederherstellungszeit. |
| snapshot.retention | “24h” | 24h | Nein | Wie lange Schnappschuss- und WAL-Dateien aufbewahrt werden, bevor sie ersetzt werden. |
| validation.interval | “6h” | — | Nein | Wie oft Replikdaten wiederhergestellt und gegen die lokale Kopie validiert werden. Standardmäßig deaktiviert. |
| checkpoint.interval | “1m” | 1m | Nein | Wie oft ein nicht-blockierender PASSIVE-Checkpoint ausgeführt wird. Wird übersprungen, wenn Leser/Schreiber aktiv sind. |
| checkpoint.min_page_count | 1000 | 1000 | Nein | Mindestanzahl WAL-Seiten (~4KB pro Seite) vor einem PASSIVE-Checkpoint. Wird übersprungen, wenn Leser/Schreiber aktiv sind. |
| checkpoint.truncate_page_n | 0 | 0 | Nein | Seitenschwellenwert für einen blockierenden TRUNCATE-Checkpoint. 0 deaktiviert. Werte ungleich Null können database is locked-Fehler unter Last verursachen. |
plus.registry
Dieser Abschnitt spezifiziert die OCI (Open Container Initiative) Registry-Speicherkonfiguration. Bencher kann als OCI-kompatible Container-/Artefakt-Registry fungieren.
Wenn dieser Abschnitt nicht konfiguriert ist, verwendet Bencher den lokalen Dateisystemspeicher
in einem registry-Verzeichnis neben der Datenbankdatei.
Dies ist geeignet für Entwicklung und Einzelinstanz-Deployments.
Für Produktions-Deployments mit mehreren Instanzen oder für Dauerhaftigkeit konfigurieren Sie S3-kompatiblen Speicher.
Es gibt zwei Speicher-schemes:
file: OCI-Artefakte im lokalen Dateisystem speichern (Standard)path: (Optional) Verzeichnis für Registry-Daten. Standardmäßig einregistry-Verzeichnis neben der Datenbankdatei.
s3: OCI-Artefakte in einem S3-kompatiblen Blob-Speicher speichernbucket: Bucket-Namepath: (Optional) Schlüsselpräfix im Bucket. Führende, abschließende und wiederholte Schrägstriche werden entfernt, sodassregistry,registry/und/registryalle unterregistryspeichern.endpoint: (AWS: Optional | Nicht-AWS: Erforderlich) Speicherendpunktregion: (Optional) Bucket-Region. Erforderlich für AWS. Standardmäßigauto, was S3-kompatible Speicher erwarten.access_key_id: S3-Zugangsschlüsselsecret_access_key: S3-Geheimzugangsschlüsselchunk_size: (Optional) Minimale Chunk-Größe in Bytes für die Pufferung von Upload-Daten vor dem Speichern. Standard: 5 MB. HTTP-Anfragekörper kommen als kleine Netzwerk-Frames an (typischerweise 8 bis 64 KB). Ohne Pufferung wird jeder Frame als separates Objekt gespeichert, was Tausende von Objekten pro Layer erzeugt. Dieser Wert entspricht auch der minimalen S3-Multipart-Upload-Teilgröße.
Legen Sie eine Bucket-Lebenszyklusregel fest, die unvollständige Multipart-Uploads abbricht. Ein Absturz während des Abschlusses eines Blob-Uploads hinterlässt einen solchen, und der Server bricht ihn nicht ab.
Wenn Sie zuvor einen path konfiguriert haben, der mit einem Schrägstrich begann oder endete, verschieben Sie die vorhandenen Objekte vor dem Upgrade auf das normalisierte Präfix. Ein path von registry/ speicherte Schlüssel unter registry//<project>/... und speichert sie jetzt unter registry/<project>/.... Jedes Segment von path wird im gespeicherten Schlüssel außerdem prozentcodiert, wo es ein ASCII-Steuerzeichen, ein Nicht-ASCII-Zeichen oder eines von \ {` `^` `} % ` ] " > [ ~ < # | * ? enthält, und ein Segment, das genau . oder .. ist, wird als %2E oder %2E%2E gespeichert. Alle anderen Zeichen, einschließlich Leerzeichen, +, =, @ und :, werden unverändert gespeichert, sodass team#1 zu team%231 wird, während team+1 als team+1 bleibt. Daten unter einem Präfix, das jetzt codiert wird, benötigen dieselbe Verschiebung. Listen Sie vor dem Verschieben von Daten die tatsächlich im Bucket gespeicherten Schlüssel auf und vergleichen Sie sie mit dem neuen Präfix.
| Name | Beispiel | Standardwert | Erforderlich | Beschreibung |
|---|---|---|---|---|
| url | “https://registry.bencher.example.com” | “http://localhost:6610” | Nein | Die extern erreichbare URL des API-Servers für OCI-Registry-Zugriff. |
| storage | { … } | — | Nein | Gibt das Registry-Speicher-Backend an. Lokale Dateien wenn weggelassen. |
| storage.scheme | “s3” | — | Ja | Gibt das Speicher-scheme an. Für alle anderen storage-Schlüssel siehe die Liste oben. |
| upload_timeout | 3600 | 3600 | Nein | Upload-Sitzungs-Timeout in Sekunden. Veraltete Uploads werden bei neuen Uploads bereinigt. |
| max_body_size | 1073741824 | 1073741824 | Nein | Maximale Body-Größe in Bytes für Blob- und Manifest-Uploads. Anfragen, die dieses Limit überschreiten, werden mit 413 Payload Too Large abgelehnt. Standard: 1 GiB. |
plus.runners
Dieser Abschnitt konfiguriert das Runner-System für die Bare-Metal-Benchmark-Ausführung. Runner sind serverseitige Agenten, die Benchmark-Jobs beanspruchen und ausführen.
Wenn dieser Abschnitt nicht konfiguriert ist, verwendet Bencher die Standardwerte.
| Name | Beispiel | Standardwert | Erforderlich | Beschreibung |
|---|---|---|---|---|
| heartbeat_timeout | 90 | 90 | Nein | Zeit in Sekunden ohne Heartbeat, bevor ein Job als unbekannt markiert wird. |
| job_timeout_grace_period | 60 | 60 | Nein | Zusätzliche Zeit in Sekunden über das konfigurierte Timeout eines Jobs hinaus, bevor der Server ihn abbricht. |
| update_base_url | https://example.com/downloads/ | GitHub Releases | Nein | Basis-URL für Runner-Selbstaktualisierungs-Downloads. Standardmäßig die Download-URL der Bencher GitHub Releases. |
plus.rate_limiting
Dieser Abschnitt spezifiziert die Ratenbegrenzung für den API-Server. Der gesamte Abschnitt ist optional. Wenn nicht angegeben, werden die aufgelisteten Standardwerte verwendet.
Um zu verhindern, dass unclaimed Projekte erstellt werden, setzen Sie unclaimed_limit auf 0.
| Name | Beispiel | Standard | Erforderlich | Beschreibung |
|---|---|---|---|---|
| window | 86400 | 86400 | Nein | Spezifiziert das Fenster für die Ratenbegrenzung in Sekunden. Standardmäßig auf einen Tag gesetzt. |
| unclaimed_limit | 255 | 255 | Nein | Kontrolliert die Ratenbegrenzung für unclaimed Projekte. Um zu verhindern, dass unclaimed Projekte erstellt werden, setzen Sie diesen Wert auf 0. |
| claimed_limit | 65536 | 65536 | Nein | Kontrolliert die Ratenbegrenzung für claimed Projekte. |
| plus_limit | 1048576 | 1048576 | Nein | Kontrolliert die Ratenbegrenzung von Metriken für Organisationen mit einem Bencher Plus-Plan. |
public
Der public-Ratenbegrenzer gilt pro IP-Adresse für nicht authentifizierte Anfragen.
Jedes Unterfeld enthält minute-, hour- und day-Limits.
Der gesamte Abschnitt ist optional.
Wenn nicht angegeben, werden die aufgelisteten Standardwerte verwendet.
| Name | Beispiel | Standard | Erforderlich | Beschreibung |
|---|---|---|---|---|
| requests | { … } | — | Nein | Spezifiziert Anfrage-Ratenlimits pro IP-Adresse. |
| requests.minute | 1024 | 1024 | Nein | Maximale Anfragen pro Minute pro IP-Adresse. |
| requests.hour | 4096 | 4096 | Nein | Maximale Anfragen pro Stunde pro IP-Adresse. |
| requests.day | 8192 | 8192 | Nein | Maximale Anfragen pro Tag pro IP-Adresse. |
| attempts | { … } | — | Nein | Spezifiziert Authentifizierungsversuch-Ratenlimits pro IP-Adresse. |
| attempts.minute | 32 | 32 | Nein | Maximale Authentifizierungsversuche pro Minute pro IP-Adresse. |
| attempts.hour | 64 | 64 | Nein | Maximale Authentifizierungsversuche pro Stunde pro IP-Adresse. |
| attempts.day | 128 | 128 | Nein | Maximale Authentifizierungsversuche pro Tag pro IP-Adresse. |
| runs | { … } | — | Nein | Spezifiziert Benchmark-Lauf-Ratenlimits pro IP-Adresse für nicht beanspruchte Projekte. |
| runs.minute | 64 | 64 | Nein | Maximale Benchmark-Läufe pro Minute pro IP-Adresse. |
| runs.hour | 128 | 128 | Nein | Maximale Benchmark-Läufe pro Stunde pro IP-Adresse. |
| runs.day | 256 | 256 | Nein | Maximale Benchmark-Läufe pro Tag pro IP-Adresse. |
user
Der user-Ratenbegrenzer gilt pro authentifiziertem Benutzer.
Jedes Unterfeld enthält minute-, hour- und day-Limits.
Der gesamte Abschnitt ist optional.
Wenn nicht angegeben, werden die aufgelisteten Standardwerte verwendet.
| Name | Beispiel | Standard | Erforderlich | Beschreibung |
|---|---|---|---|---|
| requests | { … } | — | Nein | Spezifiziert Anfrage-Ratenlimits pro Benutzer. |
| requests.minute | 2048 | 2048 | Nein | Maximale Anfragen pro Minute pro Benutzer. |
| requests.hour | 8192 | 8192 | Nein | Maximale Anfragen pro Stunde pro Benutzer. |
| requests.day | 16384 | 16384 | Nein | Maximale Anfragen pro Tag pro Benutzer. |
| attempts | { … } | — | Nein | Spezifiziert Authentifizierungsversuch-Ratenlimits pro Benutzer. |
| attempts.minute | 2 | 2 | Nein | Maximale Authentifizierungsversuche pro Minute pro Benutzer. |
| attempts.hour | 4 | 4 | Nein | Maximale Authentifizierungsversuche pro Stunde pro Benutzer. |
| attempts.day | 8 | 8 | Nein | Maximale Authentifizierungsversuche pro Tag pro Benutzer. |
| credentials | { … } | — | Nein | Spezifiziert Anmeldedaten-Erstellungs-Ratenlimits pro Benutzer. |
| credentials.minute | 4 | 4 | Nein | Maximale Anmeldedaten-Erstellungen pro Minute pro Benutzer. |
| credentials.hour | 8 | 8 | Nein | Maximale Anmeldedaten-Erstellungen pro Stunde pro Benutzer. |
| credentials.day | 16 | 16 | Nein | Maximale Anmeldedaten-Erstellungen pro Tag pro Benutzer. |
| organizations | { … } | — | Nein | Spezifiziert Organisations-Erstellungs-Ratenlimits pro Benutzer. |
| organizations.minute | 2 | 2 | Nein | Maximale Organisations-Erstellungen pro Minute pro Benutzer. |
| organizations.hour | 4 | 4 | Nein | Maximale Organisations-Erstellungen pro Stunde pro Benutzer. |
| organizations.day | 8 | 8 | Nein | Maximale Organisations-Erstellungen pro Tag pro Benutzer. |
| invites | { … } | — | Nein | Spezifiziert Einladungs-Ratenlimits pro Benutzer. |
| invites.minute | 8 | 8 | Nein | Maximale Einladungen pro Minute pro Benutzer. |
| invites.hour | 16 | 16 | Nein | Maximale Einladungen pro Stunde pro Benutzer. |
| invites.day | 32 | 32 | Nein | Maximale Einladungen pro Tag pro Benutzer. |
| runs | { … } | — | Nein | Spezifiziert Benchmark-Lauf-Ratenlimits pro Benutzer. |
| runs.minute | 64 | 64 | Nein | Maximale Benchmark-Läufe pro Minute pro Benutzer. |
| runs.hour | 1024 | 1024 | Nein | Maximale Benchmark-Läufe pro Stunde pro Benutzer. |
| runs.day | 4096 | 4096 | Nein | Maximale Benchmark-Läufe pro Tag pro Benutzer. |
project
Der project-Ratenbegrenzer gilt pro Projekt.
Jedes Unterfeld enthält minute-, hour- und day-Limits.
Der gesamte Abschnitt ist optional.
Wenn nicht angegeben, werden die aufgelisteten Standardwerte verwendet.
| Name | Beispiel | Standard | Erforderlich | Beschreibung |
|---|---|---|---|---|
| requests | { … } | — | Nein | Spezifiziert Anfrage-Ratenlimits pro Projekt. |
| requests.minute | 2048 | 2048 | Nein | Maximale Anfragen pro Minute pro Projekt. |
| requests.hour | 8192 | 8192 | Nein | Maximale Anfragen pro Stunde pro Projekt. |
| requests.day | 16384 | 16384 | Nein | Maximale Anfragen pro Tag pro Projekt. |
| runs | { … } | — | Nein | Spezifiziert Benchmark-Lauf-Ratenlimits pro Projekt. |
| runs.minute | 64 | 64 | Nein | Maximale Benchmark-Läufe pro Minute pro Projekt. |
| runs.hour | 1024 | 1024 | Nein | Maximale Benchmark-Läufe pro Stunde pro Projekt. |
| runs.day | 4096 | 4096 | Nein | Maximale Benchmark-Läufe pro Tag pro Projekt. |
runner
Der runner-Ratenbegrenzer gilt pro Runner.
Jedes Unterfeld enthält minute-, hour- und day-Limits.
Der gesamte Abschnitt ist optional.
Wenn nicht angegeben, werden die aufgelisteten Standardwerte verwendet.
| Name | Beispiel | Standard | Erforderlich | Beschreibung |
|---|---|---|---|---|
| requests | { … } | — | Nein | Spezifiziert Anfrage-Ratenlimits pro Runner. |
| requests.minute | 16 | 16 | Nein | Maximale Anfragen pro Minute pro Runner. |
| requests.hour | 256 | 256 | Nein | Maximale Anfragen pro Stunde pro Runner. |
| requests.day | 4096 | 4096 | Nein | Maximale Anfragen pro Tag pro Runner. |
oci_bandwidth
Der oci_bandwidth-Ratenbegrenzer gibt tägliche OCI-Registry-Bandbreitenlimits pro Organisationsstufe an.
Der gesamte Abschnitt ist optional.
Wenn nicht angegeben, werden die aufgelisteten Standardwerte verwendet.
| Name | Beispiel | Standard | Erforderlich | Beschreibung |
|---|---|---|---|---|
| unclaimed | 1073741824 | 1073741824 | Nein | Maximale Bytes pro Tag für nicht beanspruchte Organisationen (0 Mitglieder). Standardmäßig 1 GiB. |
| free | 10737418240 | 10737418240 | Nein | Maximale Bytes pro Tag für kostenlose (beansprucht, ohne bezahlten Plan) Organisationen. Standardmäßig 10 GiB. |
| plus | 107374182400 | 107374182400 | Nein | Maximale Bytes pro Tag für Plus (Team/Enterprise) Organisationen. Standardmäßig 100 GiB. |
plus.stats
Dieser Abschnitt gibt an, ob und wann Serverstatistiken gesammelt werden.
Der gesamte Abschnitt ist optional.
Wenn nicht angegeben, werden die aufgeführten Standardwerte verwendet.
Das heißt, Serverstatistiken sind opt-out.
Setzen Sie enabled auf false, um die Sammlung von Serverstatistiken zu deaktivieren.
| Name | Beispiel | Standard | Erforderlich | Beschreibung |
|---|---|---|---|---|
| offset | 11242 | 11242 | Nein | Gibt den Offset von Mitternacht in Sekunden für die Serverstatistiksammlung an. Standardmäßig läuft es um 03:07:22 UTC. |
| enabled | true | true | Nein | Steuert, ob Serverstatistiken gesammelt werden. Setzen Sie auf false, um sich abzumelden. |
plus.mcp
Dieser Abschnitt konfiguriert den Bencher MCP-Server. Der gesamte Abschnitt ist optional.
| Name | Beispiel | Standardwert | Erforderlich | Beschreibung |
|---|---|---|---|---|
| openai_apps_challenge | a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6 | — | Nein | Das Token zur Domainverifizierung, das OpenAI ausstellt, wenn Sie eine App einreichen, die diesen MCP-Server verwendet. Der API-Server liefert es als Klartext unter /.well-known/openai-apps-challenge aus. Wenn es nicht angegeben ist, antwortet diese Route mit 404 Not Found. |
plus.oauth
Mit diesem Abschnitt können sich MCP-Clients wie ChatGPT, claude.ai und Claude Code über OAuth bei Bencher MCP anmelden.
Der API-Server wird zu ihrem OAuth-Autorisierungsserver, und Benutzer genehmigen jede App in der Bencher Console unter console.url.
Der gesamte Abschnitt ist optional.
Wenn er nicht angegeben ist, ist OAuth deaktiviert: Seine Endpunkte geben 404 Not Found zurück, und Bencher MCP akzeptiert nur API-Schlüssel und anonyme Anfragen.
| Name | Beispiel | Standardwert | Erforderlich | Beschreibung |
|---|---|---|---|---|
| issuer | “https://api.bencher.example.com” | — | Ja | Der öffentliche Origin dieses API-Servers, unter dem Apps seine OAuth-Endpunkte finden: https, oder http nur für einen Loopback-Host wie localhost. Er muss ein Origin ohne Pfad sein, sonst startet der Server nicht. WARNUNG Ohne eine in resources aufgeführte URL folgt die Standard-Ressource diesem Wert, daher trennt eine Änderung die Apps, die bei der alten Standard-Ressource angemeldet sind, bis der alte Wert wiederhergestellt ist; mit einer in resources aufgeführten URL trennt eine Änderung nichts, solange der alte Origin diesen Server noch erreicht. |
| resources | ["https://mcp.bencher.example.com/mcp", "https://api.bencher.example.com/mcp"] |
[<issuer>/mcp] |
Nein | Die URLs des MCP-Endpunkts dieses Servers, bei denen sich Apps anmelden, die kanonische zuerst: https, oder http nur für einen Loopback-Host. Eine App, die keine angibt, erhält die erste. Das Entfernen einer URL trennt die Apps, die bei ihr angemeldet sind, bis sie wieder aufgeführt wird; ohne aufgeführte URL wird die Standard-Ressource bereitgestellt. |
| clients | [{ … }] | — | Nein | Die einzigen Apps, die sich anmelden dürfen. Das Entfernen einer App trennt sie, bis sie wieder aufgeführt wird. Aufgeführte Apps werden auf der Zustimmungsseite als verifiziert gekennzeichnet. Wenn nicht angegeben, kann jede App eine Anmeldung anfragen, sofern der API-Server ein gültiges Client-Metadatendokument von ihrer Client-ID abrufen kann. |
| clients.id | “https://app.example.com/oauth/client.json” | — | Ja | Die Client-ID der App: die https URL ihres Client-Metadatendokuments. |
| clients.metadata | { … } | — | Nein | Das Client-Metadatendokument der App, das verwendet wird, anstatt es von id abzurufen, zum Beispiel auf einem Server ohne Internetzugang. Es muss ein gültiges Client-Metadatendokument sein, dessen client_id gleich id ist, sonst startet der Server nicht. |
| signing_key | "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n" |
— | Nein | Ein privater RSA-Schlüssel mit mindestens 2048 Bit im PEM-Format (PKCS #1 oder PKCS #8), der ID-Tokens signiert. Er aktiviert OpenID Connect: die Scopes openid, email und profile, ID-Tokens sowie die UserInfo-, JWKS- und Discovery-Endpunkte. Wenn nicht angegeben, ist OpenID Connect deaktiviert. Wenn er kein gültiger Schlüssel ist, startet der Server nicht. ER SOLLTE SEHR SICHER SEIN! Jedes Mal, wenn er protokolliert wird, wird er als ************ verschleiert dargestellt. |
Ein JSON-String kann keinen Zeilenumbruch enthalten, schreiben Sie daher jeden Zeilenumbruch in signing_key als \n.
Erzeugen Sie zum Beispiel einen Schlüssel und geben Sie ihn als JSON-String aus, ohne ihn in eine Datei zu schreiben:
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 | jq -Rs .Um den Signaturschlüssel zu rotieren, ersetzen Sie ihn. Dadurch wird keine App getrennt.
Der API-Server stellt seine OAuth-Endpunkte und Metadaten an der Wurzel von issuer bereit.
Wenn ein Reverse Proxy den API-Server unter einem Pfadpräfix bereitstellt, etwa https://bencher.example.com/api,
setzen Sie issuer auf den Origin (https://bencher.example.com) und tragen Sie die vollständige URL des MCP-Endpunkts in resources ein (https://bencher.example.com/api/mcp).
Der Proxy muss dann /oauth/, /.well-known/oauth-authorization-server und /.well-known/openid-configuration am Origin an dieselben Pfade auf dem API-Server weiterleiten,
und den Metadatenpfad jeder Ressource, hier /.well-known/oauth-protected-resource/api/mcp, an /.well-known/oauth-protected-resource/mcp auf dem API-Server.
Bei mehr als einer Ressource muss der Proxy außerdem den Host Header unverändert durchreichen, da der API-Server anhand dieses Headers die anzukündigende Ressource auswählt.