תיעוד 111
תצורת שער יישומי Claude
מדריך לכל אפשרות ב-
gateway.yaml: מאזין ו-TLS, OIDC, סשן, מאגר Postgres, upstreams של Amazon Bedrock, Claude Platform on AWS, Agent Platform של Google Cloud ו-Microsoft Foundry, ניתוב מודלים, מדיניות מנוהלת וטלמטריה.
פריסת שער יישומי Claude מוגדרת בקובץ YAML אחד, בדרך כלל gateway.yaml. הקובץ מגדיר את כל מה שהשער עושה: איפה הוא מאזין, איך מפתחים נכנסים, לאן הולכת ההסקה, ואילו מדיניות וטלמטריה חלות. הדף הזה הוא המדריך לכל אפשרות בקובץ.
כדי לכתוב את הראשון, התחילו מההתחלה המהירה, שבונה תצורה מינימלית עובדת ומריצה אותה. אחרי שיש תצורה שאתם מרוצים ממנה, מדריך הפריסה מכסה אריזה בקונטיינר ואירוח ב-Kubernetes, ב-Cloud Run, או בפלטפורמה שלכם.
השער קורא את הקובץ פעם אחת, בעת ההפעלה, באמצעות claude gateway --config /path/to/gateway.yaml. כל אפשרות מאומתת מול סכמה בזמן האתחול, ולכן תצורה לא תקינה נכשלת בהפעלה עם שגיאה ברמת השדה, ולא בשימוש הראשון.
הדוגמה המלאה בסוף הדף הזה מפעילה כל מקטע.
#מבנה הקובץ
חמישה מקטעים הם חובה. כל מקטע אחר הוא אופציונלי, ומקטע שהושמט מקבל את ברירות המחדל שלו. מפתחות לא מוכרים נכשלים באתחול, ולכן שגיאת הקלדה מופיעה כשגיאה עם שם, ולא כהגדרה שמתעלמים ממנה בשקט.
מקטעי חובה:
listen: כתובת bind, כתובת URL ציבורית, סיום TLSoidc: ספק הזהות (IdP), כולל issuer, client, מיפוי claim, ומי רשאי להיכנסsession: אסימוני bearer שהשער מנפיק, עם סוד ומשך חייםstore: PostgreSQL, עבור device grants ומוני הגבלת קצבupstreams: לאן הולכת ההסקה, בין אם Anthropic, Amazon Bedrock, Claude Platform on AWS, Agent Platform של Google Cloud, או Microsoft Foundry
מקטעים אופציונליים:
admin: אימות Admin API ושמירה עבור מגבלות הוצאהenforcement: התנהגות fail-open או fail-closed של מגבלת הוצאהpricing: תעריפים חוזיים ומכפיל עבור מד ההוצאה ועבור נתוני העלות שהמפתחים רואיםmodelsו-auto_include_builtin_models: רשימת מודלים שנבחרה על ידי מנהל ומזהים לפי upstreammanaged: מדיניות הגדרות מנוהלות לפי קבוצת IdPtelemetry: העברת OTLP אל מחסנית התצפית שלכםaccess_control,limits,timeouts,rate_limits: הרשאה או חסימה של IP, תקרות גודל בקשה, זמן עד הבייט הראשון מה-upstream, ומגבלות כניסה לפי IPload_test_mode: בדיקת עומס של השער בלי קריאה לספק מודל
#הרחבת סודות
אל תכתבו סודות כמו client_secret, jwt_secret, או postgres_url ישירות ב-gateway.yaml. הפנו אליהם באחת מהצורות למטה, והשער פותר את הערך בזמן האתחול ממשתנה סביבה או מקובץ:
| צורה | נפתר אל | שימוש עבור |
|---|---|---|
${VAR} | משתנה הסביבה VAR. האתחול נכשל אם הוא לא מוגדר. | משתני סביבה של קונטיינר, AWS Secrets Manager באמצעות הזרקת env |
${file:/path} | תוכן הקובץ בנתיב המוחלט הזה, אחרי הסרת רווחים בקצוות. ההפניה חייבת להיות כל ערך השדה: בניגוד ל-${VAR}, היא לא מורחבת בתוך מחרוזת ארוכה יותר, ולכן עבור סיסמת מסד נתונים הגדירו store.password במקום להטמיע אותה ב-postgres_url. | עגינות volume של Kubernetes Secret, Vault Agent, SOPS |
#מקטעי חובה
#listen
בלוק listen שולט איפה השער משרת: כתובת ה-bind והפורט, ה-origin הנראה כלפי חוץ, וסיום TLS אופציונלי.
| שדה | חובה | תיאור |
|---|---|---|
host | לא | כתובת bind. ברירת מחדל 0.0.0.0. |
port | לא | פורט bind. ברירת מחדל 8080. |
public_url | אלא אם host הוא loopback | ה-origin הנראה כלפי חוץ בצורת https://, שמשמש לבניית redirect_uri של ה-IdP ולמטא-נתוני discovery. נדרש בכל פעם ש-host אינו כתובת loopback, בין אם TLS מסתיים בפרוקסי כגון ALB, Ingress, או Cloud Run ובין אם בשער עצמו דרך tls, מפני שהשער אף פעם לא גוזר את ה-origin שלו מכותרות X-Forwarded-*: אפשר לזייף אותן מצד הלקוח. האתחול נכשל בלעדיו. trusted_proxies למטה חל רק על זיהוי כתובת ה-IP של הלקוח. נדרש גם כדי להפעיל טלמטריה, מפני שהשער בונה מכתובת ה-URL הזו את נקודת הקצה של OTLP שהוא דוחף ללקוחות. |
tls.cert / tls.key | לא | נתיבי PEM אם השער עצמו מסיים TLS |
trusted_proxies | לא | כתובות CIDR או IP של מאזני עומסים לפני השער. כשהשדה מוגדר, השער סומך על X-Forwarded-For רק מהעמיתים האלה ורושם את כתובת ה-IP האמיתית של הלקוח עבור הגבלת קצב לפי IP ועבור ביקורת. שקול ל-set_real_ip_from של nginx. רשומות X-Forwarded-For שנכתבות כ-ipv4:port או [ipv6]:port, כמו שחלק ממאזני העומסים עושים, נקראות כשהפורט מוסר. כתובת IPv6 עם פורט שנוסף ובלי סוגריים עלולה להיקרא ככתובת אחרת או לא להיקרא בכלל, ולכן כבו את אפשרות הפורט בכל פרוקסי שכותב את הצורה הזו. |
#oidc
בלוק oidc מחבר את ה-gateway לספק הזהות ומחליט מי יכול להתחבר. הוא מציין את ה-issuer ואת לקוח ה-OAuth, ממפה את ה-claims שנושאים אימייל וקבוצות, ומגביל התחברות לפי דומיין אימייל או קבוצה.
OpenID Connect (OIDC) הוא פרוטוקול ה-SSO שה-gateway משתמש בו עם ספק הזהות. ראו הגדרת ספק זהות לגבי מה לרשום בצד ה-IdP.
| שדה | חובה | תיאור |
|---|---|---|
issuer | כן | בסיס גילוי OIDC. חייב להגיש גילוי ב-/.well-known/openid-configuration. השתמשו ב-HTTPS בסביבת ייצור. ה-gateway מקבל issuer ב-http://. issuer מסוג loopback כגון http://localhost:8081 נדחה על ידי מגן ה-SSRF אלא אם CLAUDE_GATEWAY_ALLOW_LOOPBACK=1 מוגדר בסביבת ה-gateway. |
client_id | כן | מרישום לקוח ה-OAuth שלכם |
client_secret | אלא אם token_endpoint_auth_method הוא private_key_jwt | מרישום לקוח ה-OAuth שלכם. השמיטו אותו כשמשתמשים באימות לקוח בתעודה. |
allowed_email_domains | לא | דחיית id_tokens שה-claim email שלהם אינו באחד מהדומיינים האלה, בלי תלות ברישיות. הגנה לעומק מפני תצורה שגויה של IdP מרובה דיירים. בנפרד מההגדרה הזו, id_token שה-claim email_verified שלו הוא במפורש false נדחה תמיד. |
allowed_groups | לא | הגבלת התחברות לחברים בקבוצות IdP אלה, בהתאמה ל-groups_claim. משתמש בדומיין אימייל מותר שאינו באף אחת מהקבוצות האלה נדחה. נדרש שה-IdP יפיק את claim הקבוצות. ההתאמה היא השוואת מחרוזת מדויקת ותלוית רישיות מול הערכים ב-claim הזה, וה-gateway אינו מרחיב קבוצות מקוננות: כדי לאשר חברים בתת-קבוצה, ציינו כאן את תת-הקבוצה או הגדירו את ה-IdP כך שיפיק חברות שטוחה. |
groups_claim | לא | איזה claim ב-id_token נושא חברות בקבוצות. ברירת המחדל היא groups. Microsoft Entra מפיק תפקידי אפליקציה תחת roles. מקבל מפתח שטוח או JSON Pointer לפי RFC 6901 כגון /resource_access/gateway/roles ל-claims מקוננים. |
google_groups | לא | איתור קבוצות המשתמש שהתחבר דרך Google Workspace Admin SDK Directory API, כי ה-id_token של Google אינו נושא claim קבוצות. הגדירו את service_account_json_path לקובץ מפתח של חשבון שירות עם האצלה ברמת הדומיין על ה-scope https://www.googleapis.com/auth/admin.directory.group.readonly, ואת admin_email למנהל Workspace שחשבון השירות מתחזה אליו. ה-Directory API דורש subject של מנהל אמיתי. כתובות האימייל של הקבוצות של כל משתמש הופכות ל-claim הקבוצות שלו, ולכן allowed_groups ו-managed.policies.match.groups מתאימים לפי אימייל של קבוצה. |
email_claim | לא | איזה claim ב-id_token נושא את האימייל של המשתמש. ברירת המחדל היא email. חלק מספקי ה-IdP, כגון ADFS ו-Entra B2C, מפיקים upn או preferred_username במקום זאת. מקבל מפתח שטוח, JSON Pointer, או רשימת מפתחות גיבוי שבה נעשה שימוש במפתח הראשון שקיים. |
scopes | לא | דריסה מלאה של ה-scopes של OIDC שה-gateway מבקש. ברירת המחדל היא [openid, profile, email, offline_access]. הגדירו כשה-IdP דוחה scopes שהוא אינו מזהה, או כשנדרש scope מותאם אישית כדי להפיק קבוצות או אימייל. חייב לכלול את openid. השמטת offline_access משביתה refresh tokens, ולכן מפתחים מריצים מחדש את התחברות הדפדפן בכל session.ttl_hours. ראו הגדרת ספק זהות למתכוני scope לפי IdP, כגון זרימת ה-refresh token של Google. |
scope_on_refresh | לא | שליחה גם של scope, עם אותה רשימה כמו בבקשת ההתחברות, כשה-gateway מחליף refresh token. ברירת המחדל היא false: בקשת ה-refresh משמיטה את scope. רוב ספקי ה-IdP מחזירים id_token בכל refresh ואינם זקוקים לכך. הגדירו true כשה-IdP מחזיר id_token ב-refresh רק אם מבקשים שוב את openid, מה ש-Okta מתעד עבור ה-refresh grant שלו. בלי id_token, כל refresh תלוי בכך שנקודת הקצה userinfo של ה-IdP תקבל את ה-access token המרוענן. אם אתם מגבילים התחברות או מתאימים מדיניות לפי קבוצות, וה-id_token בזמן refresh של ה-IdP משמיט אותן, הגדירו גם userinfo_fallback: true כדי שה-gateway ישלים אותן מנקודת הקצה userinfo. IdP שהעניק פחות scopes ממה שהתבקש יכול לדחות את ה-refresh עם invalid_scope, כולל עבור סשנים קיימים אם מוסיפים רשומות ל-scopes בזמן שההגדרה הזו פעילה. בטלו את המפתח אם רענונים מתחילים להיכשל ב-token_endpoint אחרי שהגדרתם אותו. נדרש Claude Code v2.1.260 או חדש יותר בשרת ה-gateway. |
extra_auth_params | לא | פרמטרי שאילתה נוספים שמצורפים לבקשת ההרשאה של ה-IdP, כלשונם. זה מנגנון הדריסה להתנהגות ייחודית ל-IdP, כגון access_type: offline עבור refresh tokens של Google, domain_hint עבור חלק מדיירי Entra, או acr_values עבור זרימות step-up. אי אפשר לדרוס את פרמטרי הפרוטוקול שה-gateway מנהל: state, nonce, redirect_uri, PKCE, scope, response_type, response_mode ו-client_id. |
userinfo_fallback | לא | כשה-id_token משמיט אימייל או קבוצות, שלוף אותם מ-/userinfo. נדרש עבור lightweight access tokens של Keycloak, שרת הארגון של Okta, וטוקנים מינימליים של ADFS. ה-id_token נשאר הסמכותי. userinfo רק ממלא פערים. ברירת המחדל היא false. |
use_pkce | לא | שליחת אתגר PKCE (S256) בבקשת ההרשאה. ברירת המחדל היא true. הגדירו false רק אם ה-IdP דוחה PKCE עבור הלקוח הסודי הזה. |
clock_skew_seconds | לא | סובלנות לסטיית שעון בעת אימות claims של זמן ב-id_token. ברירת המחדל היא 0, וזו בדיקה מחמירה. העלו אם אתם רואים שגיאות "token expired / not yet valid" מיד אחרי התחברות בגלל סטיית שעון בין המארח ל-IdP. |
token_endpoint_auth_method | לא | איך ה-gateway מאמת את עצמו מול נקודת הקצה token של ה-IdP: client_secret_basic, client_secret_post, או private_key_jwt עבור אימות לקוח בתעודה. כברירת מחדל ה-gateway בוחר אחת משתי שיטות ה-client_secret לפי מה שה-IdP מפרסם. |
client_assertion | עם private_key_jwt | בלוק עם private_key_pem ו-certificate_pem: המפתח הפרטי והתעודה עבור אימות לקוח בתעודה. נדרש v2.1.284 או חדש יותר. |
id_token_signed_response_alg | לא | אלגוריתם החתימה הצפוי של id_token. ברירת המחדל היא RS256. הגדירו עבור IdP שחותם ב-ES256, ב-PS256 או ב-EdDSA. |
additional_authorized_parties | לא | ערכי azp נוספים לקבלה מעבר ל-client_id, עבור זרימות broker ו-token-exchange של Keycloak |
discovery_url | לא | שליפת מסמך הגילוי מכתובת ה-URL הזו במקום לגזור אותו מ-issuer, עבור IdP מאחורי פרוקסי שמשכתב את מארח ה-issuer. הנתיב חייב להכיל /.well-known/. |
use_proxy | לא | שליחת בקשות ה-IdP של ה-gateway עצמו דרך ה-forward proxy ב-HTTPS_PROXY או ב-HTTP_PROXY, תוך כיבוד NO_PROXY. false משאיר את הבקשות האלה ישירות. נדרש v2.1.227 או חדש יותר. ראו בקשות IdP דרך forward proxy בהמשך. |
form_action_origins | לא | מקורות נוספים עבור ההנחיה Content-Security-Policy: form-action של דף /device. ה-gateway כבר מתיר את 'self' ואת מקור ה-authorization_endpoint שהתגלה, אבל Chrome אוכף את form-action מול כל שרשרת ההפניות. אם ה-IdP מפנה דרך מארח שני, כגון Azure AD שמאוחד ל-ADFS, Okta במבנה hub-spoke, או מיירט SSO ארגוני, ציינו כל מקור שבקשת ההרשאה עשויה לעבור דרכו בהפניה. |
ca_cert_pem | לא | תעודת ה-CA עצמה בקידוד PEM, ולא נתיב לקובץ. היא מחליפה את מאגר האמון של המערכת עבור בקשות IdP בלבד. כדי לטעון קובץ מורכב, כתבו ${file:/etc/gateway/idp-ca.pem}. השתמשו עבור Keycloak או Dex מאחורי PKI ארגוני. |
#אימות לקוח בתעודה
אם ספק הזהות מאמת לקוחות OAuth בתעודה במקום ב-client secret, כפי ש-Microsoft Entra עושה עם אישורי תעודה, הגדירו token_endpoint_auth_method: private_key_jwt. נדרש Claude Code v2.1.284 או חדש יותר בשרת ה-gateway.
בתצורה הזו ה-gateway אינו שולח סוד. הוא מאמת את עצמו מול נקודת הקצה token של ה-IdP באמצעות JWT קצר מועד החתום במפתח הפרטי של התעודה, כשמפתח מתחבר ובכל פעם שה-gateway מרענן את הסשן שלו. ה-JWT חתום ב-RS256 ומזהה את התעודה בכותרות טביעת אצבע x5t ו-x5t#S256, ולא ב-kid. ה-IdP שלכם חייב להיות מסוגל למצוא את התעודה הרשומה לפי טביעת אצבע.
1. יצירת המפתח והתעודה
צרו מפתח פרטי RSA לא מוצפן של לפחות 2048 ביט, בצורת PEM של PKCS#8 או PKCS#1, ותעודה עבורו. ה-gateway מסרב לעלות עם כל מפתח שאינו עומד בתנאים האלה. פקודת openssl הזו יוצרת מפתח כזה עם תעודה בחתימה עצמית שתקפה לשנה אחת:
openssl req -x509 -newkey rsa:2048 -nodes -keyout idp-client.key -out idp-client.crt -days 365 -subj "/CN=claude-gateway"היא כותבת את idp-client.key ואת idp-client.crt לתיקייה הנוכחית. העתיקו או הרכיבו את שני הקבצים במקום שה-gateway יכול לקרוא אותו. הדוגמה בשלב 3 משתמשת ב-/etc/gateway/.
2. העלאת התעודה ל-IdP
העלו את התעודה, לא את המפתח הפרטי, לרישום האפליקציה של ה-gateway ב-IdP.
3. הוספת המפתח והתעודה ל-gateway.yaml
תנו ל-gateway את המפתח הפרטי ואת התעודה בבלוק client_assertion. השמיטו את client_secret, כי ה-gateway מסרב לעלות כשאחד מהם מוגדר יחד עם private_key_jwt. בלוק oidc הזה מאמת את ה-gateway מול דייר Microsoft Entra בתעודה:
oidc:
issuer: https://login.microsoftonline.com/<tenant-id>/v2.0
client_id: <application-id>
token_endpoint_auth_method: private_key_jwt
client_assertion:
private_key_pem: ${file:/etc/gateway/idp-client.key}
certificate_pem: ${file:/etc/gateway/idp-client.crt}שני הערכים הם תוכן PEM, לא נתיבי קבצים, ולכן טענו קבצים מורכבים עם ${file:/path} כפי שהדוגמה עושה. ה-gateway מסרב לעלות אלא אם certificate_pem הוא תעודת PEM יחידה, בלי שאר השרשרת שלה, והמפתח הציבורי שלה תואם ל-private_key_pem.
4. הפעלה מחדש של ה-gateway ובדיקת יומן העלייה
הפעילו מחדש את ה-gateway ומצאו את השורה הזו ביומן העלייה:
[gateway] 2026-10-01T23:07:40.512Z info oidc: client authentication private_key_jwt; certificate CN=claude-gateway, SHA-1 thumbprint DE92821854EE8BAA1D98C758FAA04AABE80B9F57, expires Oct 1 23:07:31 2027 GMTהשוו את טביעת האצבע SHA-1 לזו שה-IdP מציג עבור התעודה שהעליתם. אם התעודה פגה או עדיין אינה תקפה, ה-gateway עדיין עולה אבל רושם אזהרה שהתחברויות ורענונים ייכשלו עד שתחליפו אותה. כדי לאשר שה-IdP מקבל את התעודה, בקשו ממפתח אחד להתחבר דרך ה-gateway.
#סיבוב תעודת הלקוח
ה-gateway קורא את המפתח ואת התעודה פעם אחת בעלייה, ולכן קובץ שהשתנה נכנס לתוקף רק אחרי הפעלה מחדש. סובבו בסדר הזה כדי שאף בקשת טוקן לא תציג תעודה שאין ל-IdP:
- העלו את התעודה החדשה ל-IdP לצד התעודה הישנה.
- החליפו את קובצי המפתח והתעודה ש-
gateway.yamlטוען, ואז הפעילו מחדש את ה-gateway. אם אתם מריצים כמה עותקים, הפעלה מחדש מתגלגלת מתאימה, כי ל-IdP יש את שתי התעודות עד שתסירו את הישנה. - אחרי שכל עותק הופעל מחדש, הסירו את התעודה הישנה מה-IdP.
#בקשות IdP דרך forward proxy
ה-upstreams של ההסקה מכבדים את HTTPS_PROXY ואת HTTP_PROXY בכל גרסה. הבקשות של ה-gateway עצמו אל ה-IdP, גילוי, JWKS, token ו-userinfo, הולכות ישירות אלא אם מגדירים oidc.use_proxy: true, מה שדורש v2.1.227 או חדש יותר. כשמשתנה פרוקסי מוגדר, use_proxy אינו מוגדר, וה-issuer אינו מכוסה על ידי NO_PROXY, ה-gateway משאיר את הבקשות האלה ישירות ורושם הודעה בעלייה שמבקשת מכם לבחור. use_proxy: false משאיר אותן ישירות ומשתיק את ההודעה.
עם use_proxy: true, ה-pod פותר בעצמו את שם המארח של כל נקודת קצה של ה-IdP ומבקש מהפרוקסי CONNECT לכתובת ה-IP שנפתרה, ולכן הפרוקסי חייב לקבל CONNECT לכתובת ה-IP של כל מארח שמסמך הגילוי מציין, ולא רק של ה-issuer. השתמשו בכתובת URL של פרוקסי ב-http://. ca_cert_pem ומגן ה-SSRF חלים גם על הנתיב דרך הפרוקסי.
יציאה דרך פרוקסי בלבד משנה את שני אלה: בזמן שהיא פעילה, בקשות IdP עוקבות אחרי הפרוקסי אלא אם מגדירים use_proxy: false, וה-gateway מוסר לפרוקסי כל שם מארח של IdP בלי לפתור אותו קודם.
#יציאה דרך פרוקסי בלבד
הגדירו CLAUDE_GATEWAY_PROXY_IS_EGRESS_BOUNDARY=1 בסביבת ה-gateway, ליד HTTPS_PROXY, כשה-pod מגיע למארחים אחרים רק דרך ה-forward proxy הזה ואינו יכול לפתור בעצמו שמות DNS ציבוריים, או כשהפרוקסי מסרב ל-CONNECT לכתובת IP. נדרש v2.1.277 או חדש יותר. זה משתנה סביבה ולא מפתח ב-gateway.yaml, כדי ששום דבר בקובץ התצורה לא יוכל לרכך את בדיקת הכתובות של ה-gateway.
export HTTPS_PROXY=http://proxy.corp.example.com:3128
export NO_PROXY=
export no_proxy=
export CLAUDE_GATEWAY_PROXY_IS_EGRESS_BOUNDARY=1ה-gateway רושם שורת network: אחת בעלייה בזמן שיציאה דרך פרוקסי בלבד פעילה.
כל שורה למטה היא מחלקה אחת של בקשה יוצאת ב-gateway שבו HTTPS_PROXY מוגדר, כברירת מחדל ובזמן שיציאה דרך פרוקסי בלבד פעילה.
| בקשה יוצאת | ברירת מחדל | יציאה דרך פרוקסי בלבד פעילה |
|---|---|---|
upstreams של provider: anthropic, החלפת טוקן של Workload Identity Federation, ייצוא telemetry.forward_to | נפתר ונבדק מקומית, ואז CONNECT לכתובת ה-IP שנבדקה דרך הפרוקסי. אספן טלמטריה שרשום ב-NO_PROXY מושג ישירות במקום זאת | שם המארח נמסר לפרוקסי |
| גילוי IdP, JWKS, token ו-userinfo | ישיר אלא אם oidc.use_proxy: true, ואז CONNECT לכתובת ה-IP שנבדקה | שם המארח נמסר לפרוקסי, אלא אם oidc.use_proxy: false משאיר IdP פנימי ישיר |
| upstreams של Amazon Bedrock, Claude Platform on AWS, Agent Platform של Google Cloud ו-Microsoft Foundry, ואיתור קבוצות Google | שם המארח נמסר לפרוקסי | ללא שינוי |
יציאה דרך פרוקסי בלבד נשארת כבויה אלא אם סביבת ה-gateway עומדת בכל שלושת התנאים האלה:
HTTPS_PROXYאוHTTP_PROXYמוגדר.NO_PROXYו-no_proxyריקים. אם הפלטפורמה מזריקה אחד מהם ל-pods, הגדירו את שניהם לערך ריק במכולת ה-gateway. רישום אספן טלמטריה ב-NO_PROXYמשאיר את היציאה דרך פרוקסי בלבד כבויה.CLAUDE_GATEWAY_ALLOW_LOOPBACKאינו מופעל. אספן או IdP על ה-loopback של ה-pod עצמו אינם יכולים להשתלב עם יציאה דרך פרוקסי בלבד, כי כתובת loopback שנמסרת לפרוקסי תהיה של מארח הפרוקסי עצמו, ולכן תנו לשירותים האלה כתובת שהפרוקסי יכול להגיע אליה. מאותה סיבה ה-gateway מסרב לחלוטין לשמות בסגנוןlocalhostבזמן שיציאה דרך פרוקסי בלבד פעילה.
כשאחד מהתנאים האלה אינו מתקיים, ה-gateway רושם אזהרה בעלייה שמציינת את המשתנה שעצר אותו, ושומר על התנהגות ברירת המחדל.
אחרי שיציאה דרך פרוקסי בלבד פעילה, התירו כל יעד בפרוקסי, כולל אספן פנימי וכל מארח שמוגדר לפי כתובת IP. עדיין אפשר להשאיר IdP פנימי ישיר עם oidc.use_proxy: false.
[!WARNING]
הפעילו זאת רק כשרשימת ההיתרים של הפרוקסי מחמירה לפחות כמו הבדיקה של ה-gateway עצמו. הפרוקסי חייב לסרב לנקודות קצה של מטא-דאטה בענן כגון
169.254.169.254ו-metadata.google.internal, לכתובות link-local, ול-loopback של מארח הפרוקסי עצמו, והוא חייב לסרב להן לפי הכתובת ששם נפתר אליה, ולא רק לפי השם, כי ה-gateway כבר אינו תופס שם מארח שנפתר לאחת מהן. פרוקסי שמתחבר לכל מקום שמבקשים ממנו מסיר את מגן ה-SSRF של ה-gateway עבור הבקשות האלה.
#session
בלוק session מעצב את ה-bearer tokens שה-gateway מנפיק אחרי התחברות: הסוד שחותם אותם ומשך החיים שלהם.
| שדה | חובה | תיאור |
|---|---|---|
jwt_secret | כן | לפחות 32 בתים של אנטרופיה, לדוגמה מ-openssl rand -base64 32. חותם את ה-bearer tokens של ה-gateway ב-HS256. מקבל מחרוזת יחידה או מערך לסיבוב: אינדקס 0 חותם וכל הרשומות מאמתות. כדי לסובב, הוסיפו סוד חדש בהתחלה, המתינו ttl_hours, ואז הסירו את הישן. |
ttl_hours | לא | משך החיים של bearer token של ה-gateway. ברירת המחדל היא 1. ה-CLI מרענן בשקט לפני התפוגה כשה-IdP מנפיק refresh tokens. משך חיים קצר יותר מבטל הקצאה מהר יותר. משך חיים ארוך יותר יוצר פחות הלוך ושוב ל-IdP. אם ה-IdP אינו יכול להנפיק refresh tokens כי offline_access אינו זמין, אין רענון שקט, ולכן העלו זאת ל-8 או ל-12 כדי להימנע משליחת מפתחים חזרה להתחברות בדפדפן בכל שעה. |
#store
בלוק store מפנה את ה-gateway אל מסד הנתונים PostgreSQL שלו, שמחזיק הרשאות מכשירים ומונים של הגבלת קצב.
| שדה | חובה | תיאור |
|---|---|---|
postgres_url | כן | כתובת postgres:// או postgresql:// עם מארח אחד, לא רשימה מופרדת בפסיקים. ה-gateway מריץ את מיגרציות הסכמה שלו בזמן אתחול ובעת שדרוג, ולכן לתפקיד נדרשות הרשאות ליצור ולשנות טבלאות בסכמת היעד. ראו שדרוגים ו-Postgres. |
username | לא | דורס את המשתמש שב-postgres_url |
password | לא | אישור מסד הנתונים. הגדירו אותו כאן ולא בתוך postgres_url, כדי שהאישור יישאר מחוץ לכתובת. מקבל כל תו וגובר על אישורים שבכתובת. |
max_connections | לא | גודל מאגר החיבורים של Postgres לכל replica. ברירת המחדל 5, שהיא שמרנית וידידותית למסדי נתונים משותפים. כשמגבלות הוצאה מופעלות, ה-gateway מבצע כמה פעולות מסד נתונים לכל בקשת inference, ולכן העלו אותו עבור מסד נתונים ייעודי תחת עומס, בתוך מה שגודל מאגר החיבורים מתיר. |
connect_timeout_seconds | לא | שניות שה-gateway ממתין כשהוא פותח חיבור Postgres. מספר שלם מ-1 עד 60, ברירת מחדל 5. העלו אותו אם ניסיונות חיבור מסתיימים ב-timeout כשמופע gateway חדש עולה. דורש Claude Code v2.1.274 או חדש יותר בשרת ה-gateway. גרסאות מוקדמות יותר מסרבות לעלות כשהמפתח מוגדר. |
readiness_grace_seconds | לא | כמה שניות /readyz ממשיך לדווח ready אחרי ש-Postgres מפסיק לענות. מספר שלם מ-0 עד 3600, ברירת מחדל 0. ראו התנהגות בהשבתה לבחירת ערך. דורש Claude Code v2.1.282 או חדש יותר בשרת ה-gateway. גרסאות מוקדמות יותר מסרבות לעלות כשהמפתח מוגדר. |
לפיתוח מקומי, הפנו את postgres_url אל מכולת Postgres חד פעמית, לדוגמה docker run --rm -p 5432:5432 -e POSTGRES_HOST_AUTH_METHOD=trust postgres.
#upstreams
upstreams היא רשימה סדורה. ה-gateway מעביר את ה-inference אל ה-upstream הראשון שפותר את המודל המבוקש, ומדלג על כל upstream שרשימת groups שלו משאירה את המפתח בחוץ.
ב-5xx, 429, 401, 403, 404 או timeout ה-gateway מבצע failover אל ה-upstream הבא. שאר 4xx לא, משום שהשגיאות האלה מיוחסות לבקשה ולא ל-upstream. 401 או 403 אומר שה-upstream דחה את האישור שבו השתמש ה-gateway, או מנע ממנו גישה, למשל למודל המבוקש. 404 אומר שה-upstream הזה לא מגיש את המודל המבוקש, כך ש-upstream מאוחר יותר ברשימה עדיין יכול.
אם מגדירים forward_user_identity: true על upstream, 429 שהוא מחזיר לבקשה שנשאה את כתובת האימייל של המפתח לא עובר failover. ראו איך סירוב של מגבלה לכל משתמש מגיע אל המפתח.
Failover על 404 דורש gateway v2.1.198 או חדש יותר. מהדורות מוקדמות יותר החזירו את ה-404 הראשון ללקוח גם כאשר upstream מאוחר יותר ברשימה הגיש את המודל.
כמה upstreams של אותו ספק חייבים להגדיר name: ייחודי.
הלקוחות של Amazon Bedrock, Claude Platform on AWS, Agent Platform של Google Cloud ו-Microsoft Foundry נבנים פעם אחת בעת העלייה, וה-SDK שלהם מרעננים אישורים באופן פנימי, ולכן סיבוב של אישורי ענן לא מחייב הפעלה מחדש. מפתחות API סטטיים של Anthropic ו-bearers נקראים בעת העלייה. ראו Anthropic API.
#הודעות שגיאה של upstream
ה-gateway מחזיר את תגובת השגיאה של upstream אחד, או 502 משלו, לפי האופן שבו ה-upstreams ענו:
- upstream החזיר סטטוס שה-gateway לא מבצע עליו failover: התגובה של אותו upstream. ה-gateway לא מנסה upstreams נוספים.
- כל upstream שה-gateway ניסה נכשל באופן שעליו הוא מבצע failover: ה-
429האחרון. כשאף אחד לא החזיר429, ה-gateway מעדיף, לפי הסדר, את ה-401או403האחרון, את ה-404האחרון, ואת ה-501האחרון. כשאף אחד לא החזיר אף אחד מאלה, ה-502של ה-gateway עצמו,all upstreams failed (N attempted). N סופר את רשומותupstreamsשלכם, כולל אלה שדולגו, פחות כל רשומה שרשימתgroupsשלה משאירה את המפתח בחוץ.
כשה-gateway מחזיר תגובה של upstream, הוא שומר את קוד הסטטוס של ה-upstream. האם הוא שומר את ההודעה של ה-upstream תלוי בספק. גוף השגיאה של upstream מסוג Anthropic API מגיע אל המפתח ללא שינוי.
ה-upstreams של Amazon Bedrock, Claude Platform on AWS, Agent Platform של Google Cloud ו-Microsoft Foundry יכולים לציין את מזהי החשבון, ARN של תפקידים ומזהי פרויקט בטקסט השגיאה. ה-gateway רושם את הטקסט המלא ביומן התפעולי. מה שהמפתח רואה מאותם upstreams תלוי בדחייה:
400או413במעטפת השגיאה הסטנדרטית של Anthropic: ההודעה של ה-upstream עצמו, כגוןprompt is too long. Claude Platform on AWS, Agent Platform ו-Microsoft Foundry מחזירים מעטפת זו לדחיות של API המודל.400או413בצורה של הספק עצמו: token מסוגcapability_rejected:. כשה-gateway לא יכול לסווג את הדחייה,upstream rejected the requestעל400אוrequest too large for this upstreamעל413.- כל סטטוס אחר: ניסוח גנרי לפי סטטוס, כגון
upstream rate limit exceededעל429.
לדוגמה, ה-gateway מחליף את Input is too long for requested model. של Amazon Bedrock ב-capability_rejected: prompt_too_long. Claude Code דוחס אוטומטית על ה-token הזה, כפי שהוא עושה על prompt is too long.
שמירה על הודעת 400 או 413 של upstream ענן, או החלפתה ב-token מסוג capability_rejected:, דורשת gateway v2.1.233 או חדש יותר.
#Anthropic API
ה-upstream המינימלי של Anthropic הוא מפתח API מ-Claude Console:
upstreams:
- provider: anthropic
auth:
api_key: ${ANTHROPIC_API_KEY}
# OR an OAuth bearer (e.g. a Workload-Identity-Federation-exchanged token):
# oauth_token: ${file:/var/run/secrets/anthropic-oauth-token}
# base_url: https://api.anthropic.com # default; override for a forward proxyשתי צורות האישור נבדלות בכותרת שהן שולחות:
api_key: שולחx-api-key. סובבו אותו ב-Claude Console ועדכנו את משתנה הסביבה.oauth_token: שולחAuthorization: Bearer. השתמשו בצורת ה-bearer כשהארגון מנפיק tokens לזמן קצר במקום מפתחות API לזמן ארוך. ה-bearer נקרא פעם אחת בעת העלייה, ולכן הרענון נעשה על ידי טעינה מחדש של הסוד והפעלה מחדש.
במקום מפתח או bearer סטטי, אפשר להשתמש ב-Workload Identity Federation. צרו כלל federation לפי מדריך Workload Identity Federation, ואז עגנו את ה-OIDC JWT של ה-workload כקובץ, כגון token של projected service account ב-Kubernetes או id-token של פלטפורמת CI. ה-gateway מחליף את ה-JWT ב-bearer לזמן קצר ומרענן אותו אוטומטית. קובץ ה-token נקרא מחדש בכל החלפה, ולכן tokens מוקרנים שסובבו נקלטים בלי הפעלה מחדש.
upstreams:
- provider: anthropic
auth:
federation_rule_id: ${ANTHROPIC_FEDERATION_RULE_ID}
organization_id: ${ANTHROPIC_ORGANIZATION_ID}
identity_token_file: /var/run/secrets/anthropic/id-token
# workspace_id: wrkspc_... # required if the rule covers >1 workspace
# service_account_id: svac_... # optional expected-target check#כותרות זהות לכל משתמש עבור פרוקסי שאתם מריצים
אפשר להפנות את base_url של upstream עם provider: anthropic אל פרוקסי שאתם מריצים, במקום אל Anthropic API. כדי לומר לפרוקסי הזה איזה מפתח שלח כל בקשה, הגדירו forward_user_identity: true על אותו upstream. הפרוקסי יכול אז לייחס הוצאה לכל מפתח. דורש gateway שמריץ Claude Code v2.1.233 או חדש יותר.
לדוגמה, עבור פרוקסי ב-upstream-gateway.internal.example.com:
upstreams:
- provider: anthropic
base_url: https://upstream-gateway.internal.example.com
auth:
api_key: ${PROXY_KEY}
forward_user_identity: true # default falseה-gateway מוסיף את הכותרות האלה לכל בקשה שהוא מעביר אל אותו upstream.
| כותרת | ערך |
|---|---|
x-litellm-end-user-id | כתובת האימייל של המפתח, כשה-IdP סיפק אחת. |
x-claude-gateway-user-id | ה-subject של המפתח ב-IdP, מ-claim בשם sub ב-token. |
x-claude-gateway-user-email | כתובת האימייל של המפתח, כשה-IdP סיפק אחת. |
כש-token של ה-IdP לא נושא אימייל, ה-gateway שולח רק x-claude-gateway-user-id ומשמיט את שתי כותרות האימייל. אם ה-IdP שם את האימייל ב-claim אחר, הגדירו את oidc.email_claim לאותו claim.
הפרוקסי שלכם לא מקבל את כותרות x-claude-code-* ש-Claude Code שולח, כגון x-claude-code-session-id. ה-gateway לא מעביר אותן לאף upstream, ולכן קבצו בקשות לפי מפתח באמצעות הכותרות בטבלה למעלה.
כשהפרוקסי שלכם עונה 429 לבקשה שנשאה את האימייל של המפתח, ה-gateway מחזיר את התגובה הזו למפתח כפי שהיא, בלי failover אל ה-upstream הבא, כך שתקציב או הגבלת קצב לכל משתמש של הפרוקסי נשמרים. שאר התגובות של הפרוקסי פועלות לפי כללי ה-failover הרגילים. אם token של IdP של מפתח לא נושא אימייל, ה-gateway מעביר את הבקשות שלו בלי כותרות האימייל, ולכן 429 לאחת מהבקשות האלה נספר כקיבולת upstream ועובר failover. לפני v2.1.267 בשרת ה-gateway, כל 429 עבר failover.
הגדירו forward_user_identity רק על upstream ש-base_url שלו הוא פרוקסי שאתם מפעילים. ה-gateway שולח כתובות אימייל של מפתחים אל כל שרת ש-base_url מציין. אם base_url הוא Anthropic API, שזו ברירת המחדל, ה-gateway מסרב לעלות.
[!NOTE]
אם מגדירים
forward_user_identityעל upstream של Amazon Bedrock, ה-gateway יוצא בעת העלייה עםUnrecognized key(s) in object: 'forward_user_identity'. אם הפרוקסי יושב לפני Bedrock, רשמו אותו כ-upstream עםprovider: anthropic. ה-gateway שולח ל-upstream הזה את פורמט Anthropic Messages, ולכן הפרוקסי צריך לתרגם בקשות עבור Bedrock. כדי לציין כל מפתח ל-AWS, ראו ייחוס עלות AWS לכל מפתח.
#Amazon Bedrock
לפריסת Amazon Bedrock בצד הלקוח שהשער מחליף או עומד לפניה, ראו Claude Code על Amazon Bedrock. ה-upstream בצד השער:
upstreams:
- provider: bedrock
region: us-east-1
auth: {} # preferred: AWS default credential chain
# OR explicit credentials:
# auth:
# aws_access_key_id: ${AWS_AKID}
# aws_secret_access_key: ${AWS_SK}
# aws_session_token: ${AWS_ST}
# OR a Bedrock API bearer token:
# auth:
# aws_bearer_token: ${AWS_BEARER_TOKEN}
# Override the bedrock-runtime endpoint for FIPS or VPC-endpoint deployments:
# base_url: https://bedrock-runtime-fips.us-east-1.amazonaws.comבלוק auth ריק משתמש בשרשרת האישורים של ברירת המחדל ב-AWS SDK: משתני סביבה, ~/.aws/credentials, תפקיד משימה של ECS, מטא-דאטה של מופע EC2, או IRSA על EKS. בייצור, תנו ל-pod של השער תפקיד IAM במקום להטמיע מפתחות סטטיים בתמונת קונטיינר.
אישורים מפורשים חייבים להיות מלאים: השער נכשל בעלייה כש-aws_access_key_id ו-aws_secret_access_key לא מוגדרים יחד, או כש-aws_session_token מוגדר בלעדיהם. לפני v2.1.207, בלוק auth: חלקי עבר אימות.
| הגדרה | איך |
|---|---|
| הרשאות IAM | העניקו ל-principal של השער את bedrock:InvokeModel ואת bedrock:InvokeModelWithResponseStream גם על ה-ARN של פרופילי ההסקה וגם על ה-ARN של מודלי היסוד שמתחתיהם. לקטלוג המובנה באזורי US: arn:aws:bedrock:<region>:<account>:inference-profile/us.anthropic.* ו-arn:aws:bedrock:*::foundation-model/anthropic.*. העניקו גם את bedrock:CountTokens על ה-ARN של מודלי היסוד. השער משתמש בזה, בלי חיוב, כדי לספור את אסימוני הקלט של בקשה שהלקוח נטש, כך שמגבלות ההוצאה יישארו מדויקות. בלי זה השער חוזר לבקשת Bedrock של אסימון אחד עבור הספירה הזו. |
| גישה למודל | Amazon Bedrock מפעיל גישה למודל כברירת מחדל באזורים מסחריים. השער שנותר ברמת החשבון הוא טופס תרחיש השימוש החד-פעמי של Anthropic: אם אף אחד בחשבון ה-AWS שלכם לא שלח אותו, פתחו את קונסולת Amazon Bedrock, בחרו מודל Anthropic מקטלוג המודלים, והשלימו את הטופס. ראו שליחת פרטי תרחיש שימוש לטופס של AWS Organizations ולהרשאות ששולח הטופס צריך. |
| EKS (IRSA) | צרו תפקיד IAM עם המדיניות שלמעלה ומדיניות אמון לספק ה-OIDC של האשכול שלכם, מוגבלת לחשבון השירות של השער. הוסיפו לחשבון השירות את האנוטציה eks.amazonaws.com/role-arn: arn:aws:iam::<acct>:role/claude-gateway. auth: {} קולט את זה. |
| ECS / EC2 | צרפו את תפקיד ה-IAM להגדרת המשימה או לפרופיל המופע. auth: {} קולט את זה. |
| בכל מקום אחר | העבירו אישורים דרך משתני הסביבה AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY ו-AWS_SESSION_TOKEN, או הגדירו אותם במפורש ב-auth: עם הרחבת ${VAR} |
| אזור | region: הוא אזור נקודת הקצה של ה-API. פרופילי הסקה בין אזורים מנתבים על פני הגאוגרפיה (US, EU, APAC) בלי קשר לאיזה אזור בחרתם. לאזורים שאינם US או ל-ARN של תפוקה מוקצית, הוסיפו בלוק models: עם מזהי ה-upstream הנכונים. |
#החלת guardrail של Amazon Bedrock
כדי להחיל guardrail של Amazon Bedrock על כל בקשת הסקה שהשער שולח דרך upstream של Bedrock, הוסיפו בלוק guardrail ל-upstream הזה. נדרש Claude Code v2.1.281 או חדש יותר בשרת השער.
upstreams:
- provider: bedrock
region: us-east-1
auth: {}
guardrail:
id: gr-abc123 # guardrail ID or full ARN
version: "1" # a published version number, or DRAFT
# keep the quotes: a bare 1 fails at bootהעניקו גם את bedrock:ApplyGuardrail על ה-guardrail ל-principal שחותם על הבקשות של ה-upstream הזה: ה-principal של AWS של השער, או עם assume_role התפקיד ששמו ב-role_arn.
הגדירו guardrail על כל upstream של bedrock או על אף אחד. השער מסרב לעלות על תערובת, כי failover יכול אחרת לשלוח בקשה ל-upstream של Bedrock שאין לו guardrail.
ה-guardrail מכסה רק upstream של Bedrock. אם אתם מפרטים ספק אחר ב-upstreams, השער שולח בקשות לספק הזה בלי ה-guardrail, או מסרב לעלות אם הספק הזה הוא mantle.
כשבקשת /v1/messages שבגוף שלה יש שדה amazon-bedrock-*, כגון amazon-bedrock-guardrailConfig, מגיעה ל-upstream של Bedrock שבו מוגדר guardrail, השער עונה 400 במקום להעביר אותה.
[!WARNING]
כברירת מחדל השער לא מוסיף תגיות קלט לפרומפטים, ולכן מסנן guardrail ש-Amazon Bedrock מחיל רק על קלט מתויג לא רץ על תעבורה דרך השער. כדי להוסיף את התגיות, הגדירו
input_tagging. אילו מסננים תלויים בתגיות קלט, ראו תגיות קלט בתיעוד של Amazon Bedrock.
#הוספת תגיות קלט ל-guardrail
כדי שהשער יוסיף את תגיות הקלט שמסנן התקפות הפרומפט של guardrail ב-Amazon Bedrock צריך, הגדירו input_tagging בבלוק guardrail והפעילו מחדש את השער. הגדירו את אותו ערך על כל upstream של bedrock, אחרת השער מסרב לעלות. נדרש Claude Code v2.1.316 או חדש יותר בשרת השער. שער בגרסה שאין בה את המפתח יוצא בעלייה עם Unrecognized key(s) in object: 'input_tagging'.
[!WARNING]
לפי התיעוד של Amazon Bedrock, כל מסנן ב-guardrail מפסיק להעריך תוכן לא מתויג ברגע שבקשה נושאת תגיות קלט. נסו את
input_taggingעל שער בדיקה לפני שתגדירו אותו על שער שמפתחים משתמשים בו.
input_tagging מקבל אחד מהערכים האלה:
input_tagging | איפה השער מתייג טקסט | אחרי שה-guardrail חוסם פרומפט |
|---|---|---|
last_message | הודעות user מאז התשובה האחרונה של Claude | ב-Claude Code, הפרומפט הבא יכול לעבור, ו-Claude מקבל אחר כך את הפרומפט החסום כחלק מהשיחה |
user_messages | הודעות user | גם פרומפטים מאוחרים יותר בסשן יכולים להיחסם, עד שהמפתח מסיר את הפרומפט החסום |
all_messages | הודעות user ו-assistant | כמו user_messages |
all_messages_and_system | פרומפט המערכת וכל הודעה, כולל הודעות מערכת באמצע השיחה | כמו user_messages |
עם last_message, אם בהודעות user מאז התשובה האחרונה של Claude אין טקסט לתיוג, השער מתייג במקום זאת את הודעות המערכת מאמצע השיחה מאז התשובה הזו. קריאת כלי נחשבת לתשובה.
ההנחיה של Amazon Bedrock למסנן התקפות הפרומפט היא לתייג קלט משתמש כך שפרומפט המערכת לא ייכלל. אם תגדירו all_messages_and_system, מסנן שמסמן את פרומפט המערכת של Claude Code עצמו יכול לחסום בקשות.
הדוגמה למטה מתייגת טקסט בכל הודעת user:
upstreams:
- provider: bedrock
region: us-east-1
auth: {}
guardrail:
id: gr-abc123
version: "1"
input_tagging: user_messagesהודעות user יכולות להחזיק גם טקסט ש-Claude Code מוסיף, כגון תזכורות מערכת, אז בדקו בשער הבדיקה שבקשות רגילות לא נחסמות.
בבדיקות של Anthropic, סשן מתויג שמר על קריאות מטמון הפרומפט מפרומפט אחד לבא אחריו, והתגיות לא הוסיפו אסימוני קלט.
#מה תגיות הקלט לא מכסות
אף ערך של input_tagging לא עוצר מפתח שמכניס בכוונה טקסט למקום שאליו לא מגיעה תגית. אל תסתמכו על ה-guardrail שיעריך את החלקים האלה של בקשה:
- תוכן שהשער לא מתייג: הודעות שערך
input_taggingשלכם משאיר בחוץ, הגדרות כלים, קלטי קריאות כלים, תמונות ו-PDF, בין היתר. אלא אם הגדרתםall_messages_and_system, גם פרומפט המערכת לא מתויג. - תוצאות כלים: אלה מחזיקות את מה שהכלים של Claude מחזירים, כגון תוכן קבצים ודפי אינטרנט. בבדיקות של Anthropic, מסנן מילים לא העריך אותן, עם תגיות או בלעדיהן.
אם חשבון ה-AWS או הארגון שלכם אוכף guardrail, ראו את התיעוד של Amazon Bedrock לגבי האופן שבו ה-guardrail הזה מטפל בתגיות קלט.
#תיעוד איזה מסנן guardrail הופעל
כדי לגלות איזה מסנן guardrail של Amazon Bedrock חסם בקשה של מפתח, הגדירו guardrail_trace: true על ה-upstream של Bedrock, הפעילו מחדש את השער, ובקשו מהמפתח לשלוח את הבקשה שוב. אחר כך מצאו את אירוע guardrail.trace של הבקשה ביומן הביקורת. נדרש Claude Code v2.1.314 או חדש יותר בשרת השער. שער מוקדם יותר מסרב לעלות כשהוא מוצא את guardrail_trace.
upstreams:
- provider: bedrock
region: us-east-1
auth: {}
guardrail:
id: gr-abc123
version: "1"
guardrail_trace: true # default false; beside guardrail, not inside itהשער כותב אירוע guardrail.trace, בלי הטקסט שנמצאה לו התאמה, כשמסנן הופעל או כשהפעולה של ה-guardrail היא INTERVENED. מצאו את האירועים של המפתח לפי email או sub. בקשה אחת בזרימה יכולה לייצר כמה אירועים, ואחד מהם יכול לכלול רשימת filters ריקה, אז קראו כל אירוע שיש לו אותו request_id:
| שדה | מה הוא מחזיק |
|---|---|
request_id | מזהה הבקשה |
sub, email | מזהה המשתמש והאימייל של המפתח |
upstream | ה-upstream שממנו הגיעה התשובה |
action | הפעולה של ה-guardrail, כגון INTERVENED |
filters | המסננים שהופעלו. הרשימה ריקה כש-AWS לא שולח פירוט מסנן |
filters[].side | input או output |
filters[].guardrail | מזהה ה-guardrail |
filters[].policy | מדיניות Bedrock והרשימה, כגון contentPolicy.filters או sensitiveInformationPolicy.piiEntities |
שדות אחרים ב-filters[] | רשומה יכולה לשאת גם שדות כגון action, name, type, confidence, filterStrength, score ו-threshold |
האירוע משמיט את הטקסט שמסנן מצא לו התאמה, כולל שדה match במעקב של Bedrock. מפתחים לא מקבלים את נתוני המעקב של Bedrock, כי השער מסיר אותם מכל תשובה, בזרימה או לא.
אם לקוח שולח שדה amazon-bedrock-* בגוף בקשת /v1/messages, השער עונה 400 על upstream שמגדיר guardrail_trace.
#Bedrock בחשבון AWS אחר
הגדירו assume_role על upstream של Bedrock והשער משתמש בזהות ה-AWS שלו רק כדי לקרוא ל-sts:AssumeRole על תפקיד שאתם מציינים, שיכול להיות בחשבון AWS שונה מזה של השער. כל בקשת Bedrock מה-upstream הזה חתומה באישורים של שעה ש-STS מחזיר, כך שאף מפתח גישה ארוך טווח לא עובר בין חשבונות.
נדרש שער שמריץ Claude Code v2.1.281 או חדש יותר. שער מוקדם יותר מסרב לעלות כשהוא מוצא את המפתח.
upstreams:
- name: bedrock-isolated
provider: bedrock
region: us-east-1
auth: {} # the gateway's own role: it only calls STS
assume_role:
role_arn: arn:aws:iam::222222222222:role/claude-gateway-bedrock
# external_id: ${BEDROCK_ROLE_EXTERNAL_ID} # when the role's trust policy requires oneבלוק assume_role מקבל שלושה מפתחות:
| מפתח | משמעות |
|---|---|
role_arn | תפקיד ה-IAM שהשער מקבל על עצמו, כ-ARN מסוג arn:aws:iam:: או arn:aws-us-gov:iam::. תנו לו את הרשאות Bedrock שה-upstream הזה צריך, כולל bedrock:CountTokens, ובנוסף bedrock:ApplyGuardrail כשה-upstream מגדיר guardrail. |
external_id | אופציונלי. נשלח כמזהה החיצוני בכל קריאה ל-sts:AssumeRole. הגדירו אותו כשמדיניות האמון של התפקיד דורשת אחד, וצטטו אותו אם הוא כולו ספרות. |
session_name | אופציונלי. email או sub נותנים לכל מפתח סשן משלו: ראו שיוך עלויות AWS לפי מפתח. כשלא מוגדר, כל בקשה משתמשת בסשן אחד בשם claude-apps-gateway. |
מדיניות האמון של התפקיד מציינת את ה-principal של השער עצמו, כגון תפקיד IRSA או תפקיד משימת ECS שלו. ה-principal הזה צריך sts:AssumeRole על התפקיד, ובלי הרשאת Bedrock משלו. השמיטו את Condition אם לא הגדרתם external_id.
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": { "AWS": "arn:aws:iam::111111111111:role/claude-gateway" },
"Action": "sts:AssumeRole",
"Condition": { "StringEquals": { "sts:ExternalId": "your-external-id" } }
}]
}- אם STS מסרב או לא נגיש, השער לא שולח את הבקשה עם האישורים של ה-upstream עצמו. הוא רושם ביומן את שגיאת STS עם מה לבדוק, ואז מנסה את ה-upstream הבא שפירטתם. הודעות שגיאה של upstream מכסות את מה שהלקוח מקבל כשאף upstream לא מצליח. upstream מאוחר יותר בלי
assume_roleישרת את הבקשה עם האישורים שלו, אז פרטו אחד רק אם זה מה שאתם רוצים. - השער קורא לנקודת הקצה האזורית של STS,
sts.<region>.amazonaws.com, שהרשת שלו חייבת להגיע אליה. לנקודת הקצה של FIPS, הגדירוAWS_USE_FIPS_ENDPOINT=trueבסביבה של השער ולאuse_fips_endpointבקובץ תצורה של AWS. assume_roleצריך אישורי מקור של SigV4: השער מסרב לעלות כשהוא מוגדר לצדaws_bearer_token.- בלי רשימת
groups, כל מפתח שהשער מכניס יכול להשתמש ב-upstream הזה. כדי להגביל אילו מודלים מפתח יכול להשתמש בהם, הגדירוavailableModelsבמדיניותmanaged. - כדי שמודל שמגיע דרך התפקיד לא יגיע גם מחשבון אחר, תנו לו מזהה מותאם אישית שמפת
upstream_modelשלו כוללת רק את שם ה-upstream הזה. למזהה כזה השער מדלג על כל upstream אחר, כך שגם הבקשה וגם ספירת האסימונים של בקשה שבוטלה לא יכולות לעבור ב-failover לחשבון אחר. - בקשה לשם מודל מובנה עדיין יכולה להגיע ל-upstream הזה, והשער חותם עליה באותו תפקיד. פרטו את ה-upstream הזה אחרון, אלא אם החשבון שלו צריך גם לשרת את המודלים האלה.
הדוגמה הזו נותנת למודל אחד מזהה מותאם אישית שרק ה-upstream המבודד משרת:
models:
- id: restricted-claude-opus-4-8 # a custom id, not a built-in model name
upstream_model:
bedrock-isolated: us.anthropic.claude-opus-4-8 # the only upstream that serves it#שיוך עלויות AWS לפי מפתח
כברירת מחדל השער חותם על כל בקשת Bedrock באישור אחד, כך ש-AWS רואה את הבקשות של כל המפתחים תחת principal אחד של IAM. הוסיפו session_name: email ל-assume_role והשער קורא ל-sts:AssumeRole פעם אחת לכל מפתח בכל שעה, כששם הסשן מוגדר לאימייל של המפתח הזה, וחותם על הבקשות שלו באישורים שהוחזרו, כך שהבקשות של כל מפתח מגיעות ל-AWS תחת סשן assumed-role משלו. התפקיד יכול להיות בחשבון של השער עצמו.
נדרש שער שמריץ Claude Code v2.1.281 או חדש יותר. שיוך עלויות ב-AWS מכסה את תפקיד ה-IAM ואיפה החיוב של AWS מציג את הסשנים.
upstreams:
- provider: bedrock
region: us-east-1
auth: {} # the gateway's own role: it only calls STS
assume_role:
role_arn: arn:aws:iam::123456789012:role/claude-gateway-bedrock-user
session_name: email # or subsession_name בוחר איזו טענה מאומתת הופכת ל-RoleSessionName של AWS: email או sub. השער כותב כל תו שאינו אותיות ASCII, ספרות ו-_+,.@- כהקסדצימלי =XX לכל בית UTF-8, ומקצר תוצאה ארוכה מ-64 תווים לקידומת ועוד גיבוב, כך ששם הסשן של כל מפתח נשאר תקין וייחודי. בקשה ממפתח שהאסימון שלו חסר את הטענה לא נשלחת דרך ה-upstream הזה, ויומן המפעיל אומר לעבור ל-sub או להגדיר oidc.email_claim.
מפתח פעיל עולה קריאת STS אחת בשעה לכל replica של השער, ובקשות ראשונות מקבילות חולקות קריאה אחת.
השער גם מבצע קריאה אחת משלו על התפקיד הזה: ספירת האסימונים של בקשה שהלקוח נטש, כך שמגבלות ההוצאה יישארו מדויקות. הספירה הזו ובקשת הגיבוי של אסימון אחד חתומות על ידי הסשן המשותף claude-apps-gateway, כך ש-AWS מייחס את הגיבוי ל-claude-apps-gateway ולא למפתח.
לשיוך קפדני לפי מפתח, הגדירו assume_role עם session_name על כל upstream של Bedrock שאתם מפרטים. upstream בלי זה חותם על הבקשות שהוא משרת באישורים שלו.
#נקודת הקצה Mantle של Amazon Bedrock
ספק mantle שולח הסקה אל נקודת הקצה Mantle של Amazon Bedrock. הוא דורש Claude Code v2.1.283 או חדש יותר בשרת השער. גרסאות שער מוקדמות יותר דוחות אותו בעת האתחול, לכן שדרגו כל עותק לפני שמוסיפים אותו.
הדוגמה למטה שמה את Mantle ראשון, עם upstream של Amazon Bedrock אחריו כדי לשרת כל מודל שהשדה models משאיר בחוץ:
upstreams:
- provider: mantle
region: us-east-1
models: [claude-opus-4-7, claude-haiku-4-5] # required
auth: {} # AWS default credential chain
- provider: bedrock
region: us-east-1
auth: {}הטבלה למטה מפרטת את השדות הייחודיים ל-upstream מסוג mantle.
| שדה | חובה | תיאור |
|---|---|---|
region | כן | אזור AWS. השער גוזר ממנו את נקודת הקצה כ-https://bedrock-mantle.<region>.api.aws/anthropic. |
models | כן | המודלים שהחשבון שלכם ב-AWS קיבל הרשאה אליהם ב-Mantle, בשמות שבהם הלקוחות שולחים אותם, למשל claude-haiku-4-5. רק אלה הולכים ל-upstream הזה, וכל מודל אחר מדלג אל הבא. |
auth | לא | מקבל את אותם מפתחות כמו בלוק auth של ה-upstream Amazon Bedrock, לפי אותם כללים. |
assume_role | לא | התפקיד שדרכו עוברות הבקשות של ה-upstream הזה, עם אותם מפתחות כמו ב-upstream מסוג bedrock, כולל session_name עבור שיוך לכל מפתח. תנו לתפקיד את פעולות ה-IAM של Mantle. דורש שער שמריץ Claude Code v2.1.318 או חדש יותר. שער מוקדם יותר יוצא בעת ההפעלה עם Unrecognized key(s) in object: 'assume_role'. |
base_url | לא | דריסת נקודת הקצה הנגזרת. השאירו את הנתיב /anthropic בסוף. |
העניקו לזהות ה-AWS של ה-upstream את פעולות ה-IAM של Mantle עצמו להסקה ולספירת אסימונים, שאותן מפרט Use the Mantle endpoint.
עבור מזהה מודל של Mantle שהשער לא מכיר, הוסיפו רשומה לבלוק models: ברמה העליונה, ש-upstream_model שלה ממפה את השם של ה-upstream הזה אל המזהה הזה. אחר כך שימו גם את ה-id של הרשומה הזו בשדה models של ה-upstream הזה.
ההגדרות guardrail ו-assume_role של upstream מסוג bedrock לא חלות על הבקשות ש-Mantle מגיש:
guardrail: השער לא מחיל Bedrock guardrail על בקשות שהוא שולח אל Mantle, ולכן הוא מסרב להתחיל כש-upstream מסוגmantleרשום בזמן ש-upstream כלשהו מסוגbedrockמגדירguardrail.assume_role: הגדירו אותו על ה-upstream מסוגmantleעצמו. בלעדיו, בקשות ש-Mantle מגיש נשלחות עם פרטי ההתחברות שלauthשל ה-upstream מסוגmantleעצמו.
למשמעות תגובות השגיאה של Mantle עצמו, ראו Mantle endpoint errors.
#Claude Platform on AWS
Claude Platform on AWS מגיש את ה-API הרשמי של Anthropic על תשתית AWS בכתובת aws-external-anthropic.<region>.api.aws. הוא משתמש במזהי מודלים רשמיים, מכבד כותרות anthropic-beta כפי שנשלחו, ומגיש את count_tokens, כך שאף אחת מההמרות הייחודיות ל-Bedrock לא חלה. ספק anthropicAws דורש Claude Code v2.1.198 או חדש יותר. גרסאות שער מוקדמות יותר דוחות אותו בעת האתחול.
לפריסה בצד הלקוח של אותה פלטפורמה, ראו Claude Code on Claude Platform on AWS. ה-upstream בצד השער:
upstreams:
- provider: anthropicAws
region: us-east-1
workspace_id: wrkspc_...
auth:
api_key: ${ANTHROPIC_AWS_API_KEY} # sent as x-api-key
# OR SigV4 via the AWS default credential chain:
# auth: {}
# OR explicit SigV4 credentials:
# auth:
# aws_access_key_id: ${AWS_ACCESS_KEY_ID}
# aws_secret_access_key: ${AWS_SECRET_ACCESS_KEY}
# Override the derived endpoint:
# base_url: https://aws-external-anthropic.us-east-1.api.awsהפלטפורמה רצה בחשבון AWS נפרד מ-Amazon Bedrock וחותמת בקשות SigV4 עבור שם השירות שלה, aws-external-anthropic, כך שתפקיד IAM שמוגבל ל-Bedrock לא מאשר אותה. מפתח API ב-auth.api_key מקבל עדיפות כשגם פרטי התחברות של SigV4 מוגדרים. בלוק auth ריק משתמש בשרשרת פרטי ההתחברות ברירת המחדל של AWS SDK, אותה שרשרת שבה משתמש ה-upstream Amazon Bedrock.
| שדה | חובה | תיאור |
|---|---|---|
region | כן | אזור AWS, אותיות קטנות, ספרות ומקפים. השער גוזר ממנו את נקודת הקצה כ-https://aws-external-anthropic.<region>.api.aws. |
workspace_id | כן | נשלח ככותרת בכל בקשה. הפלטפורמה דורשת אותו |
auth.api_key | לא | מפתח API לפלטפורמה, נשלח כ-x-api-key. זה לא אסימון bearer: שני מצבי האימות הם מפתח API או SigV4. |
auth.aws_access_key_id / auth.aws_secret_access_key | לא | פרטי התחברות מפורשים של SigV4. הגדרת אחד בלי השני נכשלת בעת האתחול. auth.aws_session_token מתקבל לצד שניהם. |
base_url | לא | דריסת נקודת הקצה הנגזרת |
מכיוון שהפלטפורמה פותרת מזהי מודלים רשמיים, הקטלוג המובנה מנתב אליה בלי בלוק models:. כשאתם אוצרים רשימת models:, מפתחו את הרשומה ב-anthropicAws: עם המזהה הרשמי.
#Google Cloud Agent Platform
להגדרה המקבילה בצד הלקוח, ראו Claude Code on Google Cloud. ה-upstream בצד השער:
upstreams:
- provider: vertex
region: us-east5
project_id: example-prod
auth: {} # preferred: Application Default Credentials
# OR a service account key file:
# auth: { service_account_json: /secrets/sa.json }
# Override the aiplatform endpoint for Private Service Connect:
# base_url: https://us-east5-aiplatform.p.googleapis.comבלוק auth ריק משתמש ב-Application Default Credentials: GOOGLE_APPLICATION_CREDENTIALS, מטא-נתונים של GCE, או GKE Workload Identity. קבצי מפתח JSON של חשבון שירות נתמכים אבל לא מומלצים. השתמשו ב-Workload Identity או צרפו חשבון שירות למופע GCE או Cloud Run.
הגדירו region: global כדי להשתמש ב-נקודת הקצה הגלובלית של Agent Platform של Google Cloud במקום בנקודת קצה אזורית. Google מנתבת אז כל בקשה לאזור זמין, כך שאין צורך לעקוב אחרי זמינות מודל לפי אזור. הגדרת אזור מסוים מצמידה כל בקשה אליו.
| הגדרה | איך |
|---|---|
| הרשאות IAM | העניקו לחשבון השירות של השער את roles/aiplatform.user בפרויקט, או תפקיד מותאם עם aiplatform.endpoints.predict. הפעילו את ה-API של Agent Platform של Google Cloud (aiplatform.googleapis.com). |
| גישה למודלים | ב-Model Garden, הפעילו את מודלי Claude עבור הפרויקט שלכם. הם מתפרסמים לאזורים מסוימים. בדקו בכרטיס המודל את האזורים הנתמכים. |
| GKE (Workload Identity) | קשרו חשבון שירות של GCP לחשבון השירות של Kubernetes של השער, וסמנו את ה-KSA ב-iam.gke.io/gcp-service-account: claude-gateway@<proj>.iam.gserviceaccount.com. auth: {} קולט אותו. |
| Cloud Run / GCE | הגדירו את חשבון השירות של השירות לחשבון עם roles/aiplatform.user. auth: {} קולט אותו. |
| בכל מקום אחר | auth: { service_account_json: /secrets/sa.json }, הנתיב לקובץ מפתח JSON שמורכב כסוד. השדה מקבל נתיב קובץ, לא את תוכן המפתח, כך שאין הרחבה של ${file:…}. |
#Microsoft Foundry
לפריסת Microsoft Foundry בצד הלקוח, ראו Claude Code on Microsoft Foundry. ה-upstream בצד השער:
upstreams:
- provider: foundry
resource: example-foundry # https://example-foundry.services.ai.azure.com
auth: { use_azure_ad: true } # preferred: DefaultAzureCredential / Managed Identity
# OR an API key:
# auth:
# api_key: ${FOUNDRY_API_KEY}use_azure_ad: true נפתר דרך DefaultAzureCredential: Managed Identity ב-AKS, ב-ACI או ב-App Service, Azure CLI, או פרטי התחברות מסביבה. מפתחות API עובדים אבל הם ברמת הפרויקט ולא מתחלפים אוטומטית. נקודת הקצה של Microsoft Foundry נגזרת מ-resource:. הגדירו את base_url האופציונלי כדי לדרוס אותה עבור עננים ריבוניים כמו Azure Government.
| הגדרה | איך |
|---|---|
| RBAC | העניקו לזהות השער את Azure AI User או Cognitive Services User על משאב Microsoft Foundry |
| פריסות | Microsoft Foundry משתמש בשמות פריסה שהמנהל בחר, לא במזהי מודל קנוניים. הוסיפו בלוק models: שממפה כל מזהה קנוני לשם הפריסה שלכם. |
| AKS (workload identity) | אחדו User-Assigned Managed Identity עם מנפיק ה-OIDC של האשכול וקשרו אותו לחשבון השירות של השער. use_azure_ad: true קולט אותו דרך WorkloadIdentityCredential. |
| ACI / App Service | הפעילו managed identity שמוקצה על ידי המערכת או על ידי המשתמש על המשאב. use_azure_ad: true קולט אותו. |
| בכל מקום אחר | auth: { api_key: "${FOUNDRY_API_KEY}" }. שימו ${…} במרכאות בתוך { }. |
#כותרות סטטיות בבקשות upstream
כדי להוסיף כותרות קבועות לבקשות שהשער שולח ל-upstream אחד, הגדירו headers: על אותו upstream. השתמשו בזה כשפרוקסי שאתם מריצים לפני הספק מנתב או משייך תעבורה לפי כותרת.
headers: דורש Claude Code v2.1.277 או חדש יותר בשרת השער. שער מוקדם יותר מסרב להתחיל כשהוא מוצא את המפתח. שדרגו כל עותק לפני שאתם מוסיפים את המפתח, והסירו את המפתח לפני שאתם חוזרים לגרסה מוקדמת יותר.
הכותרות הולכות לשרת ש-base_url מציין, או לנקודת הקצה של הספק עצמו כש-base_url לא מוגדר. גם הספק מקבל אותן, אלא אם הפרוקסי שלכם מסיר אותן.
הדוגמה הזו מגיעה ל-upstream של provider: vertex דרך פרוקסי ב-upstream-proxy.internal.example.com. היא מגדירה את הכותרת x-source שהפרוקסי קורא, ושולחת אסימון ממשתנה הסביבה PROXY_TOKEN כ-x-proxy-token:
upstreams:
- provider: vertex
region: us-east5
project_id: example-prod
base_url: https://upstream-proxy.internal.example.com
auth: {}
headers:
x-source: claude-apps-gateway
x-proxy-token: ${PROXY_TOKEN}הערכים הם טקסט ASCII להדפסה בלי רווח באף אחד מהקצוות. שימו מספר, true או false במרכאות כדי ש-YAML יקרא אותם כטקסט.
כדי להשאיר סוד מחוץ לקובץ התצורה, השתמשו ב-הרחבת סודות כדי לטעון את הערך ממשתנה סביבה עם ${VAR} או מקובץ עם ${file:/path}. ${VAR} שנפתר לערך ריק עוצר את השער מלהתחיל.
headers: עובד בכל ספק, וכל upstream שולח רק את שלו.
לא כל בקשה שהשער שולח ל-upstream נושאת אותן:
| הבקשה שהשער שולח ל-upstream הזה | נושאת headers: |
|---|---|
/v1/messages, עם או בלי הזרמה, וגם /v1/messages/count_tokens | כן |
| בקשה שעברה failover מ-upstream אחר | כן, רק headers: של ה-upstream הזה |
קריאת CountTokens של Amazon Bedrock עבור בקשה שהלקוח נטש | לא |
| החלפת האסימון של Workload Identity Federation | לא |
ב-upstream של Amazon Bedrock או של Claude Platform on AWS שחותם בקשות עם AWS SigV4, הכותרות האלה הן חלק מהחתימה, כך שהפרוקסי שלכם חייב להעביר אותן בלי שינוי.
אם אתם משתמשים בשם שהשער שומר, הוא מסרב להתחיל, ושגיאת ההפעלה מציינת את הכותרת. שמות שמורים כוללים:
authorizationו-x-api-keyhost,content-typeו-user-agent- כל שם שמתחיל ב-
anthropic-,x-goog-,x-amz-אוx-amzn-
#upstreams מרובים
אותו ספק יכול להופיע יותר מפעם אחת עם name: נפרד. זה מכסה אזורים שונים, חשבונות שונים דרך שרשראות פרטי התחברות שונות, provisioned throughput לעומת לפי דרישה, וגיבוי בין ספקים.
השער מנסה upstreams לפי הסדר. 5xx, 429, 401, 403, 404, פסקי זמן, ונקודת קצה חסרה (501) עוברים failover. שאר 4xx לא.
429 הוא קיבולת לכל upstream, כך שמיצוי של provisioned throughput (PT) עובר failover לפי דרישה. אם אתם מגדירים forward_user_identity: true על upstream, 429 לבקשה שנשאה את הדוא"ל של המפתח הוא סירוב לכל משתמש במקום זאת, ולא עובר failover.
בקשה עוברת מעבר ל-upstream רק במקרים האלה:
- ה-upstream נכשל
- ה-upstream לא מגיש את המודל המבוקש
- ל-upstream יש רשימת
groupsשמשאירה את המפתח בחוץ
השער לא שומר תיעוד של upstreams שנכשלו, כך שכל עוד upstream מושבת, כל בקשה שמגיעה אליו עדיין מנסה אותו וממתינה שייכשל לפני שהיא ממשיכה.
השער ממתין כך להתחלת תגובה:
- upstreams של
provider: anthropic:timeouts.upstream_ttfb_ms, 120 שניות כברירת מחדל - ספקים אחרים: עד שעה. כדי לקצר את ההמתנה הזו לבקשות הזרמה, הגדירו
timeouts.upstream_ttfb_msבשער v2.1.295 או חדש יותר. בקשות מודל בלי הזרמה ממתינות עד שעה בכל מקרה
404 הוא זמינות מודל לכל upstream, כך ש-upstream שלא הפעיל מודל לא חוסם upstream מאוחר יותר שמגיש אותו. upstream שלא יכול לפתור את המודל המבוקש מדולג בלי הלוך ושוב ברשת.
הדוגמה הזו מנתבת הקצאת provisioned throughput של Amazon Bedrock ראשונה, גולשת לפי דרישה ולחשבון שני, ונופלת ל-API של Anthropic אחרון:
upstreams:
# Primary: provisioned throughput in your home region.
- name: bedrock-pt
provider: bedrock
region: us-east-1
auth: {}
# Overflow: on-demand cross-region.
- name: bedrock-od
provider: bedrock
region: us-west-2
auth: {}
# Different account: a separate Bedrock allotment via static keys.
- name: bedrock-acct2
provider: bedrock
region: us-east-1
auth:
aws_access_key_id: ${ACCT2_AKID}
aws_secret_access_key: ${ACCT2_SK}
# Last resort: direct Anthropic API.
- name: anthropic-fallback
provider: anthropic
auth:
api_key: ${ANTHROPIC_API_KEY}
# Per-upstream model IDs are keyed on the upstream's `name:`.
models:
- id: claude-opus-4-8
label: Claude Opus 4.8
upstream_model:
bedrock-pt: arn:aws:bedrock:us-east-1:111111111111:provisioned-model/abcdef
bedrock-od: us.anthropic.claude-opus-4-8
bedrock-acct2: us.anthropic.claude-opus-4-8
anthropic-fallback: claude-opus-4-8| מנוף | איך |
|---|---|
| אזורים שונים | upstream אחד של Amazon Bedrock לכל אזור, כל אחד עם region: משלו. עם auto_include_builtin_models: true פרופילי ההסקה בין אזורים מנותבים אוטומטית. לפריסות שמוצמדות לאזור השתמשו בבלוק models:. |
| חשבונות שונים | upstream אחד של Amazon Bedrock לכל חשבון. שרשרת ברירת המחדל (auth: {}) משתמשת בזהות של ה-pod. לחשבון שני, הוסיפו assume_role כדי להגיע אליו עם פרטי התחברות קצרי חיים, או הגדירו פרטי התחברות מפורשים או אסימון bearer ב-auth:. |
| צוותים שונים | תנו ל-upstream של כל צוות רשימת groups, כך שרק מפתחים בקבוצות ה-IdP האלה מגיעים אליו. ראו Send each team to its own upstream. |
| Provisioned throughput | מפו את המודל ל-ARN של provisioned throughput ב-models: עבור השם של אותו upstream. upstreams אחרים שומרים את מזהה לפי הדרישה, כך שקיבולת ה-PT ממוצה לפני failover. |
| נקודות קצה של VPC / FIPS | הגדירו base_url: על ה-upstream לכתובת נקודת הקצה של ה-VPC או של FIPS |
| ניתוב לפי מודל | id של מודל מותאם, כזה שאינו מודל Claude מובנה, מדלג על ה-upstreams שנעדרים ממפת upstream_model: שלו. upstream עם רשימת models, ש-upstream מסוג mantle חייב שתהיה לו, מנוסה רק עבור המודלים האלה. |
| ניתוב מודל מובנה | ב-upstream בלי רשימת models או groups, השער מנסה מודלים מובנים לפי הסדר ומשתמש במזהה ברירת המחדל של הספק במקום שבו למפת upstream_model: אין רשומה. למודל מובנה שלספק יש עבורו מזהה ברירת מחדל, המפה משנה איזה מזהה ה-upstream מקבל ולא אם הוא מנוסה. upstream שדוחה את המזהה פועל לפי אותם כללי failover כמו כל שגיאת upstream אחרת. |
failover בין ספקי ענן, או אל ה-API הישיר של Anthropic, משנה איזה הסכם, גאוגרפיה ותנאים אחרים חלים על הבקשה.
ה-CLI מחיל את אותו שער תכונות על שערים בלי קשר לאיזה upstream מגיש בקשה נתונה, כך שכברירת מחדל failover לא שולח שדה גוף ש-upstream היה דוחה. אם אתם מגדירים את TTL המטמון של שעה במדיניות, הוא הולך לכל upstream ברשימה, לכן הגדירו אותו רק אם כולם מקבלים אותו.
#שליחת כל צוות ל-upstream משלו
כדי לשלוח את הבקשות של כל צוות לחשבון AWS או לפרויקט Google Cloud משלו, רשמו upstream אחד לכל צוות ותנו לכל אחד רשימת groups. רק מפתחים בקבוצת IdP שברשימה מגיעים ל-upstream הזה, בניסיון הראשון וב-failover. כל ספק מקבל groups. נדרש Claude Code v2.1.314 או חדש יותר בשרת ה-gateway.
הדוגמה הזו נותנת לקבוצות payments-eng ו-search-eng חשבון AWS לכל אחת, ומוסיפה upstream בלי רשימת groups שכל מפתח יכול להשתמש בו:
upstreams:
- name: bedrock-payments
provider: bedrock
region: us-east-1
auth: {}
assume_role:
role_arn: arn:aws:iam::111111111111:role/claude-gateway-bedrock
groups: [payments-eng]
- name: bedrock-search
provider: bedrock
region: us-east-1
auth: {}
assume_role:
role_arn: arn:aws:iam::222222222222:role/claude-gateway-bedrock
groups: [search-eng]
- name: bedrock-shared # no groups: open to everyone, so listed last
provider: bedrock
region: us-east-1
auth: {}עם תצורת הדוגמה, הבקשות של כל מפתח מתחילות ב-upstream הראשון בשורה שלו ועוברות לבא ב-failover:
| קבוצות המפתח | Upstreams, לפי הסדר |
|---|---|
payments-eng | bedrock-payments, ואז bedrock-shared |
search-eng | bedrock-search, ואז bedrock-shared |
payments-eng ו-search-eng | bedrock-payments, ואז bedrock-search, ואז bedrock-shared |
| אף אחת מהן | bedrock-shared |
כש-upstream של צוות דוחה את המודל המבוקש עם 403, ה-gateway מנסה את ה-upstream הבא בשורה של אותו צוות שמגיש את המודל. כדי להשאיר את הצוות על upstream אחד, תנו לכל upstream רשימת groups, וודאו שאף upstream אחר לא מציין קבוצה שהמפתחים של הצוות נמצאים בה. לצוות הזה אין אז failover, ובקשות ממפתחים שלא נמצאים באף קבוצה שברשימה נכשלות עם 400.
כדי להביא כל מפתח ל-upstream שאתם מתכוונים אליו, כתבו רשומות שתואמות בדיוק ושימו upstreams פתוחים בסוף:
- רשומות: כתבו כל קבוצה בדיוק כפי שה-IdP שולח אותה ב-groups claim, שגם
match.groupsקורא. ה-gateway מסרב להתחיל כשהוא מוצא רשימה ריקה או רשומה ריקה. הוא לא בודק רשומה מול ה-IdP, ולכן רשומה שלא תואמת לאף אחד לא מעלה אזהרה. - סדר: שימו upstream שאין לו רשימת
groupsבסוף. הוא משרת את כולם, ולכן אם הוא מופיע מוקדם יותר הוא לוקח את הבקשות של צוות לפני ה-upstream של הצוות עצמו.
[!WARNING]
gateway מוקדם מ-v2.1.314 מסרב להתחיל כשהוא מוצא
groups, אז שדרגו כל replica לפני שאתם מוסיפים אותו.לפני rollback, הסירו כל upstream שיש לו רשימת
groupsוכל מפתחupstream_modelאו pricing override שמציין אותו, והשאירו לפחות upstream אחד. כשרק מפתחgroupsהוסר, ה-upstream הזה פתוח לכל מפתח. מפתח או override שעדיין מציין upstream שהוסר עוצר את ה-gateway מהתחלה, עםreferences unknown upstream.
#מה קורה כשמפתח לא נמצא באף קבוצה שברשימה
אם לכל upstream יש רשימת groups, מפתח שלא נמצא באף אחת מהקבוצות האלה רואה את השגיאה הזו, וה-gateway לא פונה לאף ספק:
API Error: 400 you aren't in a group that can use this gateway. Ask your administrator to add you to oneהוסיפו את המפתח לקבוצה שברשימה ב-IdP, או הוסיפו upstream בלי רשימת groups.
ה-gateway קורא שוב את הקבוצות של מפתח בכל רענון token. אם ה-IdP משמיט קבוצות מרענון, למפתח אין אז אף קבוצה:
oidc.allowed_groupsמוגדר: ה-gateway מסרב לרענון, והסשן מסתיים- אחרת, ל-upstream אין רשימת
groups: הבקשות של המפתח עוברות אליו - אחרת, לכל upstream יש רשימת
groups: הבקשות של המפתח נכשלות עם השגיאה הזו
אם נקודת הקצה userinfo של ה-IdP מחזירה את ה-groups claim ו-oidc.google_groups לא מוגדר, הגדירו את oidc.userinfo_fallback ל-true כדי למלא את הקבוצות משם.
#מקטעים אופציונליים
#admin
אופציונלי. מפעיל את /v1/organizations/spend_limits, שמשקף את Admin API הציבורי של Anthropic, ואכיפת הוצאה לכל מפתח ב-/v1/messages. ראו Spend limits לאופן קביעת תקרות ואכיפתן. המקטע הזה מכסה את המפתחות ב-gateway.yaml שמפעילים את התכונה ומכוונים אותה.
admin:
# Named static API keys for the admin endpoints, sent as x-api-key.
# The id appears in the audit log as admin-key:<id> so each key is
# attributable. Array for rotation: add the new key, roll clients,
# remove the old.
write_keys:
- { id: terraform, key: "${GATEWAY_ADMIN_WRITE_KEY_TF}" }
- { id: ci, key: "${GATEWAY_ADMIN_WRITE_KEY_CI}" }
read_keys:
- { id: reporting, key: "${GATEWAY_ADMIN_READ_KEY}" }
# IdP groups granted full admin via the normal gateway JWT (no API key).
admin_groups: [platform-finops]
blocked_message: request an increase at https://go.example.com/claude-limits| שדה | נדרש | תיאור |
|---|---|---|
write_keys | לא | מערך של {id, key}. x-api-key שתואם לאחד מאלה יכול לרשום, להגדיר ולמחוק מגבלות הוצאה. ערכי המפתח חייבים להיות באורך 32 תווים לפחות. ערכי id חייבים להיות ייחודיים בין read_keys ו-write_keys. |
read_keys | לא | מערך של {id, key}. לקריאה בלבד: כל נקודת קצה GET, כולל רישום תקרות, שליפת אחת לפי ID, וקריאה של /effective ו-/audit. |
admin_groups | לא | שמות קבוצות IdP. JWT של ה-gateway שה-claim groups שלו כולל אחת מאלה מקבל גישת admin מלאה, קריאה וכתיבה, ומתועד בביקורת כ-oidc:<sub>. השתמשו בזה למנהלים אנושיים. השתמשו במפתחות API למכונות. רשומה ריקה ברשימה הזו עוצרת את ה-gateway באתחול. ראו Matcher values that stop the gateway at boot. |
blocked_message | לא | מצורף כלשונו ל-429 billing_error שמפתח חסום רואה. כתבו את כל ההנחיה, כגון URL או ערוץ Slack. כשהשדה לא מוגדר, ה-gateway שולח רק את הודעת ברירת המחדל. ראו How enforcement works. |
audit_retention_days | לא | ברירת מחדל 365. שורות admin_audit ישנות יותר מנוקות. |
spend_retention_months | לא | ברירת מחדל 13. שורות מונה spend ישנות מזה מנוקות. ברירת המחדל שומרת שנה מלאה ועוד החודש החלקי הנוכחי לדיווח משנה לשנה. |
identity_retention_days | לא | ברירת מחדל 90. TTL של נראה לאחרונה לשורות principal_emails, שמחזיקות את האימייל, שם התצוגה והקבוצות של כל מפתח (PII). קצר במכוון משמירת ההוצאה, כדי שזהות שההקצאה שלה בוטלה תתיישן ותצא, בזמן שמוני ההוצאה האנונימיים שלה נשארים. |
group_limit_mode | לא | min (ברירת מחדל) או max. כשמפתח נמצא בכמה קבוצות עם תקרות, min אוכף את המגבילה ביותר ו-max את הפחות מגבילה. בשימוש גם באכיפה וגם ב-/effective. |
#enforcement
בלוק enforcement שולט באופן שבו בדיקות מגבלת הוצאה מתנהגות כשהאחסון לא זמין.
| שדה | נדרש | תיאור |
|---|---|---|
fail_closed_on_error | לא | ברירת מחדל false. אכיפת ההוצאה נכשלת במצב fail open בהשבתת Postgres, כך שההסקה נשארת פעילה. הגדירו true כדי fail closed: מפתחים מעל התקרה נחסמים, וכך גם כל השאר אם האחסון לא נגיש. נדרש בלוק admin:: אכיפת הוצאה רצה רק כש-admin מוגדר, וה-gateway מסרב להתחיל אם מגדירים את זה ל-true בלי בלוק כזה. |
#pricing
בלוק pricing אומר למד ההוצאה מה לחייב במקום מחיר המחירון ב-USD, כדי שתקרות ו-/effective ישקפו את התעריפים החוזיים שלכם. הסכומים נשארים ב-USD ונשארים אומדן, לא חשבונית. שתי דרישות מוקדמות:
- Claude Code v2.1.227 או חדש יותר בשרת ה-gateway. גרסאות מוקדמות יותר דוחות את המפתח הלא מוכר באתחול.
- בלוק
admin:או, ב-v2.1.268 או חדש יותר, בלוקmanaged:עם לפחות מדיניות אחת. ה-gateway מסרב להתחיל כש-pricingמוגדר ואין אף אחד משני הבלוקים, כי שום דבר לא יקרא אותו.
pricing:
multiplier: 0.85
overrides:
- upstream: bedrock-eu
model: claude-sonnet-4-6
input: 3.30
output: 16.50
cache_read: 0.33
cache_write: 4.125| שדה | נדרש | תיאור |
|---|---|---|
multiplier | לא | ברירת מחדל 1. המד מכפיל כל סכום שנמדד בערך הזה, בין אם לפי מחירון ובין אם לפי override, כך ש-0.85 מחייב 85% מהמחיר. חייב להיות גדול מ-0 ולכל היותר 10, וערך מעל 1 הוא markup. |
overrides | לא | שורות של {upstream, model, input, output, cache_read, cache_write} ב-USD למיליון טוקנים. כל ארבעת התעריפים נדרשים. כל אחד חייב להיות גדול מ-0 ולכל היותר 10000. |
איך המד מתאים שורת override:
- שורה מחליפה את מחיר המחירון לבקשות ש-
upstream, שהואupstreams[].name, מגיש עבורmodel. זה כולל את תעריף fast mode הגבוה יותר, כך שבקשות fast ובקשות standard נמדדות באותם ארבעה תעריפים. - מזהה מובנה כגון
claude-sonnet-4-6, שמותאם כמוmodels[].id, מכסה כל צורה מתוארכת, צורה אזורית של Amazon Bedrock, או צורה של Agent Platform של Google Cloud שהמד מתמחר כמודל הזה. כל מחרוזת אחרת, כגון alias או ARN של inference-profile, תואמת את ה-ID שהלקוח שלח או את המחרוזת שנשלחה upstream, בלי תלות ברישיות. - כשיש חפיפה בין שורות, המד בוחר את השורה הספציפית ביותר ולא את השורה הראשונה: שורה ש-
modelשלה הוא מחרוזת המודל המדויקת שנשלחה upstream, אחר כך שורה שתואמת את ה-ID המדויק שהלקוח שלח, ואחר כך שורה שמציינת את המודל המובנה. - שם upstream לא מוכר נכשל באתחול, וכך גם שתי שורות ל-upstream אחד שמציינות את אותו מודל, כולל שתי איותים של מודל מובנה אחד. ה-gateway מזהיר באתחול על שורה שאף מודל שאפשר לבקש לא יכול להשתמש בה.
- בקשות web-search נשארות במחיר המחירון של $0.01. ה-multiplier עדיין חל עליהן.
לתעריפים לפי אזור, תנו לכל אזור upstream עם שם משלו ושורה אחת לכל upstream.
#העלאת מחירים
עם v2.1.271 או חדש יותר בשרת ה-gateway, אפשר להגדיר multiplier מעל 1, עד 10, כדי למדוד יותר ממה שהספק גובה, לדוגמה תעריף chargeback פנימי. הדוגמה הזו מודדת כל בקשה ב-120% מהמחיר:
pricing:
multiplier: 1.2עם בלוק admin:, ה-markup חל גם על מגבלות הוצאה. המד סופר 120% מהמחיר, ולכן מפתחים מגיעים לתקרות שלהם מוקדם יותר. ה-gateway רושם אזהרה בזמן האתחול שאומרת זאת.
ה-multiplier לא משנה את מה שספק ה-upstream גובה עבור הבקשות.
אם ה-gateway גם שולח את התעריפים ללקוחות מחוברים, מפתחים צריכים Claude Code v2.1.271 או חדש יותר כדי לראות את ה-markup. לקוחות מוקדמים יותר מתעלמים מ-multiplier מעל 1 ומציגים עלויות בלעדיו.
שרת gateway מוקדם מ-v2.1.271 מסרב להתחיל אם מגדירים multiplier מעל 1.
#שליחת התעריפים ללקוחות מחוברים
עם v2.1.268 או חדש יותר בשרת ה-gateway, ה-gateway גם מכניס את התעריפים מ-pricing למדיניות managed שהוא מגיש, כהגדרת הניהול modelPricing.
מפתחים שמדיניות מתאימה להם רואים אז את תעריפי pricing ב-/usage, בשורת המצב, וב-OpenTelemetry. מפתח שלא תואם לאף מדיניות לא מקבל הגדרות מנוהלות, ולכן המספרים שלו נשארים במחיר המחירון. לקוחות מיישמים את ההגדרה ב-Claude Code v2.1.242 או חדש יותר.
- מה ה-gateway מוסיף: אלא אם בלוק
cliשל מדיניות כבר מגדירmodelPricing, ה-gateway מוסיף את ה-multiplierו, לכל מזהה מודל שלקוח יכול לבקש, את שורת ה-override של ה-upstream הראשון שמגיש את המזהה הזה. תעריף שרק upstream של failover גובה נשאר ב-gateway. - Upstreams עם רשימת
groups: כשאחד מהם הוא ה-upstream הראשון שמגיש מזהה מודל, ה-gateway לא מוסיף שורה למזהה הזה. מפתחים רואים אז את התעריף של Claude Code עצמו למזהה הזה, שהוא התעריף הסטנדרטי של המודל כש-Claude Code מזהה את המזהה, כפול ה-multiplier. - הוצאת מדיניות אחת: הגדירו
modelPricingל-{}בבלוקcliשל אותה מדיניות, והמפתחים שלה נשארים במחיר המחירון. - שמירה על התעריפים של מדיניות: מדיניות שבלוק
cliשלה מגדירmodelPricingעםmultiplierאוoverridesמשלה שומרת את ה-modelPricingהזה בשלמותו, וה-gateway לא מוסיף לה תעריפים משלו.
#models
בלוק models הוא רשימת מודלים אופציונלית שאדמין אוצר, מוגשת ב-/v1/models ומשמשת לתרגום מזהי מודל לפי upstream. הוא נדרש לאזורי Amazon Bedrock שאינם בארה"ב, ל-ARN של provisioned-throughput ב-Amazon Bedrock, ולשמות פריסה של Microsoft Foundry.
auto_include_builtin_models: true # false: expose only the list below
models:
- id: claude-opus-4-8
label: Claude Opus 4.8
# description: optional text shown in clients that surface it
upstream_model:
anthropic: claude-opus-4-8
bedrock: us.anthropic.claude-opus-4-8 # or an inference-profile ARN
foundry: your-opus-deployment-nameכל מפתח תחת upstream_model חייב להתאים ל-name של upstream מוגדר, שברירת המחדל שלו היא שם הספק. מפתח שלא תואם לאף upstream נכשל באתחול, אז השמיטו את השורות לספקים שאתם לא משתמשים בהם.
#managed
בלוק managed מגדיר מדיניות גישה מבוססת תפקידים לפי קבוצות IdP או דומיין דוא"ל. המדיניות מוערכת לפי הסדר. כברירת מחדל נבחרת ההתאמה הראשונה, ואז היא ממוזגת על בסיס ה-catch-all של match: {}. משתמש שתואם שתי מדיניות תפקיד מקבל רק את הראשונה, ולכן כללי הדחייה של המדיניות השנייה לא חלים אלא אם מיישמים כל מדיניות תואמת. המדיניות מוגשת לכל משתמש ב-GET /managed/settings עם מטמון ETag/304.
managed:
policies:
# Specific groups first.
- match: { groups: [eng-contractors] }
cli:
availableModels: [claude-sonnet-4-6]
permissions: { deny: ["WebFetch", "WebSearch"] }
# Default catch-all last: matches everyone who authenticated.
- match: {}
cli:
availableModels: [claude-opus-4-8, claude-sonnet-4-6, claude-haiku-4-5]
# Make the Default option in /model resolve inside each policy's
# list. The eng-contractors policy inherits enforceAvailableModels.
enforceAvailableModels: truematch: {} מסוג catch-all, שבדרך כלל מופיע אחרון, נחשב לשכבת בסיס. כל מדיניות אחרת יורשת מה-catch-all כל מפתח שהיא לא מגדירה, ולכן רשומות לפי תפקיד צריכות לפרט רק את מה ששונה מברירת המחדל של הארגון. כללי המיזוג תלויים בסוג המפתח:
- רשימות היתר:
availableModelsו-permissions.allow. הרשימה של מדיניות ספציפית מחליפה במלואה את רשימת הבסיס. - רשימות דחייה ומערכי hook:
permissions.deny,permissions.ask,disabledMcpjsonServers,deniedMcpServers,blockedMarketplaces,deniedModels, וכל מערך מסוג אירוע ב-hooks. אלה לוקחים את האיחוד של הבסיס והמדיניות, כך שדחייה או hook ביקורת ברמת הארגון לא יכולים להישמט בטעות בגלל דריסה לפי תפקיד. - מפתחות מסוג רשומה:
env,modelOverridesו-skillOverrides. אלה עוברים מיזוג שטחי, כך שבלוקenvלפי תפקיד דורס מפתחות שהוא מגדיר ויורש את השאר מהבסיס.
availableModels נאכף גם בצד השרת ב-/v1/messages, כך שמודל שנדחה מחזיר 400 בלי קשר למה שהלקוח שולח. רשימה ריקה דוחה כל מודל. הבדיקה מכסה גם את המודל שעליו סשן מתחיל לפני שהמפתח בוחר אחד, ולכן התחילו סשנים על מודל שהמדיניות מתירה.
השער מאמת את ערך model עצמו לפני שהוא מעביר בקשה, כך שערך לא תקין אף פעם לא מגיע ל-upstream. הוא דוחה את הבקשה עם 400 בשני מקרים:
- כשהערך חסר או ריק, השער דוחה את הבקשה עם ההודעה
model is required. הבדיקה הזו דורשת שער שמריץ Claude Code v2.1.228 או חדש יותר. - כשהערך קיים אבל אינו מחרוזת, השער דוחה את הבקשה עם ההודעה
model must be a string. נדרש שער שמריץ Claude Code v2.1.221 או חדש יותר.
| Matcher | Behavior |
|---|---|
match: {} | תואם כל משתמש מאומת. התחילו באחד כזה והוסיפו מדיניות בהיקף קבוצה מעליו אחר כך. |
match: { groups: [a, b] } | תואם אם ה-claim groups ב-JWT מכיל אחת מהקבוצות שברשימה. תלוי רישיות: הקבוצות חייבות להתאים בדיוק לרישיות של ה-IdP. |
match: { email_domain: example.com } | תואם את החלק שאחרי ה-@ האחרון ב-claim email של ה-JWT, בלי תלות ברישיות. מקבל דומיין אחד לכל מדיניות. |
match: { groups: [a], email_domain: example.com } | שני התנאים חייבים להתאים |
משתמש מאומת שלא תואם אף מדיניות מקבל את ברירות המחדל של השער, כלומר כל מודל בקטלוג ובלי הגדרות managed. הוסיפו catch-all של match: {} בסוף אם רוצים מדיניות ברירת מחדל מובטחת.
שימו כללי דחייה ברמת הארגון במדיניות match: {}, כי כללי מדיניות קבוצה חלים רק כל עוד הטוקן של המשתמש נושא את הקבוצה הזו.
[!NOTE]
השער לא מחזיק ספריית משתמשים משלו. הוא מאשר כל בקשה לפי טוקן ה-IdP של המשתמש, קורא חברות בקבוצות מ-claim
groupsשל הטוקן ומעריך מדיניות מולו. אין רשימה למנות ואין חשבונות ליצור מראש, ולכן אין נקודת קצה של SCIM, כי אין ל-SCIM לאן לסנכרן.נהלו את מחזור החיים של משתמשים וקבוצות במקור האמת, שהוא הקצאת SCIM המקורית של ה-IdP או פלטפורמת identity-governance ייעודית. חברות בקבוצות וביטול הקצאה שמנוהלים שם זורמים לשער אוטומטית דרך הטוקן. אם רוצים הקצאת SCIM של חשבונות Claude עצמם, זו יכולת של Claude for Enterprise.
חלים שני לוחות זמנים של הפצה:
- תוכן המדיניות: עריכת מדיניות ופריסה מחדש מגיעות ללקוחות Claude Code מחוברים בסקר הבא של managed-settings, בתוך שעה, מלבד השינויים שחלים רק בהפעלה הבאה
- חברות בקבוצה: שינוי חברות המשתמש בקבוצה משנה איזו מדיניות תואמת אותו. זה נכנס לתוקף בהנפקה מחדש הבאה של הסשן, כלומר הרענון השקט הבא, בגבול של
session.ttl_hours.Claude Desktop פועל לפי לוח הזמנים שלו.
#יישום כל מדיניות תואמת
משתמש שתואם כמה מדיניות תפקיד מקבל רק את הראשונה אלא אם מגדירים policy_mode: layered ליד policies. עם layered, כל מדיניות שתואמת את המשתמש חלה, עד למדיניות match: {} הראשונה.
policy_mode דורש Claude Code v2.1.316 או חדש יותר בשרת השער. שער בגרסה שאין בה את זה מסרב להתחיל כשהוא מוצא את המפתח. שדרגו כל replica לפני שמוסיפים את המפתח, והסירו את המפתח לפני חזרה לגרסה מוקדמת יותר. בדוגמה הזו יש קבוצה אחת שמאבדת את WebFetch ואחת שמקבלת את Opus:
managed:
policy_mode: layered
policies:
- match: { groups: [no-web] }
cli:
permissions: { deny: ["WebFetch"] }
- match: { groups: [opus-users] }
cli:
availableModels: [opus, sonnet]
- match: {}
cli:
availableModels: [sonnet]
enforceAvailableModels: trueהטבלה מראה מה מקבל משתמש שנמצא גם ב-no-web וגם ב-opus-users תחת ברירת המחדל, first_match, ותחת layered.
| Setting | first_match | layered |
|---|---|---|
availableModels | sonnet | opus, sonnet |
enforceAvailableModels | true | true |
permissions.deny | WebFetch | WebFetch |
השער ממזג כל מדיניות תואמת על אלה שרשומות מתחתיה, לפי אותם כללי מיזוג כמו שכבת הבסיס:
- רשימות היתר, ערכים בודדים, ובלוקים כמו
sandbox: כל אחד מגיע בשלמותו מהמדיניות התואמת הראשונה ברשימה שמגדירה אותו, כך שרשימותavailableModelsשל שתי קבוצות לא מצטברות. - רשימות דחייה ומערכי hook: אלה מצטברים על פני כל מדיניות תואמת, כך שמשתמש בשתי קבוצות מקבל את כללי הדחייה של שתי הקבוצות.
env,modelOverridesו-skillOverrides: הרשומות מתמזגות לפי שם, והמדיניות התואמת הראשונה ברשימה שמגדירה שם מספקת את הערך שלו.- מפתחות
desktop: אלה מתמזגים לפי הכללים לבלוקdesktopהבסיסי.
[!WARNING]
מדיניות יכולה להצטבר לכללים רופפים יותר ממה שכל אחת מהן נותנת לבדה. לדוגמה, מדיניות
match: {}מגדירהsandbox.enabled: true, מדיניות של קבוצה אחת מגדירהpermissions.allow: ["Bash"], ומדיניות של קבוצה אחרת מגדירהsandbox.enabled: false. משתמש בשתי הקבוצות מקבלBashמותר עם sandbox כבוי. במקרה הזה, רשמו קודם את המדיניות שמתירה אתBash, והעתיקו לתוכה את כל בלוקsandboxשל מדיניותmatch: {}.
עם layered, השער מסרב להתחיל על חלק מההגדרות, כולל אלה:
- תבנית
!: שלילת!בכללReadאוEditברשימתpermissions.denyאוpermissions.askשל כל מדיניות, כולל מדיניותmatch: {} - מגבלה על hooks מחוץ ל-catch-all:
disableAllHooks,allowedHttpHookUrls, אוhttpHookAllowedEnvVarsבכל מדיניות שאינהmatch: {}
#התחלת סשנים על מודל שהמדיניות מתירה
אם availableModels משמיט את מודל ברירת המחדל של Claude Code, סשנים מקבלים תשובות 400 עד שהמפתח בוחר מודל מהרשימה, לדוגמה עם /model. בסשנים של השער ברירת המחדל היא מודל Opus שאליו הכינוי opus מצביע, ו-availableModels לבדו לא משנה אותה.
כדי לתקן את זה, הגדירו enforceAvailableModels: true באותו בלוק cli, ואז בדקו איזה סוג רשומה יש ברשימה:
- כינוי כמו
sonnet, או מזהה מובנה כמוclaude-sonnet-4-6: סשנים מתחילים על אחד מהמודלים האלה, ואפשרות Default ב-/modelמצביעה אליו - אין כינוי או מזהה מובנה ברשימה: סשנים יכולים להמשיך להתחיל על ברירת המחדל המובנית, ולכן הגדירו גם
modelלאחד מהמזהים שברשימה בבלוקcliשל אותה מדיניות
המדיניות הזו מפרטת מזהה מותאם אחד ש-models מגדיר, ומתחילה סשנים על המזהה הזה:
managed:
policies:
- match: { groups: [restricted-projects] }
cli:
availableModels: [restricted-claude-opus-4-8]
enforceAvailableModels: true
model: restricted-claude-opus-4-8
env:
ANTHROPIC_DEFAULT_OPUS_MODEL: restricted-claude-opus-4-8 # opus and Default resolve to the ID too#ערכי matcher שעוצרים את השער בעלייה
בעלייה, השער בודק את בלוק match של כל מדיניות ואת רשימת admin_groups. כל אחד מהערכים האלה עוצר את השער עם שגיאה שמציינת את השדה:
- רשימת
groupsריקה - רשומה ריקה ב-
groupsאו ב-admin_groups email_domainריקemail_domainשמכיל@, רווח לבן, או פסיק. השער חותך רווחים מהערך ומסיר@מוביל אחד לפני הבדיקה הזו. כתבו דומיין חשוף אחד, כמוexample.com.
לפני v2.1.232, השער עלה עם הערכים האלה. לכל ערך הייתה ההשפעה הזו:
email_domainריק: השער דילג על בדיקת הדומיין, כך שמדיניות עםemail_domainריק ובלי רשימתgroupsתאמה כל משתמש מאומת- רשימת
groupsריקה: המדיניות לא תאמה אף אחד email_domainשמכיל@, רווח לבן, או פסיק: המדיניות לא תאמה אף אחד- רשומה ריקה ב-
groupsאו ב-admin_groups: הרשומה תאמה משתמש רק כש-claimgroupsשל ה-IdP של המשתמש הכיל גם רשומה ריקה. ב-admin_groups, ההתאמה הזו העניקה גישת מנהל. אם רשימתadmin_groupsשלכם מעולם לא הכילה רשומה ריקה, אף אחד לא קיבל גישת מנהל בדרך הזו.
#בחירה בין cli ל-code
[!WARNING]
כשמדיניות משתמשת במפתח
code, כל אחד מאלה עוצר את השער מלהתחיל:
- גרסת השער:
codeדורש Claude Code v2.1.296 או חדש יותר בשרת השער. שער מוקדם יותר מסרב להתחיל כשהוא מוצא את המפתח. שדרגו כל replica לפני שמוסיפים את המפתח, ושנו אתcodeבחזרה ל-cliלפני חזרה לגרסה מוקדמת יותר.- מפתחות מעורבים: קובץ שיש בו גם
codeוגםcli, או האיות המוקדם יותרsettings, עוצר את השער בעלייה. שימו כל בלוק תחת מפתח אחד, בעריכה אחת.
הגדרות Claude Code של מדיניות, כמו כלל שדוחה קריאת קבצי .env, נכנסות לבלוק תחת המפתח cli או code. code הוא המפתח המומלץ, ו-cli הוא המפתח הישן. שני המפתחות מקבלים אותו תוכן. המפתח קובע איפה ההגדרות נאכפות:
cli: הטרמינל, התוספים של VS Code ו-JetBrains, ו-Agent SDK. תחתcli, לשונית Code של Claude Desktop מקבלת את ההגדרות הנגזרות, כך שכלל בהיקף כמוRead(./.env)לא עוצר משתמש שם.code: אותם מקומות, וגם לשונית Code של Claude Desktop יכולה להיות מכוסה.
קובץ שמשתמש ב-cli עובד כפי שעבד, ושער שמוצא cli במדיניות עם מפתח desktop מזהיר בעלייה ועולה בכל זאת. עברו ל-code כדי שההגדרות יוכלו לכסות גם את לשונית Code.
לפני המעבר, קראו את החלת הגדרות code בלשונית Code. המדיניות צריכה מפתח desktop והמחשבים של המשתמשים צריכים הגדרה לפני שההגדרות חלות שם, וחיפוש באינטרנט נכבה ב-Claude Desktop.
המדיניות הזו שמה את כלל הדחייה תחת code, עם מפתח desktop ריק:
managed:
policies:
- match: {}
code:
permissions: { deny: ["Read(./.env)"] }
desktop: {}במעבר, מחקו כל שורת serve_to_desktop באותה עריכה שמשנה את שמות הבלוקים. איפה שהוראה מציינת את בלוק cli, השתמשו בבלוק code שלכם.
serve_to_desktop: true היא דרך ישנה להציע את הגדרות cli של מדיניות ללשונית Code. אין לה השפעה כש-Claude Desktop מתחבר דרך bootstrapUrl. כל עוד המדיניות שלכם משתמשת ב-cli, אזהרת עלייה שמציינת את המפתח הזה אומרת שההגדרות האלה לא מגיעות ללשונית Code:
- כדי לכסות את לשונית Code: עברו ל-
code, אחרי שהמחשבים של המשתמשים עומדים בתנאים ב-החלת הגדרותcodeבלשונית Code - כדי להישאר על
cli: הגדירוserve_to_desktop: falseלידcliבמדיניות כדי להשתיק את האזהרה
#מה נכנס ב-cli
כל ערך code או cli הוא מסמך managed-settings.json מלא של Claude Code, אותה סכמה שהיית פורס דרך MDM או /etc/claude-code/managed-settings.json, מבוטאת כאן כ-YAML. ה-CLI מחיל את המסמך שנמסר בשכבה המנוהלת, מעל הגדרות משתמש ופרויקט, במקום הגדרות שמנוהלות בשרת. לכן הוא מתעלם מההגדרות המוגבלות למקורות מדיניות ברמת מערכת ההפעלה, כגון policyHelper ו-wslInheritsWindowsSettings.
השער מאמת כל מסמך מול סכמת ההגדרות של ה-CLI בעת האתחול, כך שמפתח ברמה העליונה שאינו מזוהה גורם לכשל באתחול עם שגיאה שמציינת כל מפתח פוגע. חלקים שנפתחו בכוונה בסכמה עדיין מקבלים ערכים שרירותיים, כי לקוחות חדשים יותר עשויים לזהות רשומות שהסכמה של השער אינה מזהה. המפתחות הפתוחים האלה כוללים את env, pluginConfigs, ומפתחות מקוננים תחת permissions.
מכיוון שהאימות משתמש בסכמה הארוזה עם הגרסה המותקנת של השער, הכנסת מפתח הגדרות ברמה העליונה שהוצג במהדורת Claude Code חדשה יותר לתצורה מנוהלת דורשת שדרוג של השער תחילה. בצע בדיקת עשן למדיניות חדשה על לקוח אחד לפני ההפצה.
הפניה המלאה למפתחות נמצאת בהגדרות Claude Code. המפתחות שרוב המפעילים ניגשים אליהם תחילה:
managed:
policies:
- match: {}
cli:
# Model access (also enforced server-side at /v1/messages)
availableModels: [claude-opus-4-8, claude-sonnet-4-6, claude-haiku-4-5]
enforceAvailableModels: true # Default resolves inside the list
# Permission policy
permissions:
deny:
- "WebFetch"
- "Read(./.env)"
- "Read(./secrets/**)"
disableBypassPermissionsMode: disable # blocks --dangerously-skip-permissions
allowManagedPermissionRulesOnly: true # ignore user/project permission rules
# Environment pushed into the CLI process. DISABLE_UPDATES blocks
# background and manual updates; DISABLE_AUTOUPDATER stops only
# background updates.
env:
DISABLE_UPDATES: "1" # pin versions via your own distribution
# Org-wide hooks. Hook commands run on developer machines, not the
# gateway, so the path must exist on every client OS in the policy.
hooks:
PostToolUse:
- matcher: "Edit|Write"
hooks:
- { type: command, command: /usr/local/bin/audit-edit.sh }| מפתח | נאכף על ידי | השפעה |
|---|---|---|
availableModels | שער + CLI | רשימת מודלים מותרים. נבדק גם ב-/v1/messages, כך שלקוח שעבר שינוי לא יכול לעקוף את זה. |
deniedModels, availableModelsMatch | שער + CLI | חסימת מודלים או גרסאות מסוימים ש-availableModels היה מתיר אחרת. מודל חסום נדחה עם 400 ב-/v1/messages ומושמט מ-/v1/models. הבדיקה של השער עצמו דורשת Claude Code v2.1.299 או מאוחר יותר בשרת השער. הבדיקה של ה-CLI דורשת v2.1.283 או מאוחר יותר בלקוחות, ולקוחות מוקדמים יותר מתעלמים משני המפתחות. |
permissions.allow / .deny | CLI | כללי כלים ופקודות. ראה הרשאות ומה כלל Bash אינו תואם. |
permissions.disableBypassPermissionsMode | CLI | הגדר ל-disable כדי לחסום את bypassPermissions, המצב שמדלג על בקשות הרשאה, ואת הדגל --dangerously-skip-permissions |
allowManagedPermissionRulesOnly | CLI | כאשר true, הגדרות מנוהלות הופכות למקור ההגדרות היחיד של כללי הרשאה. הרשומה allowManagedPermissionRulesOnly מפרטת כל מקור ש-Claude Code מתעלם ממנו אז. |
env | CLI | משתני סביבה שמוזגים לתהליך ה-CLI. השתמש לטלמטריה, עדכון אוטומטי ודריסות של שמות מודלים. |
hooks | CLI | hooks ברחבי הארגון |
managedMcpServers | CLI | שרתי MCP מרוחקים שמסופקים לכל מפתח תואם לצד השרתים שהם מוסיפים בעצמם, http ו-sse בלבד. ראה שרתי MCP במדיניות. דורש Claude Code v2.1.259 או מאוחר יותר בשרת השער ובלקוחות. לקוחות מוקדמים יותר מתעלמים מהמפתח. |
מכיוון שההגדרות האלה מגיעות דרך הרשת, ה-CLI מציג לכל מפתח תיבת דו-שיח לאישור אבטחה לפני החלת ההגדרות המפורטות להלן:
hooks- משתני
envשדורשים את אישור המפתח, כגון משתני proxy ו-base-URL - הגדרות הרצת מעטפת כגון
apiKeyHelperו-statusLine - הגדרות הבינארי של ארגז החול
sandbox.bwrapPath,sandbox.socatPathו-sandbox.ripgrep - הגדרות ארגז חול שמיירטות תעבורה, מזריקות אישורים או מחלישות בידוד, כגון
sandbox.network.tlsTerminateוהגדרות פורט ה-proxy. תיבות דו-שיח לאישור אבטחה מפרטות את כולן.
זיכרון אישור מכסה כמה זמן אישור נשמר ומתי תיבת הדו-שיח מופיעה שוב.
Claude Code מחיל חלק ממשתני env שנמסרו בלי להציג למפתח את תיבת הדו-שיח לאישור, כגון הגדרות בחירת מודל ומגבלות מספריות. משתנים שנמסרו אחרים יכולים לדרוש את אישור המפתח. ערך proxy, base-URL או OTEL_EXPORTER_OTLP_ENDPOINT שאינו ריק תמיד דורש זאת. כאשר משתנה שנמסר זקוק לאישור, תיבת הדו-שיח מציינת אותו. משתני סביבה ותיבת הדו-שיח לאישור כולל את הפרטים, כולל ארבעה מתגי פרטיות שהערך שנמסר שלהם קובע אם הם זקוקים לאישור.
תצורת הטלמטריה של השער דוחפת את OTEL_EXPORTER_OTLP_ENDPOINT, כך שהגדרת telemetry.forward_to מפעילה את תיבת הדו-שיח בכל לקוח אינטראקטיבי. תיבת הדו-שיח מגינה על המחשב של המפתח מפני שער שנפגע או עוין, ולא על הארגון מפני המפתח.
הרצה לא אינטראקטיבית, כגון claude -p, סשן Agent SDK, או סשן בלשונית Code של Claude Desktop, לא יכולה להציג את תיבת הדו-שיח. היא מחילה את ההגדרות שנדחפו להרצה הזו בלבד ואינה רושמת אותן כמאושרות, כך שהסשן האינטראקטיבי הבא של המפתח עדיין מציג את תיבת הדו-שיח.
אם מפתח מסרב, Claude Code יוצא מהסשן הזה במקום להחיל את המדיניות. כאשר אתה דוחף hook חדש, או כל משתנה env שמפעיל את תיבת הדו-שיח, למדיניות רחבה, כל מפתח תואם רואה לכן את תיבת הדו-שיח בסשנים האינטראקטיביים שלו. סשן אינטראקטיבי שרץ מציג אותה בסקר השעתי הבא, ואחרת היא מופיעה בהפעלה האינטראקטיבית הבאה של המפתח.
המפתח cli נקרא settings במהדורות מוקדמות יותר, והשער עדיין מקבל את האיות הזה ככינוי. לפריסות חדשות, השתמש ב-code.
#בדיקת מדיניות לפני פריסה
כדי לבדוק שינוי מדיניות, הפעל את השער מול מסד נתונים Postgres חד-פעמי. השער מתחבר ל-Postgres ומחיל את מיגרציות הסכמה שלו לפני שהוא בודק את התוכן של בלוקי cli, code ו-desktop. כאשר הוא לא יכול להגיע למסד הנתונים, ההפעלה נעצרת ב-could not connect to Postgres ואינה מדווחת דבר על התוכן שלהם.
#חלון הקשר בסשנים בטרמינל
סשנים בטרמינל שמחוברים דרך /login משתמשים בחלון הקשר של 1M עבור Opus 4.7 ומאוחר יותר, Sonnet 5 ומאוחר יותר, ומודלי Fable. מזהה המודל אינו זקוק לסיומת [1m], והסשנים נדחסים בערך ב-967K טוקנים. לפני Claude Code v2.1.287 במחשב של המפתח, Claude Code התייחס למודלי Opus ו-Fable כבעלי חלון של 200K אלא אם מזהה המודל הסתיים ב-[1m].
כדי שסשנים בטרמינל יידחסו בגבול 200K, הגדר את חלון הדחיסה האוטומטית ב-env של המדיניות:
managed:
policies:
- match: {}
cli:
env:
CLAUDE_CODE_AUTO_COMPACT_WINDOW: "200000"Claude Code מחיל את המשתנה הזה בלי להציג למפתח את תיבת הדו-שיח לאישור. המשתנה חל על כל מודל, כולל מזהי מודל שמסתיימים ב-[1m].
כדי לכבות הקשר של 1M, הגדר CLAUDE_CODE_DISABLE_1M_CONTEXT: "1" באותו בלוק env. Claude Code מתייחס אז לכל מודל כבעל חלון של 200K. בסשנים אינטראקטיביים, כל מפתח מאשר את המשתנה הזה בתיבת הדו-שיח לאישור לפני שהוא נכנס לתוקף.
#מטמון פרומפט של שעה
כדי לבקש את TTL של מטמון הפרומפט של שעה במקום ברירת המחדל של חמש דקות, הוסף את המפתחות האלה לבלוק code, cli או settings קיים של מדיניות והפעל מחדש את השער. המפתחות זקוקים ל-Claude Code v2.1.242 או מאוחר יותר בשרת השער ובלקוחות.
promptCacheTtl מכסה את השיחה הראשית. subagentPromptCacheTtl הוא אופציונלי ומכסה סוכני משנה, תהליכי עבודה ובקשות ברקע. הדוגמה הזו מוסיפה את שניהם למדיניות match: {} עם מפתח cli:
managed:
policies:
- match: {}
cli:
promptCacheTtl: 1h
subagentPromptCacheTtl: 1h[!WARNING]
הגדר את המפתחות רק אם ה-upstreams שלך מציעים את ה-TTL של שעה לכל מודל שהשער משרת. אם upstream דוחה את ה-TTL, הבקשה נכשלת, והשער וגם Claude Code אינם מנסים אותה שוב עם TTL של חמש דקות. עבור Amazon Bedrock, בדוק מודלים, אזורים ומגבלות נתמכים.
כדי לאשר את promptCacheTtl, התחבר לשער כמשתמש שהמדיניות תואמת לו ובדוק באיזה TTL כתיבות המטמון שלך השתמשו. העבר --model כדי לחזור על הבדיקה לכל מודל שהשער משרת.
כתיבות מטמון של שעה עולות יותר מכתיבות של חמש דקות. כדי שמגבלות הוצאה יחשבו את התעריף הגבוה יותר, אתה זקוק ל-v2.1.286 או מאוחר יותר בשרת השער.
#שרתי MCP במדיניות
כדי לספק שרתי MCP ללקוחות Claude Code שמדיניות תואמת, הגדר managedMcpServers בבלוק cli של המדיניות הזו. אתה זקוק ל-Claude Code v2.1.259 או מאוחר יותר בשרת השער ובלקוחות.
השער בודק כל רשומה בעת האתחול עם אותם כללים ש-Claude Code מחיל בלקוח, ואם רשומה נכשלת בבדיקה, השער מסרב להתחיל ומציין את הרשומה.
אם אתה כותב הפניה ${VAR} ב-gateway.yaml, השער פותר אותה מהסביבה שלו בעת האתחול דרך הרחבת סודות לפני שהוא מריץ את בדיקות הרשומה, כך שכל לקוח תואם מקבל את הערך המילולי ויכול לקרוא אותו. הנחיית הכותרות לשרתים שמסופקים חלה על הערך המורחב.
השער דוחה את האיות mcpServers של .mcp.json בבלוק cli, ושגיאת האתחול שלו מציינת את managedMcpServers כמפתח לשימוש. לפני v2.1.259, השער דחה כל הגדרת שרת MCP בבלוק cli.
#שכבת Claude Desktop
אם הארגון שלכם גם פורס את Claude Desktop, אותו שער משרת את שני הלקוחות. כוונו את bootstrapUrl, בההגדרות המנוהלות של Claude Desktop, אל <listen.public_url>/user/bootstrap. Claude Desktop גוזר את מנפיק ה-OAuth מהכתובת הזו, מריץ את אותה התחברות ב-device-code מול השער הזה, ושולף את ההגדרות שלו מהתשובה.
[!NOTE]
דורש Claude Code בגרסה v2.1.203 ואילך בשרת השער, והצטרפות מפורשת:
/user/bootstrapמחזיר 404 אלא אם המדיניות שתואמת למשתמש נושאת מפתחdesktop.desktop: {}ריק מצטרף מדיניות, ומפתחdesktopבשכבת הבסיסmatch: {}מצטרף כל מדיניות שיורשת אותה. יומן הביקורת רושם כל בקשה כ-desktop_bootstrap.serveאוdesktop_bootstrap.denied.
אם אינכם פורסים את Claude Desktop, השאירו את desktop מחוץ למדיניות שלכם לגמרי. השער אז מחזיר 404 מ-/user/bootstrap לכל משתמש.
#הגדרות שהשער גוזר עבור Claude Desktop
השער גוזר חלק גדול מתשובת ה-bootstrap מבלוק cli או code של המדיניות התואמת ומהגדרות השער ברמה העליונה:
רשימת המודלים, מ-
availableModels. הרשימה משמיטה מודלים שהמדיניות חוסמת באמצעותdeniedModelsאוavailableModelsMatch: exact. המסנן הזה דורש Claude Code בגרסה v2.1.299 ואילך בשרת השער. הקשר מורחב ב-Claude Desktop מכסה את אפשרות ההקשר של 1M לכל מודלכלים מושבתים, מרשומות
permissions.denyעם שם כלי חשוף. אם תגדירוdisabledBuiltinToolsבבלוקdesktopשל המדיניות, השער מגיש את האיחוד של הערך שלכם והרשימה הנגזרת, כך שאפשר להשבית כלים נוספים בדרך הזו אבל אי אפשר להפעיל מחדש כלי שהשבתתם דרךpermissions.denyרשימת ההיתר ליציאה, מ-
sandbox.network.allowedDomains. אם תגדירוcoworkEgressAllowedHostsבבלוקdesktopשל המדיניות, השער משתמש בערך הזה במקום הרשימה הנגזרת. אם רשימת ההיתר שהשער מגיש כוללת*והשער גם לא מגיש אתallowedWorkspaceFoldersשל Claude Desktop, Claude Desktop לא מפעיל את ארגז החול של Bash בלשונית Codeנקודת קצה OTLP שמצביעה על השער עצמו, ותכונות הזהות של המשתמש המחובר. השער מעביר את הייצואים שהוא מקבל בנקודת הקצה הזו ליעדי
forward_toשלכם. הוא כולל את נקודת הקצה ואת התכונות כשמגדירים גם אתtelemetry.forward_toוגם אתlisten.public_url.Claude Desktop מייצא כל אות בקידוד אחד:
http/protobuf, אוhttp/jsonכשמגדירים אתOTEL_EXPORTER_OTLP_PROTOCOLאו אחת מהווריאנטים לפי אות שלו ל-http/jsonב-envשל המדיניות. לפני Claude Code v2.1.261 בשרת השער, התשובה הגדירהhttp/jsonבכל מקרה, ולכן אספן שמקבל רק protobuf דחה את הייצואים של Claude Desktop
כדי להגדיר את disabledBuiltinTools, את coworkEgressAllowedHosts, או את ההגדרה managedMcpServers של Claude Desktop עצמו בבלוק desktop של מדיניות, צריך Claude Code בגרסה v2.1.232 ואילך בשרת השער. managedMcpServers של Claude Desktop מקבל ערך מערך ולא אובייקט.
השער משמיט מתשובת ה-bootstrap מפתחות שאין להם מקבילה ב-Claude Desktop, כמו hooks וכללי הרשאה תחומים כמו Bash(npm *).
#החלת הגדרות code בלשונית Code
הגדרות Claude Code שמדיניות מחזיקה תחת המפתח code שלה חלות בלשונית Code של Claude Desktop כשכל אלה מתקיימים:
- למדיניות יש גם מפתח
desktop, ו-desktop: {}ריק נחשב - Claude Desktop בגרסה 2.9939.2 ואילך
- הגדרות Claude Code המנוהלות במכונה מציינות את השער הזה
- המכונה הזו מגיעה לשער דרך HTTPS ברשת פרטית
שני התנאים האחרונים חלים על המכונה שמריצה את Claude Code עבור ההפעלה. בהפעלה מקומית, זו המחשב של המשתמש עצמו. בהפעלת לשונית Code דרך SSH, זה המארח המרוחק.
פרסו את ההגדרות המנוהלות בצד הלקוח למכונות האלה לפני שמשנים את השם מ-cli ל-code. כששני התנאים הראשונים מתקיימים ואחד משני האחרונים נכשל, משתמש שהמדיניות תואמת לו מקבל אחת מהתוצאות האלה:
- דרך HTTPS, כש-Claude Desktop כולל את Claude Code v2.1.296 ואילך: לשונית Code לא מופעלת, והתשובה להנחיה של המשתמש אומרת למה
- דרך HTTPS, כש-Claude Desktop כולל גרסה מוקדמת יותר: לשונית Code מופעלת בלי הגדרות
codeשלכם, ושום דבר בהפעלה לא אומר זאת - דרך HTTP רגיל: לשונית Code מופעלת בלי הגדרות
codeשלכם, בכל גרסה ש-Claude Desktop כולל
כשפרוקסי מול השער עונה ל-/managed/settings ב-404 משלו, לשונית Code גם מופעלת בלי הגדרות code שלכם, כולל במכונה שעומדת בכל ארבעת התנאים.
במדיניות שיש בה מפתח desktop, בלוק code שמחזיק הגדרות מכבה את כלי WebSearch ב-Cowork, ב-Chat ובלשונית Code. לשרתי MCP, ראו איפה managedMcpServers חל.
#הגדרת הגדרות Claude Desktop ישירות
הוסיפו את בלוק desktop האופציונלי לצד cli כדי להגדיר הגדרות Claude Desktop ישירות. כתבו הגדרות ממדריך ההגדרות המנוהלות של Claude Desktop כשמות מפתח שטוחים. השמיטו מפתחות ש-Claude Desktop קורא רק מ-MDM או מקבצים מקומיים, כמו bootstrapUrl. השער דוחה אותם בעלייה.
הדוגמה הזו מגדירה שלושה מפתחות Claude Desktop לקבוצה eng-contractors לצד הגדרות cli שלה:
managed:
policies:
- match: { groups: [eng-contractors] }
cli:
availableModels: [claude-sonnet-4-6]
enforceAvailableModels: true
desktop:
isLocalDevMcpEnabled: false
disableAutoUpdates: true
banner: { text: "Contractor build: internal use only" }כל מפתח הוא אופציונלי. Claude Desktop מחיל את ברירת המחדל שלו לכל מפתח שמשמיטים.
#מה השער דוחה בעלייה
השער מאמת כל בלוק desktop בעלייה מול סכמת ההגדרות ש-Claude Desktop עצמו משתמש בה, כך שטעות עולה בהפעלת השער כשגיאה שמציינת את המפתח ולא מגיעה לכל שולחן עבודה מחובר. השער נכשל בעלייה כשבלוק מכיל:
- מפתח לא מוכר
- מפתח מוכר שהערך שלו Claude Desktop היה דוחה או משמיט בשקט, כמו ערך ריק או תת-מפתח עם שגיאת כתיב בתוך רשומה מקוננת. לפני v2.1.260, השער השמיט בשקט שדה עם שגיאת כתיב בתוך אובייקט מקונן של רשומת
managedMcpServersאוorgPluginSettingsבמקום להיכשל בעלייה. - מפתח שהשער מחשב בעצמו: חיבור ההסקה, רשימת המודלים, וממסר ה-OTLP. הגדירו אותם דרך
upstreams,models, ו-forward_toשל מקטעtelemetry. - כינוי ישן של מפתח נוכחי. בשגיאת העלייה, השער מציין את המפתח הקנוני לכתיבה.
אם משתמשים בערך או בצורת רשומה שהוצאו משימוש, כמו רשומת managedMcpServers בלי transport, השער עולה ורושם אזהרה שמציינת את התחליף.
לפני v2.1.232, השער קיבל רשימה קבועה של 11 מפתחות feature-gate, כמו chatTabEnabled ו-disableAutoUpdates, ודחה כל מפתח אחר בעלייה. לפני v2.1.227, השער גם דחה את chatTabEnabled ואת chatAdvancedFileAnalysisEnabled בעלייה.
#מפתחות שדורשים גרסת שער או Claude Desktop מאוחרת יותר
השער מאמת בלוק desktop מול הסכמה שמצורפת לגרסה המותקנת שלו, כמו שהוא עושה לבלוק cli. כדי לספק הגדרה שהוצגה במהדורת Claude Desktop חדשה יותר, שדרגו קודם את השער. לדוגמה, userPluginMarketplacesEnabled ו-userPluginUploadsEnabled דורשים Claude Code בגרסה v2.1.260 ואילך בשרת השער ו-Claude Desktop 1.37937.0 ואילך במכונות של החברים.
blockReadsOutsideWorkingDirectories, disableBypassPermissionsMode, configRecheckIntervalMinutes ו-sshClientPath דורשים Claude Code בגרסה v2.1.281 ואילך בשרת השער. כך גם הערך required של microsoftAuthBroker והשדה continuousAccessEvaluation של רשומת managedMcpServers של Microsoft 365. מהדורות Claude Desktop שקדמו לערך required קוראות אותו כ-disabled, לכן הגדירו required רק אחרי ש-Claude Desktop של כל חבר תומך בו. מדריך ההגדרות המנוהלות של Claude Desktop מציין את המהדורה שקוראת כל מפתח לראשונה.
[!NOTE]
sshTransportדורש Claude Code בגרסה v2.1.293 ואילך בשרת השער.
אם מגדירים orgPluginSettings בבלוק desktop של מדיניות, השער מגיש אותו בצורת המערך ש-Claude Desktop 1.15200.0 ואילך קורא. שולחנות עבודה ישנים יותר מתעלמים מהמערך ולא אוכפים מדיניות כלי תוסף, לכן עדכנו חברים ל-1.15200.0 ואילך לפני שמסתמכים על זה.
#איך מדיניות תפקיד יורשת את בלוק desktop הבסיסי
השער ממלא מפתחות שבלוק desktop של מדיניות לא מגדיר מבלוק desktop של ה-catch-all match: {}, באותה דרך שהוא ממלא בלוק cli של מדיניות מהבסיס. אם מגדירים disabledBuiltinTools או builtinToolPolicy גם בבסיס וגם במדיניות תפקיד, השער שומר את ההגבלה של הבסיס:
disabledBuiltinTools: השער משתמש באיחוד של רשימת הבסיס ורשימת המדיניותbuiltinToolPolicy: אם מגדירים כלי לערך שאינוallowבבסיס, השער שומר את הערך הזה גם אם מגדיריםallowלאותו כלי במדיניות תפקיד
לכל מפתח אחר, אם מגדירים אותו במדיניות התפקיד, השער משתמש בערך של מדיניות התפקיד. השער מחליף מערך או אובייקט מקונן כמו banner בשלמותו, כך שאם מגדירים banner.text במדיניות תפקיד, השער משמיט את banner.backgroundColor של הבסיס.
#מתי שינוי מדיניות מגיע ל-Claude Desktop
אחרי שפורסים מחדש את השער עם מדיניות ששונתה, Claude Desktop מחיל את רוב ההגדרות רק כשהוא מופעל בפעם הבאה:
- סגור: Claude Desktop שולף את תשובת ה-bootstrap כשהוא מופעל, כך שהשינוי חל מההפעלה הבאה
- פתוח: Claude Desktop בודק תשובה ששונתה כל 10 דקות כברירת מחדל ומחיל כמה הגדרות בלי הפעלה מחדש. לשאר, כמו
skillCreationEnabled, המשתמש רואה כרטיס Relaunch Claude Desktop בסרגל הצד ושומר את ההגדרות הקודמות עד שהוא מפעיל מחדש את האפליקציה. אחרי 24 שעות כברירת מחדל, Claude Desktop מציג תיבת דו-שיח להפעלה מחדש ומפעיל את עצמו מחדש אחרי 2 דקות של חוסר פעילות
כדי לקצר את 24 השעות, הגדירו relaunchEnforcementHours בבלוק desktop של המדיניות. צריך Claude Code בגרסה v2.1.260 ואילך בשרת השער ו-Claude Desktop 1.40609.0 ואילך במכונות של החברים. עם 0, תיבת הדו-שיח מופיעה ברגע ש-Claude Desktop מוצא את השינוי.
#הקשר מורחב ב-Claude Desktop
אם מגישים את Claude Desktop מהשער, בורר המודלים שלו מציע אפשרות הקשר של 1M לכל מודל ברשימה שיכול לרוץ עם חלון הקשר של 1M. אלה כוללים את Claude Opus 4.6 ואילך, Claude Sonnet 4.6 ואילך, ואת מודלי Fable. האפשרות היא וריאנט [1m] של המודל, שהקשר מורחב מתאר. צריך Claude Code בגרסה v2.1.284 ואילך בשרת השער.
רשומת models לא מקבלת אפשרות 1M כש:
- upstream שיכול להגיש את הרשומה ממפה אותה למודל בלי תמיכה ב-1M, כולל upstream שהשער מגיע אליו רק ב-failover
- לא ה-
idשלה ולא אף אחד מערכיupstream_modelשלה מציין מודל Claude, כמו כינוי מותאם שמנותב ל-ARN של פרופיל הסקה של אפליקציה
כדי לשנות מה הבורר מציע, השתמשו באחת מאלה:
- התחלת משתמשים באפשרות 1M: הגדירו
modelPrefer1mContext: trueבבלוקdesktopשל המדיניות. משתמשים שעדיין לא בחרו מודל מתחילים באפשרות 1M כשלמודל הראשון ברשימה יש אחת. משתמשים שכבר בחרו מודל שומרים על הבחירה שלהם. - הצעת האפשרות ידנית: עשו זאת אם שרת השער שלכם מריץ גרסה ישנה מ-v2.1.284, או שרשומה לא מציינת מודל Claude. רשמו את המודל פעמיים ב-
models, פעם עם ה-ID הפשוט ופעם עם[1m]מצורף, שתיהן עם אותה מפתupstream_model. Claude Desktop מציג את הזוג כמודל אחד עם אפשרות 1M. השער מגיש רשומת[1m]בלי לבדוק אותה, לכן הוסיפו אחת רק למודל שה-upstreams שלכם מגישים ב-1M.
הדוגמה הזו מציעה את האפשרות ידנית לכינוי מותאם שמנותב לפרופיל הסקה של אפליקציה, ומתחילה משתמשים חדשים עליה:
models:
- id: corp-sonnet
upstream_model:
bedrock: arn:aws:bedrock:us-east-2:123456789012:application-inference-profile/sonnet-5-prod
- id: corp-sonnet[1m]
upstream_model:
bedrock: arn:aws:bedrock:us-east-2:123456789012:application-inference-profile/sonnet-5-prod
managed:
policies:
- match: {}
desktop:
modelPrefer1mContext: true#הסרת אפשרות 1M
כדי להסיר את האפשרות מהבורר, הגדירו CLAUDE_CODE_DISABLE_1M_CONTEXT: "1" בבלוק env תחת מפתח cli של המדיניות. אם גם רשמתם רשומה שה-id שלה מסתיים ב-[1m], השער עדיין מגיש אותה, לכן מחקו גם את הרשומה הזו.
המשתנה גם מגיע להפעלות הטרמינל של מפתחים שהמדיניות תואמת להם. למה הוא משנה שם, ראו הקשר מורחב.
#קדימות מול מקורות מנוהלים אחרים
אם למכשיר יש גם מדיניות שנמסרה ב-MDM או managed-settings.json מקומי, הגדרות שהשער מסר מדורגות ראשונות. קדימות בתוך השכבה המנוהלת בדף ההגדרות המנוהלות אומר מתי המקורות המקומיים חלים, ויש בו את המפתחות ש-Claude Code קורא מכל מקור ניהול בלי קשר למקור שבחר, כמו מפתחות נעילת ארגז החול, forceRemoteSettingsRefresh, ומיזוג env לפי משתנה. policyHelper שמוגדר בפרופיל MDM או בקובץ ההגדרות המנוהלות רץ רק כשהשער לא מספק הגדרות. הרשומה אומרת מה הפלט שלו מחליף.
מארחים מטמיעים כמו Claude Desktop יכולים לספק מדיניות דרך אפשרות managedSettings של ה-SDK. הגדרות הורה ממארחים מטמיעים אומר מתי Claude Code מחיל אותן, והגבלת הגדרות הורה מפרטת אילו הגדרות בכיוון היתר עדיין חלות בלי נעילות allowManaged*Only.
מדיניות השער חלה על כל הפעלה של Claude Code במכונה, כולל הרצות claude -p לא אינטראקטיביות והפעלות שה-Agent SDK יוצר. אם השער לא נגיש בהפעלה, הפעלות מחוברות יוצאות עם שגיאה במקום לרוץ בלי המדיניות שלהן.
#telemetry
ה-CLI שולח מדדים, לוגים, וכשהאפשרות מופעלת גם traces, אל ה-gateway, שמעביר אותם כלשונם לכל יעד מוגדר. הייצואים משתמשים ב-OpenTelemetry Protocol (OTLP) מעל HTTP. כדי לדלג על הממסר ולגרום לסשנים לייצא ישירות אל ה-collector שלך, ציין את שם ה-collector במדיניות. ראה Monitoring usage למדדים ולאירועים שה-CLI פולט.
בסשנים שנכנסו דרך /login, ה-CLI חותם כל ייצוא בזהות המשתמש המאומת, שנקראת מ-JWT שה-gateway הנפיק: המאפיינים user.id, user.email ו-user.groups. לכן ייחוס עלות ושימוש לכל מפתח עובד בלי הגדרה מצד המפתח. אירועים ש-Claude Code רושם לפני שהמפתח נכנס לא נושאים את הזהות הזו. כדי לראות איזה מאפיין עוקב אחרי שינוי בקבוצות של מפתח, ראה שינויי קבוצות במהלך סשן פתוח.
סשנים של Claude Desktop ושל Cowork שנכנסו דרך ה-gateway חותמים את ה-telemetry שלהם ב-user.email וב-user.groups לצד enduser.id, כך שאפשר לכסות שימוש בטרמינל, ב-Desktop וב-Cowork בשאילתה אחת על user.email או על user.groups. user.groups הוא רשימת קבוצות ה-IdP מופרדת בפסיקים.
telemetry של Desktop ושל Cowork נושא גם את enduser.sub, ה-claim sub שספק הזהות שלך מנפיק למשתמש, והוא נשאר זהה כשכתובת האימייל של משתמש משתנה. סשני טרמינל חותמים את אותו ערך תחת user.id, כך ששאילתה שמתאימה את enduser.sub מול user.id של טרמינל מכסה יחד את השימוש של משתמש אחד בטרמינל, ב-Desktop וב-Cowork. בייצואים של Desktop ושל Cowork, user.id הוא מזהה אנונימי, לא ה-subject.
כמו כל נתוני OpenTelemetry מ-Claude Code, המאפיינים האלה הולכים רק ליעדים שהארגון שלך מגדיר, ולעולם לא ל-Anthropic.
אם רשימת הקבוצות של משתמש ארוכה מ-255 תווים אחרי percent-encoding, או ששם קבוצה מכיל פסיק או סימן שוויון, ה-gateway משמיט את user.groups מ-telemetry של Desktop ושל Cowork של אותו משתמש במקום לקצץ אותו. סשני הטרמינל של אותו משתמש עדיין נושאים את הרשימה המלאה.
ה-gateway משמיט את enduser.sub כשה-subject ארוך מ-255 תווים אחרי percent-encoding, או מכיל רווח, תו מחוץ ל-ASCII להדפסה, או אחד מבין , ; = \ " %. ה-telemetry של Desktop ושל Cowork של אותו משתמש שומר על שאר המאפיינים שלו.
נדרש Claude Code v2.1.265 או חדש יותר בשרת ה-gateway כדי לקבל user.email ו-user.groups ב-telemetry של Desktop ושל Cowork, ו-Claude Desktop 1.24012 או חדש יותר בכל מחשב של מפתח כדי לקבל user.groups.
נדרש Claude Code v2.1.274 או חדש יותר בשרת ה-gateway כדי לקבל enduser.sub.
telemetry:
forward_to:
- url: https://otel-collector.internal.example.com
headers:
Authorization: ${OTLP_TOKEN}
# Per-signal opt-in. Default: metrics only.
metrics: true
logs: false
traces: false
- url: https://api.datadoghq.com/api/v2/otlp
headers:
DD-API-KEY: ${DD_API_KEY}[!WARNING]
כל יעד בוחר בנפרד ב-
metrics, ב-logsוב-traces, וברירת המחדל היא מדדים בלבד. האותות נבדלים ברגישות:
- Metrics: מונים מצטברים כגון ספירות טוקנים, ספירות בקשות וזמן תגובה
- Logs and traces: יכולים לשאת פקודות Bash מלאות, קלטי כלים ונתיבי קבצים, ולכסות כל דבר ש-Claude Code עושה במחשב של מפתח
הפעל לוגים ו-traces רק ביעדים עם בקרות הגישה ומדיניות השמירה שהנתונים האלה מצדיקים.
כל כתובת URL של forward_to חייבת להשתמש ב-https://, עם חריג אחד ל-collector על ממשק ה-loopback של ה-gateway עצמו:
http://localhost:<port>עובר אימות הגדרות, אבל מנגנון ההגנה מפני SSRF חוסם כל ייצוא עםECONNREFUSED_SSRFאלא אם מגדיריםCLAUDE_GATEWAY_ALLOW_LOOPBACK=1בסביבה של ה-gatewayhttp://127.0.0.1:<port>אוhttp://[::1]:<port>נכשל בעלייה אלא אם המשתנה הזה מוגדר
ל-collector בתוך האשכול, חשוף אותו מעל HTTPS בכתובת הפנימית שלו, או הרץ אותו כ-sidecar כשהמשתנה מוגדר.
כש-HTTPS_PROXY מוגדר, ה-gateway שולח ייצואים דרך אותו proxy.
כדי להגיע ל-collector פנימי ישירות, הוסף אותו ל-NO_PROXY לפי hostname או לפי דומיין עם נקודה מובילה כגון .internal.example.com, מה שדורש Claude Code v2.1.277 או חדש יותר בשרת ה-gateway. ודא שה-gateway יכול להגיע ל-collector בלי ה-proxy. רשומה בלי נקודה מובילה מתאימה רק לאותו שם מדויק, לא לשמות שמתחתיו. טווחי CIDR לא מתאימים.
כש-יציאה דרך proxy בלבד מופעלת, אפשר את ה-collector ב-proxy במקום זאת, כי כל רשומת NO_PROXY משאירה את היציאה דרך proxy בלבד כבויה.
telemetry כבוי ב-CLI כברירת מחדל. כשמגדירים גם את telemetry.forward_to וגם את listen.public_url, ה-gateway מפעיל אותו ללקוחות מחוברים על ידי דחיפת שישה משתני סביבה דרך /managed/settings:
CLAUDE_CODE_ENABLE_TELEMETRY=1OTEL_METRICS_EXPORTER,OTEL_LOGS_EXPORTERו-OTEL_TRACES_EXPORTER, כל אחד מוגדר ל-otlpאם לפחות יעדforward_toאחד מפעיל את האות הזה, ול-noneאחרתOTEL_EXPORTER_OTLP_ENDPOINT=<public_url>OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
כש-מוסיפים תוויות משלך, ה-gateway דוחף גם את OTEL_RESOURCE_ATTRIBUTES.
לפני Claude Code v2.1.265 בשרת ה-gateway, ה-gateway דחף את שלושת בוררי ה-exporter כ-otlp, כולל לאותות שאף יעד לא בחר בהם.
נקודת הקצה שנדחפת נבנית מכתובת ה-URL הציבורית, כך שמדדים ולוגים לא דורשים הגדרת OTEL ממפתחים או ממדיניות.
מפתחים שנכנסו דרך /login לא יכולים להפנות ייצואים מחדש עם הגדרת OTEL משלהם:
- משתנים שהוגדרו מקומית: Claude Code מחיל את המשתנים שנדחפו בשכבת managed, כך שכל אחד מהם דורס את הערך שמפתח מגדיר לו מקומית.
- נקודות קצה שהוגדרו מקומית: כשייצוא OTLP/HTTP מופעל, ה-CLI מתעלם מכל נקודת קצה שהוגדרה מקומית, בין שה-gateway דחף את משתני ה-telemetry ובין שלא. הייצואים שלו הולכים אל ה-gateway אלא אם מדיניות מציינת את ה-collector שלך כנקודת הקצה.
בלי יעד forward_to לאות, ה-gateway מקבל אותו ומשליך אותו. אם מפתחים כבר מייצאים telemetry של Claude Code לאחד מה-collectors שלך, הוסף אותו כיעד forward_to, עם לוגים או traces מופעלים אם הם מייצאים אותם, כדי שהוא ימשיך לקבל את הנתונים שלהם אחרי שהם נכנסים. כדי לדלג על הממסר במקום זאת, ציין את שם ה-collector במדיניות.
Traces דורשים גם CLAUDE_CODE_ENHANCED_TELEMETRY_BETA=1 בכל לקוח. הגדר אותו בבלוק env של מדיניות managed, כי ה-gateway לא דוחף אותו. מפתחים מאשרים אותו באותה תיבת אישור אבטחה שנקודת הקצה שנדחפה כבר מפעילה.
הגדר אותו ל-1 רק במדיניות של הקבוצות שרוצים לעקוב אחריהן ב-traces. מדיניות שלא מגדירה אותו יורשת את הערך ממדיניות ה-catch-all match: {} שלך אם המדיניות הזו מגדירה אחד, לפי כללי המיזוג. כדי למנוע מלקוחות של קבוצה לשלוח traces גם כשמפתח מגדיר את המשתנה מקומית, הגדר אותו ל-0 במדיניות של אותה קבוצה.
גם קידוד OTLP ב-protobuf וגם קידוד ב-JSON מועברים, וכל backend תואם OpenTelemetry עובד כיעד.
#שליחת מדדים מצטברים
אם ה-collector שלך מקבל רק מדדים מצטברים, הגדר את OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE ל-cumulative. Claude Code שולח מדדי delta כברירת מחדל, וה-gateway מעביר אותם בלי להמיר אותם. הגדר את המשתנה במקום שבו כל סוג סשן קורא אותו:
- סשני טרמינל: בבלוק
envתחת מפתחcliאוcodeשל מדיניות - סשני Cowork שרצים במחשב של המשתמש: בבלוק
envשל הגדרות managed בצד הלקוח באותו מחשב - סשני לשונית Code תחת מדיניות
code: בבלוקenvשל המדיניות, אחרי שמתקיימים התנאים להחלה של הגדרותcode - סשני לשונית Code תחת מדיניות
cli: בבלוקenvשל הגדרות managed בצד הלקוח במחשב שמריץ את הסשן. מעל SSH, זה המארח המרוחק.
אם מוסיפים את המשתנה להגדרות managed של מחשב, הגדר גם parentSettingsBehavior: "merge" במקור בעדיפות הגבוהה ביותר באותו מחשב. בלעדיו, סשני Cowork וסשני לשונית Code תחת מדיניות cli רצים בלי רשימת ההיתר ליציאה ובלי מדיניות אחרת ש-Claude Desktop מעביר להם כהגדרות הורה.
#הוספת תוויות משלך
כדי לשים תוויות קבועות כגון service.namespace או deployment.environment.name על ה-telemetry של סשנים שנכנסו דרך ה-gateway, הגדר את telemetry.resource_attributes. כל תווית היא מאפיין resource של OpenTelemetry, וכל יעד מקבל את אותן תוויות.
סשנים מקבלים את התוויות רק כשמגדירים גם את telemetry.forward_to וגם את listen.public_url. הדוגמה הזו מוסיפה שתי תוויות:
telemetry:
forward_to:
- url: https://otel-collector.internal.example.com
resource_attributes:
service.namespace: claude
deployment.environment.name: prodה-gateway מסרב לעלות כשתווית שוברת אחד מהכללים האלה, ושגיאת העלייה מציינת את שם התווית:
- שמות משתמשים רק באותיות, בספרות, ב-
., ב-_וב-- - שמות אינם שמורים. בהשוואה בכל מצב אותיות, השמות השמורים הם כל מה שמתחיל ב-
user., ב-enduser.או ב-identity., ועודservice.name,service.version,claude.deployment_mode,host.arch,os.type,os.versionו-wsl.version - ערכים הם ASCII להדפסה לא ריק, בלי רווח ובלי אף אחד מבין
, ; = \ " % - ערכים הם לכל היותר 255 תווים כפי שה-gateway סופר אותם אחרי percent-encoding, כך ש-
/,:ו-@נספרים כל אחד כשלושה - ערכים הם טקסט, אז צטט מספר,
trueאוfalse
נדרש Claude Code v2.1.281 או חדש יותר בשרת ה-gateway כדי להגדיר את telemetry.resource_attributes. gateway מוקדם יותר מסרב לעלות כשהוא מוצא את המפתח. שדרג כל replica לפני שמוסיפים את המפתח, והסר את המפתח לפני שמחזירים גרסה מוקדמת יותר.
סשני טרמינל שנכנסו דרך /login מקבלים את התוויות כ-OTEL_RESOURCE_ATTRIBUTES, שנדחף עם שאר משתני ה-telemetry. אם מגדירים את OTEL_RESOURCE_ATTRIBUTES בבלוק env של מדיניות, סשני טרמינל שהמדיניות הזו מתאימה להם מקבלים את הערך הזה במקום התוויות. Claude Desktop מקבל את התוויות מה-gateway לצד user.email ושאר מאפייני הזהות.
Claude Code גם מעתיק כל תווית אל כל נקודת נתונים של מדד, כך שאפשר לסנן מדדים לפיה ב-backend שלא מאנדקס מאפייני resource. כדי לכבות את ההעתקה הזו, ראה Metrics cardinality control.
#שינויי קבוצות במהלך סשן פתוח
סשני טרמינל שמים את user.groups על ה-resource של OTLP ושוב על כל נקודת נתונים של מדד ועל כל אירוע. אם הקבוצות של מפתח משתנות בזמן שסשן פתוח, נקודות נתונים ואירועים לשימוש שאחרי ה-רענון השקט הבא נושאים את הקבוצות החדשות. ה-resource שומר את הקבוצות הישנות עד שהמפתח מפעיל מחדש את Claude Code, אז קבץ לפי המאפיין על נקודת הנתונים או על האירוע.
אם מפעילים את resource_to_telemetry_conversion ב-exporter של Prometheus remote write ב-OpenTelemetry Collector, ה-exporter מחליף את user.groups של כל נקודת נתונים בזה של ה-resource, כך שכל נקודת נתונים מציגה את הקבוצות הישנות. כדי לשמור את הערך של נקודת הנתונים, מחק את user.groups מה-resource לפני אותו exporter.
מעבד resource זה של OpenTelemetry Collector מוחק את המאפיין ב-pipelines שמציינים אותו:
processors:
resource/drop-user-groups:
attributes:
- key: user.groups
action: deleteאחרי שמוסיפים את resource/drop-user-groups ל-processors של pipeline המדדים, כל series נושא את תווית user_groups מנקודת הנתונים שלו.
#ייצוא ישיר אל ה-collector שלך
כדי שסשנים שנכנסו דרך /login ישלחו telemetry ישירות אל ה-collector שלך במקום דרך הממסר, הגדר את OTEL_EXPORTER_OTLP_ENDPOINT לכתובת הבסיס https:// של ה-collector בבלוק env של מדיניות managed. Claude Code מוסיף /v1/metrics, /v1/logs או /v1/traces לכתובת שאתה מגדיר, כגון https://otel-collector.example.com:4318, ומייצא כל אות לשם מעל OTLP/HTTP. נדרש Claude Code v2.1.265 או חדש יותר בכל מחשב של מפתח. לקוחות מוקדמים יותר מייצאים דרך הממסר.
כדי לאמת מול ה-collector, הגדר את OTEL_EXPORTER_OTLP_HEADERS באותו בלוק env. סשנים לעולם לא שולחים את טוקן הסשן של המפתח ב-gateway אל collector ששמו צוין כך.
כשמוסיפים או משנים את נקודת הקצה הזו במדיניות, Claude Code מבקש מכל מפתח לאשר אותה בתיבת אישור האבטחה לפני שהוא מחיל אותה בסשן אינטראקטיבי.
Claude Code בודק את נקודת הקצה לפני שהוא מייצא אות ישירות, ומשאיר את האות על הממסר כשבדיקה נכשלת. הבדיקות כוללות:
- נקודת הקצה מגיעה מה-gateway עצמו. אם מגדירים את אותו משתנה בפרופיל MDM או ב-
managed-settings.jsonמקומי, הייצואים נשארים על הממסר. - כתובת ה-URL משתמשת ב-
https://, או ב-http://אל כתובת loopback - כתובת ה-URL נפתרת לנתיב שמסתיים ב-
/v1/<signal>, בלי query או fragment. Claude Code בונה את הנתיב הזה בעצמו מהמשתנה הגנרי. הוא משתמש במשתנה לפי אות כגוןOTEL_EXPORTER_OTLP_METRICS_ENDPOINTכפי שנכתב, אז כלול שם את הנתיב המלא. - כתובת ה-URL אינה המארח של ה-gateway עצמו. נקודת קצה שמופנית אל ה-gateway שומרת על נתיב הממסר ועל טוקן הסשן שלו.
- לא אתה ולא המפתח הגדרתם
otelHeadersHelperבאף מקור הגדרות. כש-helper מוגדר, כל אות נשאר על הממסר.
נקודת הקצה שאתה מציין משנה רק לאן הייצואים הולכים. עדיין בוחרים אילו אותות מיוצאים בכלל עם בוררי OTEL_*_EXPORTER.
נקודת הקצה לבדה לא מפעילה ייצוא, אז הגדר גם את המשתנים שכן מפעילים, אלא אם ה-gateway כבר דוחף אותם:
- אם ה-gateway כבר דוחף את משתני ה-telemetry, הם מכסים הפעלה, בוררים ופרוטוקול, ונקודת הקצה המפורשת שלך דורסת את ערך
<public_url>שנדחף. הגדר בוררOTEL_*_EXPORTERל-otlpבעצמך רק לאות שאף יעדforward_toלא מפעיל. - אם הוא לא דוחף, הגדר גם את
CLAUDE_CODE_ENABLE_TELEMETRY=1, את בורריOTEL_*_EXPORTERואתOTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf.
כשהמפתח יוצא, או נכנס ל-gateway אחר, הייצואים אל ה-collector נעצרים ו-Claude Code משליך כל batch שנותר במקום לשלוח אותו.
#כשיעד נכשל
ה-gateway לא מאגר, לא מנסה שוב ולא שומר telemetry, אז הוא משליך ייצוא שלא מגיע ליעד במקום למסור אותו באיחור. כל יעד מצליח או נכשל בפני עצמו, והלקוח המייצא מקבל תגובת הצלחה בכל מקרה, כך שמסירה שנכשלה מופיעה רק בלוג של ה-gateway.
אחרי חמש מסירות כושלות רצופות ליעד, ה-gateway משהה העברה אליו במקטעים של 30 שניות, ורושם כל השהיה בלוג, עד שמסירה מצליחה. כל תגובת שגיאה, timeout או שגיאת חיבור נספרים כמסירה כושלת, חוץ מ-400, 413, 415, 422 ו-431, שמשמעותם שה-collector סירב למטען של אותו ייצוא כי הוא פגום או גדול מדי.
מטען שנדחה לא מקדם ולא מאפס את מונה הכשלונות: ה-gateway ממשיך להעביר אל היעד ורושם אזהרה שמציינת אותו ואת הסטטוס, בסירוב הראשון של היעד ובכל מאה אחריו.
#כוונון HTTP
ארבעה בלוקים אופציונליים ברמה העליונה, access_control, limits, timeouts ו-rate_limits, מכווננים את משטח ה-HTTP. ברירות המחדל מתאימות לרוב הפריסות.
| בלוק | מפתח | ברירת מחדל | תיאור |
|---|---|---|---|
access_control | allow_cidrs / deny_cidrs | ריק | היתר או דחייה של IP נכנס לפי כתובת הלקוח, אחרי פתרון trusted_proxies. deny_cidrs נבדק ראשון. לקוח שהוא תואם נדחה גם אם allow_cidrs תואם גם כן. אם allow_cidrs אינו ריק, השער דוחה כברירת מחדל. /healthz ו-/readyz פטורים מ-allow_cidrs. כשפרוקסי מהימן שולח רשומת X-Forwarded-For שאינה כתובת IP, הלקוח האמיתי אינו ידוע והשער רושם אזהרה פעם אחת שמציינת מה לבדוק. במקום שבו אחת מהרשימות חלה על הבקשה, הוא מסרב לה עם 403 וסיבת ביקורת xff_unparseable. במקום שבו אף אחת לא חלה, הוא מגיש את הבקשה ומשתמש בכתובת של הפרוקסי עצמו ככתובת ה-IP של הלקוח למגבלות קצב לפי IP ולביקורת. |
limits | max_request_bytes | 32 MiB | גוף בקשה נכנס מרבי. בקשות גדולות מדי מקבלות 413 לפני שהגוף נשמר בחוצץ. העלו עבור בקשות קובץ או תמונה גדולות. |
limits | max_request_header_bytes | לא מוגדר | מוריד את מגבלת השער של 256 KiB על סך הכותרות של בקשה. בקשה מעל המגבלה מחזירה 431, וערך מעל 256 KiB אינו משפיע. אם מפתחים מקבלים 431 אחרי כניסה, ראו כותרות בקשה גדולות מדי אחרי כניסה. |
limits | max_url_length | לא מוגדר | כשהוא מוגדר, כתובת URL ארוכה מדי מחזירה 414 |
timeouts | upstream_ttfb_ms | 120000 | המתנה מרבית לכותרות התגובה של ה-upstream (זמן עד הבייט הראשון). גוף התגובה אחר כך מוזרם בלי תקרת שעון קיר. אם המפתח אינו מוגדר, ברירת המחדל חלה על upstreams של provider: anthropic, ובכל ספק אחר השער ממתין עד שעה אחת עד שהתגובה מתחילה. כדי לקצר את ההמתנה הזו, ראו upstreams מרובים. |
rate_limits | device_authorization.max / .window_seconds | 30 / 600 | מגבלת קצב לפי IP על נקודת הקצה הלא מאומתת של device-authorization. העלו עבור ארגון גדול מאחורי IP יציאה משותף או NAT. פריסות גדולות מראה איך לגודל אותה. המגבלות האלה חלות רק על זרימת הכניסה של device-grant, לא על הסקה של /v1/messages. ראו עמידות בפני brute-force של קוד משתמש. |
rate_limits | device_verify.max / .window_seconds | 10 / 600 | מגבלת קצב לפי IP על הגשות user_code ב-/device. זה מה שעוצר מישהו מניחוש הקוד של מפתח אחר. פריסות גדולות מראה עד כמה להעלות אותה. |
אם משאירים את שתי רשימות access_control ריקות, וזו ברירת המחדל, השער מגיש כל כתובת לקוח, כך שרק הרשת שלכם מגבילה מי יכול להגיע אליו. זה חשוב כי שער יכול לדחוף הגדרות מנוהלות שמריצות פקודות על מכונות של מפתחים.
בזמן ש-allow_cidrs ריק, השער מזהיר בשני מקומות, בלי לשנות איך הוא עונה לכל בקשה:
- בעלייה: אזהרה ביומן התפעולי ממליצה לאפשר רק את הטווחים הפרטיים
10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,100.64.0.0/10,127.0.0.0/8,::1/128ו-fc00::/7, ועוד כל טווח פנימי אחר שממנו המפתחים שלכם מתחברים. אם קושרים את השער לכתובת loopback ולא מגדירים לאtrusted_proxiesולאpublic_url, כמו בפיתוח מקומי, האזהרה לא מופיעה. - בזמן ריצה: בפעם הראשונה שמגיעה בקשה מכתובת מחוץ לטווחים הפרטיים האלה, השער רושם אזהרה ופולט אירוע ביקורת
access.public_clientשנושא את ה-IP של הלקוח. שניהם נורים פעם אחת לכל תהליך. כתובות link-local,169.254.0.0/16ו-fe80::/10, לא נחשבות ציבוריות. השער עונה ל-/healthzול-/readyzלפני שהבדיקה הזו רצה, כך שבדיקות תקינות מטווחים ציבוריים לא מפעילות אותה.
שני האותות משתמשים בכתובת הלקוח כפי שהשער פותר אותה. אם מאזן עומסים, port-forward או מנהרה מעבירים תעבורה ואינם רשומים ב-listen.trusted_proxies, השער רואה את כתובת הממסר, שבדרך כלל פרטית, כך שלא האזהרה בזמן ריצה ולא רשימת היתר פרטית תופסות תעבורה שמועברת דרכו.
מאחורי חזית כזו, הגדירו קודם listen.trusted_proxies כדי שהשער יראה כתובות לקוח אמיתיות, ושמרו על כך שהשער וכל מה שלפניו לא יהיו נגישים מהאינטרנט הציבורי בכל מקרה.
#load_test_mode
בלוק load_test_mode מאפשר לבדוק עומס על שער בלי לקרוא לספק מודל. בזמן שהוא פועל, השער בונה וחותם כל בקשת ספק כרגיל, משליך אותה במקום לשלוח אותה, ומזרים תשובה מוכנה מראש בחזרה דרך נתיב התגובה הרגיל שלו. התשובה היא טקסט מילוי שמתחיל במשפט שאומר שהיא מוכנה מראש.
דורש Claude Code v2.1.282 או חדש יותר על שרת השער. שער מוקדם יותר מסרב לעלות כשהוא מוצא את המפתח. שדרגו כל רפליקה לפני שמוסיפים את הבלוק, והסירו את הבלוק לפני חזרה לאחור.
הדוגמה למטה מפעילה את המצב עם ברירות המחדל, תשובה של בערך 750 טוקנים של טקסט שמוזרמת על פני כ-10 שניות:
load_test_mode:
enabled: true
reply_tokens: 750 # roughly how many tokens of text each canned reply carries
reply_seconds: 9.5 # how long a streamed reply takes| שדה | נדרש | תיאור |
|---|---|---|
enabled | כן | true מפעיל את המצב. false שומר את המספרים שלכם בקובץ עם המצב כבוי. השער מסרב לעלות אם הבלוק קיים בלעדיו. |
reply_tokens | לא | ברירת מחדל 750. בערך כמה טוקנים של טקסט כל תשובה מוכנה מראש נושאת, מספר שלם מ-1 עד 100000. |
reply_seconds | לא | ברירת מחדל 9.5. כמה זמן תשובה מוזרמת נמשכת, מ-0 עד 600. 0 שולח את כל התשובה בבת אחת. תשובה לבקשה שאינה streaming תמיד חוזרת בבת אחת. |
בדיקת עומס במצב הזה מכסה את השער, את Postgres שלכם, וכל מה שלפני השער. היא לא מכסה את המגבלות, המהירות ונתיב הרשת של הספק, או את ההמתנה ב-מגבלה על בקשות upstream מקבילות של כל רפליקה. רפליקה עדיין רושמת את האזהרה client requests are open כשיש יותר בקשות פתוחות מהמגבלה הזו, הנקודה שבה בקשות ייצור מתחילות להמתין.
אף בקשת מודל לא נשלחת לספק, כך שה-CPU של רפליקה לכל בקשה הוא אומדן ונמדד נמוך יותר מאשר בייצור, שגם מצפין את התעבורה שלו אל הספק. אשרו מספר רפליקות עם פיילוט קטן מול הספק האמיתי. לפני v2.1.283, האומדן נמדד נמוך בהרבה.
בזמן שהמצב פועל, בקשה יכולה לשאת כותרת x-load-test-user שמחזיקה מספר שלם של עד שבע ספרות. השער סופר כל מספר כמפתח נפרד, עם הדוא"ל והקבוצות של המפתח שהטוקן שלו הגיע עם הבקשה.
תנו לפריסת בדיקת העומס מסד נתונים ריק משלה, כי השער מסרב לעלות עם המצב פועל מול מסד נתונים שבו מפתח כלשהו כבר הוציא משהו.
[!WARNING]
לעולם אל תפעילו את זה על שער שמפתחים משתמשים בו. כל בקשה מקבלת את התשובה המוכנה מראש ואין קריאה למודל. השער רושם אזהרת
load_test_mode is onבעלייה ומסמן כל אירוע ביקורתinferenceעםload_test: trueבזמן שהמצב פועל.
#דוגמה מלאה
הגדרת הייחוס המלאה הזו מפעילה כל מקטע ליבה. בלוקי כוונון ה-HTTP שומרים על ברירות המחדל שלהם. העתיקו אותה, מחקו מה שלא צריך, ומלאו את הערכים שלכם. ההגדרה ב-התחלה מהירה היא גרסה מינימלית של זה.
# Run with:
# claude gateway --config gateway.yaml
#
# Operational log verbosity is controlled by the CLAUDE_GATEWAY_LOG_LEVEL
# environment variable (debug | info | warn | error; default info). debug
# also logs the claim names in each id_token, for groups_claim diagnosis.
# It does not affect audit events, which are always emitted.
listen:
host: 0.0.0.0
port: 8080
public_url: https://claude-gateway.internal.example.com
# Omit the tls block when running behind a TLS-terminating ingress.
# tls:
# cert: /certs/gateway.crt
# key: /certs/gateway.key
# trusted_proxies:
# - 10.0.0.0/8
oidc:
issuer: https://example.okta.com
client_id: 0oa1example2
client_secret: ${OIDC_CLIENT_SECRET}
allowed_email_domains:
- example.com
# Required when the issuer is the Okta org server, whose id_tokens
# can omit email and groups; the gateway fills them from /userinfo.
userinfo_fallback: true
# allowed_groups: [claude-code-users]
# Okta emits groups only when the `groups` scope is requested and the
# app's groups claim filter allows them. The contractors policy below
# matches on groups, so the scope is requested here.
scopes: [openid, profile, email, offline_access, groups]
# extra_auth_params: { access_type: offline, prompt: consent } # Google
# groups_claim: groups # Entra app roles: use `roles`
# email_claim: email
session:
jwt_secret: ${GATEWAY_JWT_SECRET} # openssl rand -base64 32
# ttl_hours: 1
store:
postgres_url: ${GATEWAY_POSTGRES_URL}
# max_connections: 5
# connect_timeout_seconds: 5
# readiness_grace_seconds: 300 # keep passing the readiness check through a database failover
# Enables /v1/organizations/spend_limits (mirrors the Anthropic Admin API)
# and per-developer spend enforcement on /v1/messages. Omit to disable.
# Caps themselves are set via the admin API, not here.
# admin:
# write_keys:
# - { id: terraform, key: "${GATEWAY_ADMIN_WRITE_KEY_TF}" }
# read_keys:
# - { id: reporting, key: "${GATEWAY_ADMIN_READ_KEY}" }
# admin_groups: [platform-finops]
# blocked_message: request an increase at https://go.example.com/claude-limits
# # audit_retention_days: 365
# # spend_retention_months: 13
# # identity_retention_days: 90
# # group_limit_mode: min
# enforcement:
# fail_closed_on_error: false
# Load test this deployment without calling a model provider. Never on a
# gateway that developers use: every request gets a canned reply.
# load_test_mode:
# enabled: true
# # reply_tokens: 750
# # reply_seconds: 9.5
# Meter at contracted rates instead of USD list price. Requires admin: or a
# managed: policy. With managed:, the same rates also go to signed-in clients.
# Rates below are placeholders, not real contract prices.
# pricing:
# multiplier: 0.85
# overrides:
# - { upstream: anthropic, model: claude-sonnet-4-6, input: 3.30, output: 16.50, cache_read: 0.33, cache_write: 4.125 }
upstreams:
- provider: anthropic
auth:
api_key: ${ANTHROPIC_API_KEY}
# - provider: bedrock
# region: us-east-1
# auth: {}
# - provider: mantle
# region: us-east-1
# models: [claude-opus-4-8, claude-opus-4-7, claude-haiku-4-5]
# auth: {}
# - provider: anthropicAws
# region: us-east-1
# workspace_id: wrkspc_...
# auth:
# api_key: ${ANTHROPIC_AWS_API_KEY}
# - provider: vertex
# region: us-east5
# project_id: example-prod
# auth: {}
# - provider: foundry
# resource: example-foundry
# auth: { use_azure_ad: true }
auto_include_builtin_models: true
models:
- id: claude-opus-4-8
label: Claude Opus 4.8
upstream_model:
anthropic: claude-opus-4-8
# bedrock: us.anthropic.claude-opus-4-8
# mantle: anthropic.claude-opus-4-8
# anthropicAws: claude-opus-4-8
# vertex: claude-opus-4-8
# foundry: <your-opus-deployment-name>
- id: claude-sonnet-4-6
label: Claude Sonnet 4.6
upstream_model:
anthropic: claude-sonnet-4-6
- id: claude-haiku-4-5
label: Claude Haiku 4.5
upstream_model:
anthropic: claude-haiku-4-5
managed:
policies:
- match: { groups: [contractors] }
cli:
availableModels: [claude-haiku-4-5]
# allow auto-approves these tools; it does not block the rest.
# Add deny rules to restrict tools.
permissions: { allow: [Read, Grep] }
- match: {}
cli:
availableModels: [claude-opus-4-8, claude-sonnet-4-6, claude-haiku-4-5]
# Constrain the Default picker option to each policy's availableModels
# instead of the built-in default, so no role gets a 400 on Default.
# The contractors policy inherits this key.
enforceAvailableModels: true
permissions:
allow: [Read, Grep, Edit]
deny: ["WebFetch"]
env: { HTTP_PROXY: http://proxy.example.com:8080 }
telemetry:
forward_to:
- url: https://otel.internal.example.com:4318
headers:
Authorization: Bearer ${OTEL_TOKEN}#הגדרות מנוהלות בצד הלקוח
כל מה שלמעלה מגדיר את שרת השער. מכוונים את מכונות המפתחים אל השער בנפרד, על כל מכשיר, דרך ההגדרות המנוהלות של Claude Code. השער לא יכול לדחוף את מפתחות הכניסה בעצמו, כי הם אלה שאומרים ללקוח איפה השער נמצא.
עבור ה-CLI, הגדירו את המפתחות האלה ב-managed-settings.json לפי מערכת ההפעלה. שני מפתחות הכניסה מנתבים את /login של כל מפתח אל השער שלכם:
{
"forceLoginMethod": "gateway",
"forceLoginGatewayUrl": "https://claude-gateway.internal.example.com",
"parentSettingsBehavior": "merge"
}parentSettingsBehavior: "merge" שומר על כך שהעברת רשימת ההיתר של היציאה מ-Claude Desktop אל הפעלות Claude Code המוטמעות שלו תעבוד. מסירת מדיניות להפעלות Claude Desktop מסביר את המנגנון ואיפה ההצטרפות חייבת לשבת.
כדי לעצור מפתחים מלעקוף את השער עם משתנה של ספק ענן או ANTHROPIC_BASE_URL משלהם, הוסיפו "allowedProviders": ["gateway"] לאותו קובץ. Claude Code אז מסרב לכל הפעלה במכונה שלא מוגדרת לשער Cloud, ומאשר שער רק כשהוא זה ש-forceLoginGatewayUrl מציין או אחד שכתובת ה-URL שלו מוגדרת בבלוק env של הקובץ כ-ANTHROPIC_BASE_URL. claude gateway מסרב לרוץ על מכונה שמגדירה את הרשימה, אז השאירו את המפתח מחוץ למארח השער. ראו את הערך allowedProviders בייחוס ההגדרות. דורש Claude Code v2.1.285 או חדש יותר.
פרסו את קובץ managed-settings.json לכל מכשיר, בדרך כלל דרך פלטפורמת ה-MDM שלכם. נתיב הקובץ שונה לפי פלטפורמה. ראו איפה כל מנגנון שומר את המדיניות.
כברירת מחדל, מדיניות registry ב-Windows או plist של managed-preferences ב-macOS מחליפים את קובץ managed-settings.json במקום להתמזג איתו, מלבד מפתחות החריגה ובדיקות בין מקורות למעלה. כל שלושת המפתחות בקטע הזה עוקבים אחרי כלל המקור בעדיפות הגבוהה ביותר, כך שציים שמספקים מדיניות דרך Group Policy או פרופילי תצורה חייבים לשים את שלושתם במנגנון הזה במקום.
עבור Claude Desktop, הגדירו את המפתח bootstrapUrl ב-תצורה המנוהלת של Claude Desktop עצמו ל-<listen.public_url>/user/bootstrap. זרימת הכניסה והמדיניות לפי קבוצה אז תואמות לאלה של ה-CLI אחרי שמדיניות מצטרפת בצד השרת עם מפתח desktop. בלי ההצטרפות, /user/bootstrap מחזיר 404. ראו שכבת Claude Desktop לחצי שבצד השרת.
Claude Code מכבד את forceLoginGatewayUrl, gatewayInternalNetworks, ואת הערך "gateway" של forceLoginMethod ממקור מנוהל במכונה: managed-settings.json, ה-plist של macOS או ה-registry של Windows HKLM, או עוזר מדיניות. הגדרתם ב-payload של השער לא מגדירה את כניסת השער. עבור ~/.claude/settings.json של מפתח עצמו, ראו הגדרת כתובת ה-URL של השער בהגדרות המשתמש.
השאירו את forceLoginMethod ואת forceLoginOrgUUID מחוץ ל-payload. Claude Code עדיין קורא את שני המפתחות מה-payload לבדיקת האישורים בעלייה, כך שמפתח ששומר אישור שהונפק על ידי Anthropic במכונה מקבל את יציאת העלייה המתוארת תחת מדיניות מנהל דורשת כניסה לשער Cloud גם אחרי שהם נכנסים.
#קשור
- סקירת שער אפליקציות Claude: התחלה מהירה וחיבור מפתחים
- מדריך פריסה: הגדרת IdP, תמונת קונטיינר, Kubernetes ו-Cloud Run, ותפעול
- מגבלות הוצאה: תקרות לפי מפתח וה-API לניהול