메인 콘텐츠로 건너뛰기
이 페이지는 Claude 앱 게이트웨이 실행의 운영 측면을 다룹니다: 게이트웨이를 ID 공급자(IdP)에 등록하고, 게이트웨이를 컨테이너로 배포하며, 일상적으로 운영합니다. 게이트웨이가 부팅 시 읽는 gateway.yaml 파일의 모든 옵션에 대해서는 구성 참조를 참조하세요. 프로덕션 배포는 순서대로 4단계를 따르며, 아래 섹션이 이를 일치시킵니다. 처음 두 단계는 선택을 하는 곳이고, 나머지 두 단계는 실행 중일 때 참조할 참고 자료입니다.
  1. ID 공급자 설정: OAuth 클라이언트를 등록하고 Okta, Entra, Google에 대한 IdP별 참고사항 확인
  2. 게이트웨이 배포: 고정된 컨테이너 이미지를 빌드하고 Kubernetes, Cloud Run 또는 자신의 플랫폼에서 실행합니다. 이 섹션은 비용, 우회, 다중 게이트웨이 및 서버리스 결정도 다룹니다
  3. 운영 설정: 로그, 상태 프로브, 중단 동작, 시크릿 로테이션 및 업그레이드. 모니터링 및 런북을 연결할 때 참조할 참고 자료
  4. 보안 태세 검토: 데이터가 어디로 흐르는지, 위협 모델 및 규정 준수 답변. 보안 검토를 위한 참고 자료
로그인 또는 부팅이 실패하면 문제 해결로 바로 이동하세요. 이는 표시되는 오류를 기준으로 구성되어 있습니다.
프라이빗 네트워크에 배포하세요. Claude Code는 주소가 프라이빗인 게이트웨이에만 연결합니다. 이는 보안 가드입니다. 신뢰할 수 있는 게이트웨이는 개발자 머신에서 명령을 실행하는 설정을 푸시할 수 있기 때문입니다. 게이트웨이를 내부 로드 밸런서 또는 VPN 뒤에 배치하고 프라이빗 IP로만 확인되는 호스트명을 지정하세요.

ID 공급자 설정

단일 리디렉션 URI https://<gateway>/oauth/callback을 사용하여 기밀 OAuth/OpenID Connect(OIDC) 웹 애플리케이션을 ID 공급자에 등록하고, 게이트웨이 액세스 권한이 있어야 하는 사용자 또는 그룹에 할당하세요. 모든 OIDC 호환 IdP가 작동합니다: Okta, Microsoft Entra ID, Google Workspace, Keycloak, Dex, PingFederate 등. IdP는 세 가지 요구사항을 충족해야 합니다:
  • /.well-known/openid-configuration을 프로덕션에서 HTTPS를 통해 제공합니다. 게이트웨이는 http:// 발급자를 허용하며, 루프백 발급자는 추가로 CLAUDE_GATEWAY_ALLOW_LOOPBACK=1이 필요합니다
  • 인증 코드 흐름을 지원합니다. PKCE(Proof Key for Code Exchange)는 기본적으로 활성화되어 있습니다. 이를 지원하지 않는 IdP의 경우 oidc.use_pkce: false로 비활성화하세요
  • id_token에서 email을 반환하고 선택적으로 groups를 반환하거나, oidc.userinfo_fallback: true를 사용하여 userinfo 엔드포인트에서 제공합니다
프라이빗 PKI의 경우 oidc.ca_cert_pem을 설정하세요. 일부 공급자는 이메일 및 그룹 클레임을 다르게 처리합니다:
  • Okta: https://example.okta.com의 조직 인증 서버는 emailgroups를 생략하는 얇은 id_token을 반환하므로, 이를 issuer로 사용할 때마다 oidc.userinfo_fallback: true를 설정하세요. https://example.okta.com/oauth2/default와 같은 id_token에 email 및 선택적으로 groups를 포함하는 사용자 정의 인증 서버는 이를 직접 내보내며 폴백이 필요하지 않습니다. Okta는 oidc.scopes에서 groups 범위가 요청되고 앱의 그룹 클레임 필터가 이를 허용할 때만 groups를 내보냅니다. userinfo_fallback은 IdP가 요청하지 않은 클레임을 채울 수 없습니다.
  • Microsoft Entra ID: issuer = https://login.microsoftonline.com/<tenant-id>/v2.0. Entra는 이름이 아닌 그룹 개체 ID를 내보내므로, managed.policies.match.groups에서 GUID를 사용하거나 인간이 읽을 수 있는 이름을 위해 앱 역할을 사용하세요. 테넌트가 groups 대신 roles 아래에 역할을 내보내는 경우 oidc.groups_claim: roles을 설정하세요.
  • Google Workspace: issuer = https://accounts.google.com. Google의 id_token은 그룹을 전달하지 않습니다. Google을 IdP로 사용하여 그룹 기반 allowed_groups 또는 managed.policies를 사용하려면 oidc.google_groups를 구성하세요. 이는 도메인 전체 위임이 있는 서비스 계정을 사용하여 Admin SDK Directory API를 통해 각 사용자의 그룹을 조회합니다. 이 없이는 멤버십 게이팅을 위해 oidc.allowed_email_domains를 사용하고 정책 할당을 위해 managed.policies.match.email_domain을 사용하세요. Google은 또한 표준 offline_access 범위를 무시합니다. 새로고침 토큰의 경우 oidc.scopes: [openid, profile, email]oidc.extra_auth_params: { access_type: offline, prompt: consent }를 설정하세요.
위에서 다루지 않은 ID 공급자에 대한 지원은 문제 해결을 참조하세요.
새로고침 토큰을 사용하면 게이트웨이가 개발자를 브라우저로 다시 보내지 않고 개발자의 세션을 자동으로 갱신할 수 있습니다. 또한 IdP가 사용자를 비활성화할 때 다음 새로고침이 실패하고 세션이 ttl_hours 내에 종료되므로 프로비저닝 해제를 주도합니다. 게이트웨이는 기본적으로 새로고침 토큰을 얻기 위해 offline_access를 요청합니다. IdP가 오프라인 액세스에 대한 명시적 동의를 요구하는 경우 OAuth 클라이언트를 구성하여 이를 허용하세요.IdP가 전혀 새로고침 토큰을 발급할 수 없는 경우, 게이트웨이는 여전히 작동하지만 자동 갱신이 없으므로 개발자는 세션이 만료될 때 브라우저 로그인을 다시 실행합니다. 이것이 매시간 발생하지 않도록 하려면 session.ttl_hours8 또는 12로 올리세요. 트레이드오프는 프로비저닝 해제 지연입니다. 새로고침 토큰이 없으면 비활성화된 사용자는 더 긴 TTL이 경과할 때까지 액세스를 유지합니다.

배포

게이트웨이는 단일 Linux 바이너리입니다. 복제본이 상태 비저장이고 Postgres가 공유 조정 계층이므로 수평으로 확장됩니다. 환경에서 상태 비저장 서비스를 실행하는 방식대로 실행하세요. 이 섹션의 나머지 부분은 이미지가 필요한 것을 설명하며, Kubernetes 및 Cloud Run에 대한 짧은 참고사항이 있습니다. 게이트웨이는 업스트림 자격 증명을 보유하고 추론을 위한 단일 송신 지점으로 작동하므로 네트워크 내부에서 실행되도록 설계되었습니다. 개발자와 IdP가 HTTPS를 통해 도달할 수 있는 곳이면 어디든 실행할 수 있습니다. 프로덕션 자격 증명을 보유하는 다른 서비스처럼 취급하세요. 몇 가지 결정이 실행 위치 이상으로 배포를 형성합니다:
  • 비용: 게이트웨이에 대한 별도의 라이선스 또는 사용자당 요금이 없습니다. 이는 claude 바이너리의 일부입니다. 기존 클라우드 또는 Anthropic 약정을 통해 추론에 대해 비용을 지불하고, 컨테이너 및 텔레메트리 수집기의 컴퓨팅을 지불합니다.
  • 우회: 게이트웨이는 모델로의 유일한 경로가 이를 통과하도록 강제하지 않습니다. 자신의 자격 증명이 있는 개발자는 여전히 공급자를 직접 호출할 수 있으므로, 해당 경로를 닫는 것은 네트워크 정책 결정입니다. 예를 들어 api.anthropic.com으로의 송신을 게이트웨이를 제외하고 차단합니다. 해당 송신을 차단하면 각 개발자의 머신에서 api.anthropic.com을 호출하는 WebFetch 도메인 안전 확인도 중단됩니다. 관리형 정책에서 skipWebFetchPreflight: true를 설정하여 비활성화하세요.
  • 다중 게이트웨이: 각 게이트웨이는 자신의 구성을 가진 별도의 배포입니다. CLI는 게이트웨이 호스트명별로 신뢰 지문 및 자격 증명을 저장하므로, 다른 팀이 충돌 없이 다른 게이트웨이에 연결할 수 있습니다. 여러 OIDC 발급자를 제공하려면 별도의 인스턴스를 실행하세요.
  • 서버리스: Cloud Run이 작동합니다. 콜드 OIDC 검색을 피하려면 min-instances: 1을 설정하세요. Lambda 및 Cloud Functions는 작동하지 않습니다. 게이트웨이는 장기 실행 HTTP 서버이기 때문입니다.
여기의 모든 프로덕션 토폴로지는 일반 HTTP 복제본 앞에 Ingress, Cloud Run의 프론트 엔드 또는 ALB와 같은 L7 프록시를 배치합니다. listen.trusted_proxies를 프록시의 소스 범위로 설정하여 게이트웨이가 X-Forwarded-For에서 클라이언트 IP를 읽도록 하세요. 게이트웨이는 TCP 피어가 신뢰할 수 있을 때만 헤더를 인정합니다. Google Cloud 작동 예제는 토폴로지별 구체적인 값을 가지고 있습니다. 신뢰할 수 있는 프록시가 없으면, 모든 요청이 프록시의 IP에서 오는 것으로 나타나므로 IP당 속도 제한이 하나의 공유 버킷으로 축소되고 감사 이벤트에 프록시의 IP가 기록됩니다.

컨테이너 이미지

표준 Claude Code 릴리스의 네이티브 claude 바이너리 주위에 자신의 이미지를 빌드하세요:
  1. 고정된 릴리스에서 이미지 아키텍처용 Linux 빌드를 다운로드하세요. 다운로드 URL은 특정 버전 설치를 참조하세요.
  2. 바이너리 무결성 및 코드 서명에 설명된 대로 릴리스의 GPG 서명된 manifest.json에 대해 확인하세요.
  3. 빌드 컨텍스트에 복사하세요.
빌드가 릴리스 호스트에 도달할 수 없는 경우 릴리스를 내부 레지스트리로 미러링하고 플릿이 실행하는 버전을 고정하세요. 바이너리 외에도 이미지는 다음이 필요합니다:
  • glibc 기반 이미지: glibc 빌드의 유일한 동적 종속성은 glibc 라이브러리입니다. Musl 기반 이미지는 linux-x64-musl 또는 linux-arm64-musl 빌드와 추가 패키지가 필요합니다. Alpine Linux 설정을 참조하세요.
  • 쓰기 가능한 상태 디렉토리: 게이트웨이는 모든 사용자로 실행되지만, 최소 이미지에는 쓰기 가능한 홈이 없습니다. CLAUDE_CONFIG_DIR/tmp/.claude와 같은 쓰기 가능한 경로로 설정하세요.
  • 컨테이너 명령: claude gateway --config /etc/claude/gateway.yaml. 구성 파일은 읽기 전용으로 마운트되고 시크릿은 환경 변수로 제공됩니다. 게이트웨이는 listen.port에서 수신하며, 기본값은 8080입니다.

Kubernetes

게이트웨이를 모든 상태 비저장 서비스처럼 배포로 실행하세요:
  • ConfigMap에서 구성을 마운트하고 Secret에서 시크릿을 마운트하세요. YAML에서 ${file:/path/to/secret} 또는 환경 변수를 통해 시크릿을 참조하세요
  • Ingress에서 TLS를 종료하고 listen.public_url을 Ingress 호스트명으로 설정하세요
  • 준비 프로브를 GET /readyz로 지정하고 생존 프로브를 GET /healthz로 지정하세요
워크로드 ID정적 키보다 플랫폼의 워크로드 ID를 선호하세요: EKS의 Bedrock용 IRSA, GKE의 Agent Platform용 Workload Identity, AKS의 Foundry용 워크로드 ID. 업스트림 블록에서 auth: {}를 설정하거나 Foundry의 경우 use_azure_ad: true를 설정하면, 게이트웨이는 해당 공급자의 기본 자격 증명 체인을 통해 포드의 ID를 선택합니다. Bedrock 업스트림을 GKE에서 사용하는 경우와 같은 클라우드 간 페어링의 경우, 업스트림의 auth 블록에서 명시적 자격 증명을 설정하세요. upstreams 참조는 플랫폼별 설정 세부사항을 가지고 있습니다.

Cloud Run

서비스를 다음과 같이 구성하세요:
  • listen.port를 기본값 8080으로 유지하세요. 이는 Cloud Run의 기본 PORT와 일치하거나 port: ${PORT}를 설정하세요
  • public_url을 외부에서 도달 가능한 원본으로 설정하세요. 프로덕션의 경우 이는 일반적으로 내부 로드 밸런서의 호스트명입니다. /login공개 주소를 거부하고 *.run.app URL이 하나로 확인되므로, Cloud Run URL 단독은 curl 또는 브라우저 스모크 테스트에만 작동합니다. 예외는 *.run.app이 Private Service Connect를 통해 프라이빗으로 확인되고 Cloud DNS 프라이빗 영역이 있는 네트워크입니다. 해당 토폴로지에서 Cloud Run URL은 유효한 public_url입니다. Google Cloud 작동 예제는 둘 다 다룹니다.
  • 구성을 시크릿 볼륨으로 마운트하세요
  • 첫 번째 요청에서 콜드 OIDC 검색을 피하려면 min-instances: 1을 설정하세요
Cloud Run 또는 GKE, Cloud SQL 및 Secret Manager를 다루는 Google Cloud의 완전한 작동 예제는 Google Cloud에 배포를 참조하세요.

게이트웨이 URL을 개발자 머신으로 푸시

게이트웨이가 제공되면, MDM을 통해 또는 OS별 managed-settings.json을 직접 작성하여 관리형 설정을 통해 각 개발자의 머신으로 forceLoginMethodforceLoginGatewayUrl을 푸시하세요. 이 없이는 /login이 게이트웨이 옵션이 없는 표준 계정 선택기를 표시합니다. 파일 경로는 클라이언트 측 관리형 설정을 참조하세요.

운영

게이트웨이가 트래픽을 제공하면, 일상적인 운영은 로그를 읽고, 상태를 프로브하며, 일정에 따라 시크릿을 로테이션하는 것입니다. 아래 섹션은 각각을 다루고, Postgres가 보유한 것과 업그레이드 및 롤백이 어떻게 동작하는지를 다룹니다.

로그

게이트웨이는 stderr에 두 개의 스트림을 작성하며, 둘 다 JSON 친화적입니다:
  • 감사 이벤트: 보안 관련 이벤트당 한 줄의 JSON. stderr를 로그 수집기로 파이프하세요. 내보낸 이벤트는 config.load, session.mint, session.refresh, device.authorize, device.verify, auth.denied, access.denied, inference, managed.serve, spend.blockedadmin.denied를 포함합니다. 필드는 이벤트에 따라 다릅니다:
    • 성공적인 mint 및 refresh 이벤트는 sub, email, client_ip 및 결과를 전달합니다
    • 거부 이벤트는 이유, 경로 및 클라이언트 IP를 전달합니다. 거부 시 ID가 없기 때문입니다
    • inference는 어느 업스트림이 요청을 제공했는지 및 응답 상태를 기록합니다
    • admin.denied는 거부된 관리자 API 인증 시도를 이유(invalid_key 또는 no_credentials), 클라이언트 IP, 메서드 및 경로와 함께 기록하며, 제시된 키 자료는 없습니다
  • 운영 로그: 부팅, 경고 및 업스트림 오류에 대한 인간이 읽을 수 있는 [gateway] 접두사 줄. CLAUDE_GATEWAY_LOG_LEVEL 환경 변수는 상세도를 제어하고 info, warn 또는 error를 허용하며, 기본값은 info입니다. 감사 이벤트는 항상 내보내지므로 이는 감사 이벤트에 영향을 주지 않습니다.

상태

게이트웨이는 GET /healthz를 생존 프로브로 제공하고 GET /readyz를 준비 프로브로 제공합니다. /readyz는 저장소에 도달 가능한지 확인합니다. 둘 다 access_control.allow_cidrs에서 제외되므로 프로브는 잠긴 리스너에서 작동합니다. /.well-known/oauth-authorization-server의 OAuth 검색 문서는 구성 로드, OIDC 검색, 업스트림 클라이언트 구성 및 Postgres 마이그레이션이 모두 성공한 후에만 200을 반환하므로, 엔드 투 엔드 부팅 확인으로도 작동합니다. 실행 중인 게이트웨이는 또한 <public_url>/protocol에서 실행 중인 버전과 일치하는 수락하는 경로 및 요청 형태의 설명을 제공합니다. 내용은 릴리스 간에 안정적이지 않습니다.

중단 동작

Postgres가 다운되면, 게이트웨이 자체는 로그인한 개발자를 계속 제공하고 새로운 로그인은 실패합니다. 개발자가 실제로 계속 작동하는지는 오케스트레이터가 준비를 처리하는 방식에 따라 다릅니다:
  • 기존 세션: 베어러 토큰은 JWT 시크릿으로 로컬에서 검증되고, 세션 새로고침은 저장소를 건드리지 않으며, 게이트웨이 프로세스는 여전히 추론을 제공할 수 있습니다
  • 새로운 로그인: Postgres가 복구될 때까지 실패합니다. 장치 흐름 및 속도 제한 카운터가 Postgres에 있기 때문입니다
  • 지출 제한 적용: 중단 중에 기본적으로 열린 상태로 실패하므로 추론이 계속 흐릅니다. 차단하는 것을 선호하면 닫힌 상태로 뒤집으세요
  • 준비: /readyz는 중단 중에 준비되지 않음을 보고하므로, 준비에 대한 트래픽을 게이트하는 오케스트레이터는 Postgres가 복구될 때까지 모든 복제본을 한 번에 로테이션에서 제거합니다. 해당 토폴로지에서 게이트웨이가 여전히 제공할 수 있는 추론을 포함한 모든 트래픽은 로드 밸런서에서 실패합니다. /healthz의 생존 프로브는 계속 통과하므로 복제본은 다시 시작되지 않습니다. 로그인한 개발자가 저장소 중단을 통해 계속 작동하도록 하려면 준비 프로브를 /healthz로 지정하세요. 비용은 새로운 로그인이 여전히 준비됨을 보고하는 복제본에 대해 실패한다는 것입니다.
IdP가 다운되면, 기존 세션은 ttl_hours까지 작동하고, 새로운 로그인 및 새로고침은 실패합니다. IdP가 자주 유지보수 창을 가지면 더 긴 ttl_hours를 설정하세요.

JWT 시크릿 로테이션

기존 세션이 유효하게 유지되도록 3단계로 서명 시크릿을 로테이션하세요:
  1. 새 시크릿을 생성하세요. session.jwt_secret 배열에 앞에 추가하세요.
  2. 배포를 롤링하세요. 새 토큰은 새 시크릿으로 서명합니다. 이전 토큰은 여전히 검증합니다.
  3. ttl_hours와 여유 후에 이전 시크릿을 제거하고 다시 롤링하세요.
로테이션은 또한 만료 전에 세션을 강제로 제거하는 유일한 방법입니다: 베어러 토큰은 JWT 시크릿에 대해 로컬에서 검증되므로 세션별 해제가 없습니다. 배열에 이전 시크릿을 유지하지 않고 시크릿을 완전히 교체하면 한 번에 모든 미해결 세션이 무효화됩니다. 개별 오프보딩의 경우 IdP에서 사용자를 프로비저닝 해제하세요. 세션은 ttl_hours 내에 종료됩니다.

Postgres

게이트웨이는 부팅 시 마이그레이션으로 생성되는 5개의 테이블을 보유합니다:
테이블내용보존
kv장치 부여(10분 TTL) 및 속도 제한 카운터행별 TTL
spend주요 기간별 누적 지출 카운터(센트)admin.spend_retention_months, 기본값 13
spend_limits구성된 지출 상한API를 통해 삭제될 때까지
admin_audit관리자 API 변경 추적admin.audit_retention_days, 기본값 365
principal_emails각 주요의 마지막 확인 이메일, 표시 이름 및 IdP 그룹. PII를 포함합니다.admin.identity_retention_days 마지막 활동 이후, 기본값 90
30초 루프는 TTL을 지난 kv 행을 만료하고, 시간별 스윕은 지출 테이블의 보존 창을 적용하므로 아무것도 무한정 증가하지 않습니다. 지출 제한이 구성되지 않으면 kv만 작성됩니다. 보안 정책이 애플리케이션 역할의 DDL을 금지하면 이러한 테이블과 _migrations을 관리자 역할로 미리 생성하고 앱 역할에 각각에 대해 SELECT, INSERT, UPDATE, DELETE를 부여하세요. 지출 제한이 사용 중이면, 손실된 데이터베이스는 개발자 재로그인뿐만 아니라 손실된 지출 추적 및 상한을 의미하므로 정기적인 백업을 실행하세요. 보존을 기다리지 않고 떠난 개발자 하나를 즉시 지우려면 DELETE FROM principal_emails WHERE principal = '<sub>'을 직접 실행하세요. 이는 이메일, 이름 및 그룹을 보유하는 유일한 테이블을 제거합니다. spendadmin_audit 행은 의사명 OIDC sub만 참조합니다.

업그레이드

복제본은 상태 비저장이므로 롤링 재시작은 언제든지 안전합니다. 게이트웨이는 부팅 시 스키마 마이그레이션을 실행하므로, 새 바이너리를 배포하면 데이터베이스가 자동으로 마이그레이션됩니다. 데이터베이스 역할이 DDL을 실행할 수 없으면 스키마를 미리 생성하세요. 현재 버전으로 시드된 _migrations 테이블을 포함합니다. 그렇지 않으면 부팅이 CREATE TABLE을 시도하면서 실패합니다. 마이그레이션은 추가 전용이므로 더 적은 마이그레이션을 아는 이전 바이너리로 롤백하는 것은 안전합니다. 추가 행을 무시합니다. 롤백은 또한 YAML을 이전 바이너리의 스키마에 대해 재검증하므로, 새 릴리스에서 도입한 키를 채택한 구성은 이전 바이너리에서 부팅이 실패합니다. 롤백 전에 새 키를 제거하세요. 게이트웨이의 버전을 자신의 이미지에 고정하므로, 새 Claude Code 릴리스의 수정사항(보안 수정사항 포함)은 핀을 업데이트하고 재배포할 때만 배포에 도달합니다. 게이트웨이를 프로덕션 자격 증명을 보유하는 다른 서비스에 사용하는 것과 동일한 패칭 주기에 포함하세요.

보안

이 섹션은 보안 검토가 묻는 질문에 답합니다: 어떤 데이터가 게이트웨이를 통해 흐르고 어디로 가는지, 설계가 방어하는 공격, 규정 준수 질문지에 속하는 답변.

데이터 흐름

데이터경로게이트웨이에서 Anthropic으로 전송됨
추론(프롬프트, 완료)CLI → 게이트웨이 → 업스트림Anthropic API가 구성된 업스트림인 경우에만
텔레메트리(OTLP 메트릭, 플러스 옵트인 로그 및 추적)CLI → 게이트웨이 → 수집기절대 아님
ID(이메일, 그룹, sub)IdP → 게이트웨이 → JWT → CLI; CLI는 OTLP 내보내기에 스탬프합니다절대 아님
관리형 설정게이트웨이 YAML → CLI절대 아님
감사 로그게이트웨이 stderr → 수집기절대 아님

위협 모델 요약

게이트웨이는 네트워크 경계 내부에 있지만, 개별 개발자 노트북은 신뢰할 수 있는 것으로 취급되지 않습니다. 설계는 3가지 방식으로 이를 설명합니다:
  • 개발자는 원시 업스트림 키 대신 단기 JWT를 보유합니다. CLI-게이트웨이 레그는 RFC 8628 장치 부여를 사용하고, 게이트웨이의 IdP와의 인증 코드 교환은 기본 구성에서 PKCE를 실행하므로, 가로챈 IdP 인증 코드는 쓸모가 없습니다.
  • 장치 검증 페이지는 동일 출처 POST 및 RFC 8628 §5.1당 IP당 속도 제한을 적용합니다. 사용자 코드 무차별 대입 저항을 참조하세요.
  • 아웃바운드 요청은 DNS를 확인하고, 링크 로컬 및 클라우드 메타데이터 주소와 기본적으로 루프백을 차단하며, 연결을 확인된 IP에 고정하는 서버 측 요청 위조(SSRF) 가드를 통과합니다. 따라서 IdP 및 OTLP 대상과 같은 운영자 영향 URL은 클라우드 메타데이터 엔드포인트로 리디렉션될 수 없습니다. RFC 1918 프라이빗 범위는 의도적으로 허용됩니다. IdP 및 OTLP 수집기가 일반적으로 프라이빗 IP에 있기 때문입니다. 루프백 IdP 또는 수집기에 대한 로컬 개발의 경우 게이트웨이의 환경에서 CLAUDE_GATEWAY_ALLOW_LOOPBACK=1을 설정하세요. 프로덕션에서는 설정하지 마세요.
자신의 송신 제어를 추가하면, 게이트웨이는 워크로드 ID와 같은 인스턴스 메타데이터 자격 증명을 사용할 때마다 메타데이터 서버에 도달해야 합니다. 두 가지 위협은 범위를 벗어났습니다. 이는 보안할 인프라입니다:
  • 손상된 게이트웨이 호스트: 호스트는 업스트림 자격 증명을 보유하고 관리형 설정을 모든 연결된 개발자에게 배포하므로, 게이트웨이 구성에 대한 제어는 MDM에 대한 제어와 비교할 수 있습니다. CLI의 일회성 승인 대화는 셸 가능 설정의 자동 변경을 제한하지만 호스트 보안을 대체하지 않습니다.
  • 악의적인 OIDC 공급자: 공급자는 게이트웨이가 신뢰하는 id_token에 서명하므로 모든 ID를 주장할 수 있습니다. IdP 검증 및 보안은 귀사의 책임입니다.

사용자 코드 무차별 대입 저항

개발자가 /device 검증 페이지에 입력하는 user_code는 20자 알파벳에서 그려진 8자이며, 20⁸ 또는 약 2.56×10¹⁰ 조합을 산출하고 10분 후 만료됩니다. 게이트웨이는 rate_limits를 통해 구성 가능한 장치 부여 엔드포인트에 IP당 속도 제한을 적용합니다. 많은 개발자가 단일 공유 회사 NAT 주소에서 로그인하면 제한을 올리세요. 제한은 로그인 흐름에만 적용되며 추론에는 적용되지 않습니다.

규정 준수 태세

  • 데이터 거주지: 게이트웨이의 자체 데이터 평면은 Anthropic API가 구성된 업스트림인 경우를 제외하고 Anthropic에 아무것도 보내지 않습니다. 그 경우 기존 데이터 처리 계약이 추론 경로에 적용됩니다. 텔레메트리, 감사, ID 및 설정은 구성한 대상으로만 이동합니다.
  • 호스트 프로세스 트래픽: 호스트 프로세스는 Claude Code CLI이며, 시작 분석 및 업데이트 확인을 Anthropic으로 보낼 수 있습니다. 엄격한 송신 배포의 경우 게이트웨이의 컨테이너 환경에서 CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1을 설정하세요.
  • 클라이언트 분석: CLI는 게이트웨이에 로그인하는 동안 자신의 사용 분석을 비활성화하고, 오류 보고는 타사 API 표면에서 기본적으로 꺼져 있습니다.
  • 클라이언트 머신: 개발자의 CLI는 CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1skipWebFetchPreflight: true가 설정되지 않으면 여전히 WebFetch 호스트명 확인 및 버전 확인을 Anthropic으로 보냅니다. 데이터 사용을 참조하세요.
  • 설문 조사 평가: 게이트웨이 자격 증명은 Anthropic 바운드 평가 싱크를 비활성화하므로 평가는 Anthropic으로 전송되지 않습니다.
  • 트랜스크립트 공유: 설문 조사의 트랜스크립트 공유 프롬프트에서 예를 선택하면 Anthropic으로 업로드하는 대신 ~/.claude/feedback-bundles/ 아래의 로컬 파일을 작성합니다.
  • 클라이언트 업데이트: 업데이트 확인은 게이트웨이 트래픽과 별개입니다. 자신의 배포를 통해 버전을 고정하고 노트북이 릴리스를 가져오면 안 되면 DISABLE_UPDATES를 설정하세요. DISABLE_AUTOUPDATERclaude update가 여전히 작동하는 동안 백그라운드 업데이트만 중지합니다.
  • TLS: 프로덕션에서 public_url을 HTTPS를 통해 제공하세요. 게이트웨이의 자체 리스너를 통해 listen.tls를 사용하거나 listen.public_url이 설정된 일반 HTTP 복제본 앞의 TLS 종료 ingress에서. 게이트웨이는 일반 HTTP를 거부하지 않습니다. IdP는 프로덕션에서 HTTPS를 제공해야 하고, Postgres는 ?sslmode=require를 지원합니다. ingress에서 Strict-Transport-Security를 설정하세요.
  • 취약점 공개: 보안 문제 보고를 따르세요

문제 해결

질문 및 피드백은 Claude Code 지원을 사용하거나 Claude Code GitHub 저장소에서 이슈를 열어주세요. 문제를 보고할 때 다음을 포함하세요:
  • 게이트웨이 문제: 관련 창의 게이트웨이 stderr, 시크릿이 수정된 gateway.yaml, 게이트웨이 버전(랜딩 페이지 /에 표시되고 /managed/settingsx-cc-gateway-version 응답 헤더에 표시됨), 최근에 변경된 것
  • 로그인 문제: 개발자는 claude --debug-file ./claude-debug.txt를 실행하고, 재현하며, 해당 파일과 동일한 창의 게이트웨이 감사 로그를 보냅니다
  • 추론 문제: 요청된 모델, 구성된 업스트림, 요청의 게이트웨이 감사 로그(어느 업스트림이 제공했는지 및 응답 상태를 기록함)
증상원인수정
개발자의 /loginCloud 게이트웨이 화면 대신 표준 계정 선택기를 표시합니다forceLoginMethod 또는 forceLoginGatewayUrl이 해당 머신의 관리형 설정에 설정되지 않음관리형 설정 파일을 장치에 배포하세요. /login은 거기서 게이트웨이 URL을 읽습니다
시작 시 Gateway login is configured in managed settings, but this Claude Code build does not include Cloud gateway support. 표시설치된 Claude Code 빌드가 게이트웨이 지원보다 앞서갑니다개발자가 Claude Code를 Cloud 게이트웨이 지원을 포함하는 릴리스로 업데이트하도록 하세요
CLI /login: Gateway hosts must be on your organization's private network; <host> resolves to the public (or unrecognized) address <ip>게이트웨이 호스트명이 적어도 하나의 공개 IP 주소로 확인됩니다. Claude Code는 각 확인된 주소를 확인하고 모든 주소가 프라이빗이어야 합니다. 일반적인 원인은 한 패밀리가 공개 주소로 확인되는 이중 스택 이름입니다. AWS 내부 이중 스택 로드 밸런서를 포함하여 공개 범위 AAAA 주소를 반환합니다게이트웨이 이름이 개발자 머신에서 프라이빗 주소로만 확인되도록 하세요. 이중 스택 이름의 경우 공개 범위 레코드를 삭제하거나 별도의 내부 전용 DNS 이름을 제공하세요. 프라이빗 네트워크 전제조건을 참조하세요.
CLI /login: Gateway login requires a direct connection and does not support connecting through an HTTP proxyHTTPS_PROXY 또는 HTTP_PROXY가 게이트웨이 호스트에 적용되고 프록시의 호스트명이 공개 주소로 확인됩니다. 호스트가 프라이빗 주소로만 확인되는 프록시는 허용되며 이 오류를 트리거하지 않습니다개발자의 머신에서 NO_PROXY에 게이트웨이 호스트를 추가하여 연결이 직접이거나 호스트명이 프라이빗 주소로 확인되는 프록시를 사용하세요
CLI /login: Could not resolve gateway host <host>머신이 게이트웨이의 내부 DNS 이름을 확인할 수 없습니다. 일반적으로 회사 네트워크에 없기 때문입니다개발자가 네트워크 또는 VPN에 연결한 후 /login을 다시 시도하도록 하세요
부팅이 store.postgres_url을 명명하는 구성 검증 오류로 종료됩니다Postgres가 구성되지 않음. 게이트웨이는 Postgres가 필요합니다store.postgres_url을 설정하세요. 로컬 개발의 경우 일회용 컨테이너를 사용하세요: docker run --rm -p 5432:5432 -e POSTGRES_HOST_AUTH_METHOD=trust postgres.
부팅 종료: requires the native binaryNode 대신 네이티브 바이너리에서 실행 중입니다독립 실행형 설치 방법 중 하나로 Claude Code를 설치하세요
부팅이 config.load 후 OIDC 검색 오류로 종료됩니다oidc.issuer에 도달할 수 없거나 TLS 체인을 신뢰하지 않습니다발급자가 포드에서 도달 가능하고 /.well-known/openid-configuration을 제공하는지 확인하세요. 프라이빗 PKI의 경우 ca_cert_pem을 설정하세요.
부팅이 Postgres 권한 오류로 종료됩니다앱 역할에 CREATE TABLE 권한이 없습니다관리자 역할로 스키마를 미리 생성하고 앱 역할에 DML을 부여하거나, 새 마이그레이션을 적용하는 부팅을 위해 DDL을 임시로 부여하세요
/oauth/callback이 “Sign-in could not be completed” 표시이메일 도메인이 거부되었거나, id_token 검증이 실패했거나, email_verified가 명시적으로 false입니다. 게이트웨이는 항상 이를 거부하며 재정의가 없습니다allowed_email_domains를 확인하고 IdP가 검증된 email 클레임을 반환하는지 확인하세요. email_verified: false의 경우 IdP 측 검증을 수정하세요. IdP가 다른 클레임 이름 아래에 이메일을 내보내면 oidc.email_claim을 설정하세요.
로그: token exchange failed: id_token missing email claimIdP가 기본적으로 id_token에 email을 포함하지 않습니다. 이 거부는 allowed_email_domains가 설정된 경우에만 발생합니다. 없으면 누락된 이메일이 이메일 없이 세션을 민트합니다IdP를 구성하여 id_token에 email을 내보내세요. Okta: 사용자 정의 인증 서버의 ID 토큰 클레임에 email을 추가하세요. Entra: 앱 등록에서 email을 선택적 클레임으로 추가하세요. PingFederate: email을 내보내는 OpenID Connect 정책을 활성화하세요. IdP가 userinfo 엔드포인트에서 email을 제공하지만 id_token에 포함하지 않으려면(예: Okta 조직 인증 서버), oidc.userinfo_fallback: true를 설정하세요.
모든 Bedrock 요청이 502를 반환합니다. 로그는 Could not load credentials from any providers 표시EC2에서 IMDSv2의 기본 홉 제한 1은 컨테이너 내부에서 인스턴스 메타데이터 요청을 차단합니다. 부팅 및 /readyz는 AWS SDK가 클라이언트 구성이 아닌 첫 번째 요청에서 인스턴스 자격 증명을 확인하므로 어쨌든 통과합니다aws ec2 modify-instance-metadata-options --instance-id <id> --http-put-response-hop-limit 2로 홉 제한을 올리거나 시작 템플릿에서 설정하세요. 변경은 인스턴스의 모든 컨테이너에 적용됩니다. 가능한 경우 ECS 작업 역할을 선호하세요. 이는 ECS 컨테이너 자격 증명 엔드포인트에서 자격 증명을 읽고 변경을 완전히 피하거나, 노출을 제한하기 위해 전용 게이트웨이 인스턴스에 변경을 적용하세요.
IdP 오류: unknown or unsupported scopeIdP가 인식하지 못하는 범위를 거부합니다oidc.scopes를 IdP가 허용하는 정확한 목록으로 설정하세요. openid를 포함해야 합니다. 기본값은 openid profile email offline_access입니다.
oidc.scopes 설정 후 세션이 자동으로 갱신되지 않습니다offline_access가 재정의에서 삭제되었습니다IdP가 지원하면 offline_access를 다시 추가하세요. 새로고침 토큰이 없으면 개발자는 매 session.ttl_hours마다 브라우저 로그인을 다시 실행합니다.
브라우저가 “This request came from another site and was blocked” 표시CSRF 보호로 차단된 교차 사이트 양식 POST. 포함되거나 프록시된 페이지의 경우 예상됩니다검증 링크를 직접 열어주세요
Chrome이 “Refused to send form data … violates … Content Security Policy directive: form-action”으로 승인 버튼을 차단하지만 동일한 페이지가 Safari 또는 Firefox에서 작동합니다Chrome은 전체 리디렉션 체인에 대해 form-action을 적용합니다. IdP가 허용 목록에 없는 두 번째 호스트로 계속 리디렉션합니다.리디렉션 체인의 각 추가 원본을 oidc.form_action_origins에 추가하세요. 승인 페이지에서 Chrome DevTools → 콘솔을 열어 어느 원본이 차단되었는지 확인하세요.
로그인이 IdP에서 완료되지만 콜백이 실패합니다. Chrome에서 CSP 오류 또는 Safari에서 “this sign-in link has expired”IdP가 response_mode=form_post를 통해 코드를 반환했으며, 이는 POST를 통해 /oauth/callback으로 교차 원본을 자동 제출합니다. Chrome은 엄격한 CSP에서 이를 차단합니다. Safari는 제출을 허용하지만 콜백은 쿼리 문자열만 읽습니다.IdP가 response_mode=query를 준수하는지 확인하세요. 게이트웨이가 명시적으로 요청하므로 콜백은 일반 리디렉션입니다
로그인이 로컬에서 작동하지만 ALB 뒤에서 실패합니다public_url이 설정되지 않아 IdP가 내부 http:// 원본을 redirect_uri로 받습니다listen.public_url을 외부 https:// 원본으로 설정하세요
개발자가 신뢰 프롬프트를 반복적으로 봅니다TLS 인증서가 복제본별 또는 요청별로 회전합니다ingress에서 안정적인 인증서를 사용하거나 TLS를 한 번 종료하고 내부적으로 일반 HTTP를 통해 복제본을 실행하세요
CLI /login: “Could not verify the gateway’s TLS certificate” 또는 SELF_SIGNED_CERT_IN_CHAIN게이트웨이의 TLS 체인이 CLI 호스트의 신뢰 저장소에 없는 프라이빗 CA로 서명됩니다Claude Code는 기본적으로 네이티브 바이너리 및 Node 22.15 이상에서 OS 신뢰 저장소를 읽습니다. CLAUDE_CODE_CERT_STORE는 이 동작을 제어합니다. CA가 OS 신뢰 저장소에 설치되면 개발자가 현재 런타임에 있는지 확인하세요. 그렇지 않으면 시작 전에 NODE_EXTRA_CA_CERTS를 CA 인증서 PEM으로 설정하세요. 첫 연결 지문 프롬프트는 여전히 적용됩니다.