SpyBara
Go Premium

claude-apps-gateway-on-aws.md 2026-11-11 22:59 UTC to 2026-11-12 21:00 UTC

No changes for this document in this history range.

2026
Mon 2 23:57 Fri 6 23:01 Wed 11 22:59

Terapkan gateway aplikasi Claude di AWS

Contoh praktis menjalankan gateway aplikasi Claude di AWS: ECS Fargate atau EKS, Amazon RDS untuk PostgreSQL, AWS Secrets Manager, dan autentikasi berbasis peran IAM ke Amazon Bedrock.

[!NOTE]

Halaman ini menjelaskan satu cara untuk menjalankan gateway aplikasi Claude di AWS. Konfigurasi ini adalah contoh yang berfungsi untuk infrastruktur yang dikelola pelanggan daripada deployment produksi yang didukung; gunakan ini untuk melihat bagaimana potongan-potongan cocok bersama sebelum menyesuaikannya dengan lingkungan Anda sendiri. Untuk persyaratan yang tidak bergantung pada platform, lihat panduan deployment.

Contoh ini menyediakan gateway aplikasi Claude di AWS dengan Amazon Bedrock sebagai upstream model, menggunakan Amazon ECS di AWS Fargate atau Amazon EKS untuk komputasi. Okta adalah penyedia identitas (IdP) contoh, tetapi penyedia IdP yang sesuai dengan OpenID Connect (OIDC) apa pun berfungsi; lihat Pengaturan penyedia identitas untuk detail per-IdP.

[!NOTE]

Bedrock bukan satu-satunya upstream Claude di AWS. Gateway juga mendukung Claude Platform di AWS, API Claude yang dioperasikan Anthropic dengan autentikasi AWS dan penagihan AWS Marketplace, sebagai pengganti Bedrock atau bersama dengannya. Entri upstream, kredensial, dan izin IAM-nya berbeda dari yang berfokus pada Bedrock di halaman ini; referensi upstream Claude Platform di AWS mencakup apa yang berubah, dan sisa halaman ini berlaku tanpa perubahan.

Arsitektur

Diagram gateway aplikasi Claude di AWS: Klien Claude Code terhubung melalui HTTPS ke Application Load Balancer internal yang menghadap gateway (ECS Fargate atau EKS), yang berjalan di subnet pribadi bersama dengan instans Amazon RDS untuk PostgreSQL untuk status sesi. Gateway memproses masuk pengguna melalui OIDC terhadap IdP perusahaan, membaca rahasia dari AWS Secrets Manager, meneruskan permintaan model ke Amazon Bedrock menggunakan peran IAM-nya, dan menarik gambarnya dari Amazon ECR saat deploy.

Arsitektur contoh, dengan Amazon Bedrock sebagai upstream model. Upstream Claude Platform di AWS menempati posisi yang sama.

Gateway berjalan sebagai endpoint HTTPS pribadi di jaringan Anda yang diakses pengembang melalui IdP Anda. Sesi Claude Code mereka mencapai model Claude di Amazon Bedrock melalui peran IAM gateway, jadi tidak ada kredensial model yang mendarat di mesin pengembang. Konfigurasi referensi menyediakan:

  • Layanan Amazon ECS di AWS Fargate atau Amazon EKS Deployment yang menjalankan kontainer gateway
  • Repositori Amazon ECR untuk gambar gateway
  • Instans Amazon RDS untuk PostgreSQL di subnet pribadi, tidak dapat diakses secara publik, untuk store gateway
  • Rahasia AWS Secrets Manager untuk kunci penandatanganan JWT, rahasia klien OIDC, dan URL Postgres
  • Peran IAM dengan bedrock:InvokeModel, bedrock:InvokeModelWithResponseStream, dan bedrock:CountTokens, terpasang sebagai peran tugas ECS atau terikat melalui IAM Roles for Service Accounts (IRSA) di EKS
  • Application Load Balancer Internal untuk HTTPS

Prasyarat

Panduan ini membuat sumber daya milik gateway itu sendiri, tetapi dibangun di atas infrastruktur jaringan dan identitas yang sudah Anda miliki. Sebelum memulai, Anda memerlukan:

Atur environment variable Anda

Setiap perintah di halaman ini membaca empat nilai dari shell Anda: AWS_REGION, ACCOUNT_ID, VPC_ID, dan PRIVATE_SUBNETS.

Pilih region AS tempat Bedrock menyediakan model Claude yang Anda perlukan. Panduan ini mengandalkan katalog model bawaan gateway, yang di-resolve ke inference profile us.anthropic.*, dan kebijakan IAM memberikan akses ke ARN tersebut. Di region non-AS, tambahkan blok models: dengan ID inference profile untuk geo tersebut dan ubah prefiks ARN pada kebijakan IAM agar sesuai.

Jika Anda tidak memiliki ID VPC, tampilkan daftar VPC Anda dengan aws ec2 describe-vpcs, lalu tampilkan daftar subnet VPC tersebut untuk menemukan dua subnet privat di Availability Zone yang berbeda:

aws ec2 describe-subnets --filters "Name=vpc-id,Values=<your-vpc-id>" \
  --query 'Subnets[].{ID:SubnetId,AZ:AvailabilityZone,CIDR:CidrBlock}' --output table

Ekspor keempatnya sebelum melanjutkan:

export AWS_REGION=us-east-1   # a US region where Bedrock serves the Claude models you need
export ACCOUNT_ID="$(aws sts get-caller-identity --query Account --output text)"
export VPC_ID=<your-vpc-id>
export PRIVATE_SUBNETS="<subnet-id-a> <subnet-id-b>"

Men-deploy gateway

Langkah-langkah di bawah ini menyediakan deployment lengkap dengan perintah aws.

1. Buat security group

Tiga security group merangkai jalur lalu lintas: jaringan korporat Anda menjangkau load balancer pada port 443, load balancer menjangkau gateway pada port 8080, dan gateway menjangkau Postgres pada port 5432. Tidak ada hal lain yang dapat dijangkau. Cara Anda memasangnya bergantung pada jalur komputasi:

  • Pada ECS Fargate, langkah deploy memasang $ALB_SG ke load balancer dan $GW_SG ke service.
  • Pada EKS, AWS Load Balancer Controller membuat security group frontend sendiri untuk ALB, sehingga $ALB_SG dan $GW_SG tidak digunakan: anotasi inbound-cidrs pada langkah deploy membatasi listener ke jaringan korporat Anda, dan security group database menerima security group cluster sebagai gantinya.
ALB_SG="$(aws ec2 create-security-group --group-name claude-gateway-alb \
  --description "Claude gateway ALB" --vpc-id "$VPC_ID" \
  --query GroupId --output text)"
GW_SG="$(aws ec2 create-security-group --group-name claude-gateway-svc \
  --description "Claude gateway service" --vpc-id "$VPC_ID" \
  --query GroupId --output text)"
DB_SG="$(aws ec2 create-security-group --group-name claude-gateway-db \
  --description "Claude gateway Postgres" --vpc-id "$VPC_ID" \
  --query GroupId --output text)"

aws ec2 authorize-security-group-ingress --group-id "$ALB_SG" \
  --protocol tcp --port 443 --cidr <your-corporate-cidr>
aws ec2 authorize-security-group-ingress --group-id "$GW_SG" \
  --protocol tcp --port 8080 --source-group "$ALB_SG"
aws ec2 authorize-security-group-ingress --group-id "$DB_SG" \
  --protocol tcp --port 5432 --source-group "$GW_SG"

2. Buat IAM role dan kirimkan formulir use case

Gateway berjalan dengan task role khusus yang satu-satunya izinnya adalah memanggil model Claude di Bedrock. Sesuai referensi upstream Bedrock, kebijakan harus mencakup ARN inference-profile lintas region maupun ARN foundation-model yang mendasarinya:

cat > bedrock-invoke.json <<EOF
{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": ["bedrock:InvokeModel", "bedrock:InvokeModelWithResponseStream", "bedrock:CountTokens"],
    "Resource": [
      "arn:aws:bedrock:${AWS_REGION}:${ACCOUNT_ID}:inference-profile/us.anthropic.*",
      "arn:aws:bedrock:*::foundation-model/anthropic.*"
    ]
  }]
}
EOF
cat > ecs-trust.json <<'EOF'
{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Principal": { "Service": "ecs-tasks.amazonaws.com" },
    "Action": "sts:AssumeRole"
  }]
}
EOF

aws iam create-role --role-name claude-gateway-task \
  --assume-role-policy-document file://ecs-trust.json
aws iam put-role-policy --role-name claude-gateway-task \
  --policy-name bedrock-invoke --policy-document file://bedrock-invoke.json

ECS juga memerlukan execution role, yang digunakan oleh agent ECS itu sendiri untuk menarik image dari ECR dan menyuntikkan nilai Secrets Manager yang dibuat kemudian. Role ini terpisah dari task role yang digunakan AWS SDK milik gateway saat runtime:

aws iam create-role --role-name claude-gateway-execution \
  --assume-role-policy-document file://ecs-trust.json
aws iam attach-role-policy --role-name claude-gateway-execution \
  --policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
cat > secrets-read.json <<EOF
{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": ["secretsmanager:GetSecretValue", "secretsmanager:DescribeSecret"],
    "Resource": [
      "arn:aws:secretsmanager:${AWS_REGION}:${ACCOUNT_ID}:secret:gateway-jwt-secret-??????",
      "arn:aws:secretsmanager:${AWS_REGION}:${ACCOUNT_ID}:secret:gateway-oidc-client-secret-??????",
      "arn:aws:secretsmanager:${AWS_REGION}:${ACCOUNT_ID}:secret:gateway-postgres-url-??????"
    ]
  }]
}
EOF
aws iam put-role-policy --role-name claude-gateway-execution \
  --policy-name read-gateway-secrets --policy-document file://secrets-read.json

Kebijakan ini menyebutkan satu ARN per secret alih-alih wildcard gateway-* polos, yang di akun bersama juga akan cocok dengan secret yang tidak terkait; akhiran -?????? cocok persis dengan sufiks acak enam karakter yang ditambahkan Secrets Manager ke ARN setiap secret. Akhiran -* akan menjadi glob prefiks biasa dan juga akan cocok dengan nama yang lebih panjang seperti gateway-postgres-url-prod.

Kebijakan IAM memberikan izin kepada gateway untuk memanggil Bedrock, dan Bedrock mengaktifkan akses model secara default di region komersial. Gerbang tingkat akun yang tersisa adalah formulir use case satu kali dari Anthropic: jika belum ada seorang pun di akun Anda yang mengirimkannya, buka konsol Amazon Bedrock, pilih model Anthropic dari Model catalog, dan lengkapi formulirnya. Akses diberikan segera setelah pengiriman; lihat Claude Code di Amazon Bedrock untuk formulir AWS Organizations dan izin IAM yang diperlukan oleh pengirim.

Jalur EKS menggunakan kembali kedua dokumen kebijakan pada role IRSA alih-alih dua role ECS; lihat langkah deploy.

3. Sediakan Amazon RDS for PostgreSQL

Instance menjalankan Postgres 16 di subnet privat, tanpa alamat publik dan dengan enkripsi penyimpanan aktif.

Pertama, buat subnet group yang menempatkan database di subnet privat, serta parameter group dengan rds.force_ssl=1 agar server menolak koneksi plaintext. Versi engine dipatok sekali karena family parameter group harus cocok dengan versi mayor engine yang dijalankan instance:

aws rds create-db-subnet-group --db-subnet-group-name claude-gateway-db \
  --db-subnet-group-description "Claude gateway" --subnet-ids $PRIVATE_SUBNETS

PG_VERSION=16
PG_FAMILY="postgres${PG_VERSION}"
aws rds create-db-parameter-group --db-parameter-group-name claude-gateway-db \
  --db-parameter-group-family "$PG_FAMILY" \
  --description "Claude gateway - require TLS on every connection"
aws rds modify-db-parameter-group --db-parameter-group-name claude-gateway-db \
  --parameters "ParameterName=rds.force_ssl,ParameterValue=1,ApplyMethod=immediate"

Kemudian buat instance dengan kata sandi master yang dihasilkan:

PGPASS="$(openssl rand -hex 24)"
aws rds create-db-instance --db-instance-identifier claude-gateway-db \
  --engine postgres --engine-version "$PG_VERSION" \
  --db-instance-class db.t4g.micro \
  --allocated-storage 20 --db-name claude_gateway \
  --master-username gateway --master-user-password "$PGPASS" \
  --db-subnet-group-name claude-gateway-db \
  --db-parameter-group-name claude-gateway-db \
  --vpc-security-group-ids "$DB_SG" \
  --no-publicly-accessible --storage-encrypted

Argumen literal --master-user-password terlihat di tabel proses dan di log audit/EDR selama perintah berjalan, paparan yang sama dengan yang dibahas dalam catatan langkah secret. Pada host bersama atau yang dipantau, berikan kata sandi melalui --cli-input-json dari file 0600 sebagai gantinya, seperti yang dilakukan setup.sh milik bundle.

Tunggu hingga instance aktif, yang dapat memakan waktu beberapa menit, lalu baca endpoint privatnya dan susun string koneksi yang akan digunakan gateway:

aws rds wait db-instance-available --db-instance-identifier claude-gateway-db
DB_HOST="$(aws rds describe-db-instances --db-instance-identifier claude-gateway-db \
  --query 'DBInstances[0].Endpoint.Address' --output text)"
GATEWAY_POSTGRES_URL="postgres://gateway:${PGPASS}@${DB_HOST}:5432/claude_gateway?sslmode=verify-full"

sslmode=verify-full membuat gateway memverifikasi rantai dan hostname sertifikat server RDS, tidak hanya mengenkripsi. Trust anchor-nya adalah bundle sertifikat AWS RDS, yang disalin oleh langkah build image di bawah ke /etc/claude/rds-global-bundle.pem dan dipercaya melalui NODE_EXTRA_CA_CERTS. Jangan menambahkan parameter sslrootcert= gaya libpq ke URL: driver gateway hanya membaca sslmode dari query string dan akan meneruskan sslrootcert ke Postgres sebagai parameter startup, yang ditolak oleh server.

Service ECS atau pod EKS harus berjalan di VPC ini agar dapat menjangkau endpoint privat instance, dan security group claude-gateway-db hanya menerima security group gateway.

4. Tulis gateway.yaml

Blok upstreams mengarah ke Bedrock dengan auth: {}, sehingga gateway melakukan autentikasi melalui rantai kredensial default AWS dari task role di ECS atau role IRSA di EKS. Lihat referensi konfigurasi untuk setiap field.

Dua field listen menjelaskan apa yang berada di depan gateway:

  • public_url: origin https:// eksternal, wajib untuk setiap bind non-loopback; lihat referensi listen. Gateway membangun redirect_uri IdP dan dokumen discovery-nya hanya dari nilai ini, tidak pernah dari header X-Forwarded-*.
  • trusted_proxies: rentang sumber front end. Gateway menghormati X-Forwarded-For hanya ketika peer TCP ada dalam daftar ini, lalu menelusuri rantai melewati hop tepercaya, sehingga rate limit login per-IP dan event audit mencatat IP developer alih-alih IP load balancer.

Pada kedua jalur, front end adalah ALB internal, baik dibuat secara langsung maupun oleh AWS Load Balancer Controller, dan node ALB mengambil alamat dari subnet tempat ALB dipasang, jadi atur trusted_proxies ke CIDR subnet tersebut. Ini mempercayai setiap host di subnet tersebut sebagai proxy. Pastikan sumber ingress ALB, yaitu CIDR korporat Anda, tidak tumpang tindih dengannya, dan jangan berbagi subnet dengan workload tidak tepercaya yang dapat memalsukan IP klien melalui X-Forwarded-For.

Atribut preservasi port klien ALB, routing.http.xff_client_port.enabled, dapat dibiarkan pada pengaturan mana pun: jika aktif, ALB menulis klien sebagai 203.0.113.7:54321 atau [2001:db8::1]:54321, dan gateway membaca keduanya dengan port dibuang.

listen:
  host: 0.0.0.0
  port: 8080
  public_url: https://claude-gateway.internal.example.com
  trusted_proxies: [<your-alb-subnet-cidrs>]

oidc:
  issuer: https://example.okta.com
  client_id: 0oa1example2
  client_secret: ${OIDC_CLIENT_SECRET}           # EKS: ${file:/secrets/oidc-client-secret}
  allowed_email_domains: [example.com]
  # The Okta org authorization server returns a thin id_token that omits
  # email and groups; the gateway fills them from /userinfo.
  userinfo_fallback: true
  # Okta emits groups only when the `groups` scope is requested and the
  # app's groups claim filter allows them.
  scopes: [openid, profile, email, offline_access, groups]

session:
  jwt_secret: ${GATEWAY_JWT_SECRET}              # EKS: ${file:/secrets/jwt-secret}
  ttl_hours: 8 # bounds deprovision latency; lower
# toward 1 for tighter revocation

store:
  postgres_url: ${GATEWAY_POSTGRES_URL}          # EKS: ${file:/secrets/postgres-url}
  # readiness_grace_seconds: 300                 # keep passing the health check
# through an RDS failover

upstreams:
  - provider: bedrock
    region: <your-region>                        # match $AWS_REGION so the IAM
# policy's ARNs cover it
    auth: {} # AWS default credential chain:
# ECS task role, or IRSA on EKS

[!NOTE]

Hanya blok oidc yang spesifik untuk Okta. Untuk menggunakan Microsoft Entra ID sebagai gantinya, atur issuer ke https://login.microsoftonline.com/<tenant-id>/v2.0, hapus userinfo_fallback dan scope groups, dan perhatikan bahwa Entra mengeluarkan Object ID grup alih-alih nama, sehingga managed.policies harus dicocokkan pada GUID, atau pada App Roles dengan oidc.groups_claim: roles. Lihat Penyiapan penyedia identitas.

5. Simpan secret di AWS Secrets Manager

Buat tiga secret; execution role dari langkah IAM sudah dapat membacanya:

aws secretsmanager create-secret --name gateway-jwt-secret \
  --secret-string "$(openssl rand -base64 32)"
aws secretsmanager create-secret --name gateway-oidc-client-secret \
  --secret-string '<your-okta-client-secret>'
aws secretsmanager create-secret --name gateway-postgres-url \
  --secret-string "$GATEWAY_POSTGRES_URL"

Catat ARN yang dicetak oleh setiap panggilan; task definition ECS merujuk secret berdasarkan ARN.

[!NOTE]

Argumen literal --secret-string terlihat di tabel proses dan di log audit/EDR selama setiap perintah berjalan. Pada host bersama atau yang dipantau, letakkan nilainya di file 0600 dan berikan --secret-string file://<path> sebagai gantinya. setup.sh milik bundle menjaga nilai secret tetap di luar argv proses dengan cara yang sama, dengan meneruskan file sementara 0600 ke --cli-input-json.

Tidak seperti secret, gateway.yaml itu sendiri tidak berisi nilai rahasia, karena setiap kredensial di-resolve saat boot melalui ekspansi ${VAR} atau ${file:...}. Cara semuanya mencapai container berbeda menurut jalur:

  • Pada ECS, build di langkah berikutnya menyalin gateway.yaml ke dalam image di /etc/claude/gateway.yaml, dan task definition menyuntikkan ketiga secret sebagai environment variable melalui field secrets-nya, sehingga YAML merujuk ${GATEWAY_JWT_SECRET}, ${OIDC_CLIENT_SECRET}, dan ${GATEWAY_POSTGRES_URL}.
  • Pada EKS, mount gateway.yaml dari ConfigMap dan secret sebagai file di /secrets, yang dirujuk sebagai ${file:/secrets/...}. Ambil Kubernetes Secret dari Secrets Manager dengan External Secrets Operator atau provider AWS milik Secrets Store CSI driver, atau buat secara langsung dengan kubectl.

6. Build dan push image ke Amazon ECR

Build image sesuai persyaratan container image, dengan menempatkan binary glibc linux-x64 di ./claude dalam build context. Tulis Dockerfile Anda sendiri sesuai persyaratan tersebut atau mulai dari Dockerfile milik bundle, yang menyalin gateway.yaml yang telah diisi dari langkah-langkah sebelumnya ke dalam image di /etc/claude/gateway.yaml. Pada ECS, salinan tertanam itulah cara konfigurasi mencapai container, itulah sebabnya build dilakukan setelah file ditulis. Jalur EKS sebaliknya me-mount gateway.yaml dari ConfigMap saat deploy, sehingga salinan tertanam tidak digunakan di sana.

Image juga membawa bundle sertifikat AWS RDS sebagai trust anchor untuk sslmode=verify-full pada string koneksi, jadi unduh terlebih dahulu ke dalam build context. AWS merotasi bundle tersebut (CA regional baru ditambahkan), jadi unduh setiap kali build alih-alih mematok checksum atau meng-commit-nya:

curl -fL --proto '=https' -o rds-global-bundle.pem \
  https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem

Persyaratan container image tidak mencakup bundle tersebut, jadi jika Anda menulis Dockerfile sendiri, tambahkan dua baris yang menyalin dan memercayainya; Dockerfile milik bundle sudah menyertakan keduanya:

COPY rds-global-bundle.pem /etc/claude/rds-global-bundle.pem
ENV NODE_EXTRA_CA_CERTS=/etc/claude/rds-global-bundle.pem

Buat repositori ECR dan login-kan Docker ke repositori tersebut. Tag immutable berarti tag <version> yang dipatok oleh langkah deploy tidak dapat kemudian diarahkan ulang secara diam-diam ke image yang berbeda:

aws ecr create-repository --repository-name claude-gateway \
  --image-tag-mutability IMMUTABLE \
  --image-scanning-configuration scanOnPush=true
aws ecr get-login-password --region "$AWS_REGION" \
  | docker login --username AWS --password-stdin \
    "${ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com"

Build dan push image. Task definition di bawah menjalankan linux/amd64, jadi platform harus cocok di sini; untuk Fargate di ARM64 (Graviton), build linux/arm64 dengan binary linux-arm64 dan atur cpuArchitecture ke ARM64 sebagai gantinya:

docker build --platform=linux/amd64 \
  -t "${ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/claude-gateway:<version>" .
docker push "${ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/claude-gateway:<version>"

7. Deploy

[tab] ECS Fargate

Buat cluster dan log group untuk stderr gateway, yang membawa event audit maupun log operasionalnya. Retensi adalah panggilan terpisah, dan tanpanya CloudWatch menyimpan log selamanya; sesuaikan 90 hari tersebut dengan kebijakan retensi audit Anda:

aws ecs create-cluster --cluster-name claude-gateway
aws logs create-log-group --log-group-name /ecs/claude-gateway
aws logs put-retention-policy --log-group-name /ecs/claude-gateway \
  --retention-in-days 90

Tulis task definition. Task role membawa izin Bedrock dan execution role menyuntikkan secret; gunakan ARN secret dari langkah Secrets Manager:

{
  "family": "claude-gateway",
  "networkMode": "awsvpc",
  "requiresCompatibilities": ["FARGATE"],
  "cpu": "1024",
  "memory": "2048",
  "runtimePlatform": { "cpuArchitecture": "X86_64", "operatingSystemFamily": "LINUX" },
  "executionRoleArn": "arn:aws:iam::<account-id>:role/claude-gateway-execution",
  "taskRoleArn": "arn:aws:iam::<account-id>:role/claude-gateway-task",
  "containerDefinitions": [
    {
      "name": "gateway",
      "image": "<account-id>.dkr.ecr.<region>.amazonaws.com/claude-gateway:<version>",
      "portMappings": [{ "containerPort": 8080 }],
      "secrets": [
        { "name": "GATEWAY_JWT_SECRET",   "valueFrom": "<gateway-jwt-secret ARN>" },
        { "name": "OIDC_CLIENT_SECRET",   "valueFrom": "<gateway-oidc-client-secret ARN>" },
        { "name": "GATEWAY_POSTGRES_URL", "valueFrom": "<gateway-postgres-url ARN>" }
      ],
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/claude-gateway",
          "awslogs-region": "<region>",
          "awslogs-stream-prefix": "gateway"
        }
      }
    }
  ]
}

Daftarkan:

aws ecs register-task-definition --cli-input-json file://claude-gateway-task.json

Tempatkan ALB internal di depan dengan target group yang melakukan health check pada gateway. --ip-address-type ipv4 penting: ALB internal dual-stack menerbitkan record AAAA dengan rentang publik, yang ditolak oleh pemeriksaan jaringan privat /login:

ALB_ARN="$(aws elbv2 create-load-balancer --name claude-gateway \
  --scheme internal --type application --ip-address-type ipv4 \
  --subnets $PRIVATE_SUBNETS --security-groups "$ALB_SG" \
  --query 'LoadBalancers[0].LoadBalancerArn' --output text)"

TG_ARN="$(aws elbv2 create-target-group --name claude-gateway \
  --protocol HTTP --port 8080 --vpc-id "$VPC_ID" --target-type ip \
  --health-check-path /readyz \
  --query 'TargetGroups[0].TargetGroupArn' --output text)"

Tambahkan listener HTTPS. --ssl-policy mematok batas bawah TLS yang modern, karena jika dihilangkan akan kembali ke default lama ELBSecurityPolicy-2016-08, yang masih menerima TLS 1.0/1.1.

ALB menutup koneksi setelah 60 detik tanpa data secara default. Ping keepalive gateway menjaga stream tetap berada dalam batas default tersebut, sehingga menaikkan timeout menambah margin di atas frekuensi ping; baris Pemecahan masalah tentang stream yang terputus membahas mekanismenya dan gateway versi lama. Perintah di bawah menambahkan listener dan menaikkan timeout:

aws elbv2 create-listener --load-balancer-arn "$ALB_ARN" \
  --protocol HTTPS --port 443 \
  --ssl-policy ELBSecurityPolicy-TLS13-1-2-2021-06 \
  --certificates CertificateArn=<your-acm-certificate-arn> \
  --default-actions Type=forward,TargetGroupArn="$TG_ARN"

aws elbv2 modify-load-balancer-attributes --load-balancer-arn "$ALB_ARN" \
  --attributes Key=idle_timeout.timeout_seconds,Value=3600

Buat service. Deployment circuit breaker mengembalikan deployment yang task-nya terus gagal, akibat image yang buruk atau konfigurasi yang tidak dapat di-boot, ke kondisi stabil terakhir alih-alih meluncurkan ulang task yang gagal tanpa henti:

aws ecs create-service --cluster claude-gateway --service-name claude-gateway \
  --task-definition claude-gateway --desired-count 1 --launch-type FARGATE \
  --deployment-configuration "deploymentCircuitBreaker={enable=true,rollback=true}" \
  --health-check-grace-period-seconds 60 \
  --network-configuration "awsvpcConfiguration={subnets=[$(echo $PRIVATE_SUBNETS | tr ' ' ',')],securityGroups=[$GW_SG],assignPublicIp=DISABLED}" \
  --load-balancers "targetGroupArn=$TG_ARN,containerName=gateway,containerPort=8080"

Masa tenggang 60 detik memberi task yang baru dimulai waktu untuk menarik image, terhubung ke store, dan menjawab health check pertamanya sebelum ECS mulai menghitung kegagalan terhadap deployment.

Health check target group pada GET /readyz memverifikasi bahwa store dapat dijangkau, sehingga task yang tidak dapat menjangkau Postgres tidak pernah masuk rotasi. Agar task tetap lolos pemeriksaan selama gangguan database singkat seperti failover RDS, atur store.readiness_grace_seconds seperti dijelaskan dalam Perilaku saat gangguan, yang juga membahas alternatif /healthz.

Task berjalan di subnet privat tanpa IP publik, sehingga semua egress (ke Bedrock, IdP Anda, Secrets Manager, ECR, dan CloudWatch Logs) melewati NAT gateway. Agar lalu lintas Bedrock tidak melalui jalur publik, buat interface VPC endpoint bedrock-runtime dan arahkan base_url upstream ke endpoint tersebut, seperti ditunjukkan dalam referensi upstream Bedrock; IdP tetap memerlukan egress internet.

Selesaikan dengan memberikan developer hostname yang dapat di-resolve secara privat: di private hosted zone Route 53, buat alias nama DNS internal gateway ke ALB, dan atur listen.public_url ke hostname tersebut. Nama *.elb.amazonaws.com milik ALB sendiri di-resolve ke alamat privat pada ALB internal, tetapi tidak dapat membawa sertifikat ACM Anda, jadi gunakan nama Anda sendiri.

Perbarui redirect URI yang diotorisasi pada klien OAuth ke <public_url>/oauth/callback sebelum login pertama. Setelah mengubah public_url, build ulang dan push image dengan tag baru, daftarkan revisi task definition baru, dan deploy ulang. Pada ECS, pengaturan tersebut berada di gateway.yaml yang tertanam di image, dan gateway membangun origin publiknya hanya dari pengaturan tersebut, mengabaikan X-Forwarded-Host dan X-Forwarded-Proto. X-Forwarded-For dihormati untuk IP klien hanya ketika listen.trusted_proxies diatur.

[tab] EKS

Jalur ini memerlukan kubectl dan eksctl terinstal secara lokal, serta cluster EKS yang sudah ada dengan IAM OIDC provider dan AWS Load Balancer Controller terinstal. Cluster harus berada di $VPC_ID agar pod dapat menjangkau endpoint privat RDS, dan security group claude-gateway-db harus menerima security group pod atau node milik cluster sebagai pengganti $GW_SG.

Pada EKS, gateway mendapatkan kredensial Bedrock melalui IRSA alih-alih role ECS. Trust policy ecs-tasks.amazonaws.com dari langkah IAM tidak berlaku di sini; IRSA memerlukan role yang trust policy-nya melakukan federasi pada OIDC provider milik cluster, dibatasi ke system:serviceaccount:claude-gateway:gateway. eksctl create iamserviceaccount membuat role tersebut, memasang kebijakan, dan menganotasi service account Kubernetes dengan ARN role dalam satu langkah. Ubah dua dokumen kebijakan dari langkah IAM menjadi managed policy yang dapat dipasangnya:

BEDROCK_POLICY_ARN="$(aws iam create-policy --policy-name claude-gateway-bedrock-invoke \
  --policy-document file://bedrock-invoke.json --query Policy.Arn --output text)"
SECRETS_POLICY_ARN="$(aws iam create-policy --policy-name claude-gateway-secrets-read \
  --policy-document file://secrets-read.json --query Policy.Arn --output text)"

kubectl create namespace claude-gateway
eksctl create iamserviceaccount --cluster <your-cluster> --region "$AWS_REGION" \
  --namespace claude-gateway --name gateway --role-name claude-gateway \
  --attach-policy-arn "$BEDROCK_POLICY_ARN" \
  --attach-policy-arn "$SECRETS_POLICY_ARN" \
  --approve

Kebijakan secret hanya diperlukan ketika pod membaca Secrets Manager sendiri, seperti yang dilakukan provider AWS milik Secrets Store CSI driver menggunakan service account milik pod yang melakukan mount; hapus kebijakan ini jika Anda membuat Kubernetes Secret dengan cara lain. Provider tersebut memerlukan kedua action dalam kebijakan: provider memanggil DescribeSecret saat merekonsiliasi secret yang dirotasi, sehingga grant yang hanya berisi GetSecretValue dapat di-mount pada deploy pertama tetapi berhenti mengambil rotasi.

Deploy gateway sebagai Deployment standar beserta Service dan Ingress, seperti dijelaskan dalam Deployment Kubernetes, dengan:

  • serviceAccountName: gateway
  • gateway.yaml di-mount dari ConfigMap dan secret di-mount di /secrets
  • readiness probe diarahkan ke GET /readyz

Untuk front end, Ingress yang dikelola oleh AWS Load Balancer Controller menyediakan ALB internal. Anotasikan dengan:

  • alb.ingress.kubernetes.io/scheme: internal dan alb.ingress.kubernetes.io/target-type: ip
  • alb.ingress.kubernetes.io/ip-address-type: ipv4, sehingga tidak ada record AAAA dengan rentang publik yang diterbitkan untuk ditolak oleh pemeriksaan jaringan privat /login
  • alb.ingress.kubernetes.io/inbound-cidrs: <your-corporate-cidr>, sehingga security group frontend yang dikelola controller hanya menerima jaringan korporat Anda sebagai pengganti default 0.0.0.0/0-nya
  • alb.ingress.kubernetes.io/certificate-arn dengan sertifikat ACM
  • alb.ingress.kubernetes.io/ssl-policy: ELBSecurityPolicy-TLS13-1-2-2021-06, sehingga listener tidak kembali ke kebijakan default lama yang menerima TLS 1.0 dan 1.1
  • alb.ingress.kubernetes.io/load-balancer-attributes: idle_timeout.timeout_seconds=3600, margin di atas keepalive streaming milik gateway; lihat Pemecahan masalah

Dengan IRSA, AWS SDK membaca token service-account yang diproyeksikan dan menukarnya dengan AWS STS, sehingga pod tidak pernah memerlukan EC2 instance metadata service; NetworkPolicy egress dapat memblokir 169.254.169.254 untuk pod gateway. Masalah hop-limit node di Pemecahan masalah di bawah hanya berlaku untuk cluster yang tidak menggunakan IRSA dan mengandalkan node instance role.

8. Kirim URL gateway ke mesin developer

Gateway kini berjalan, tetapi developer tidak dapat menjangkaunya dari /login sampai URL gateway ada di mesin mereka. Deploy cuplikan pengaturan terkelola secara lengkap, dengan forceLoginMethod, forceLoginGatewayUrl, dan opt-in parentSettingsBehavior: "merge", ke setiap perangkat melalui MDM. Tidak ada opsi gateway di pemilih login yang dapat dipilih developer secara manual.

Referensi Terraform

Bundle pendamping di examples/gateway/aws mengemas halaman ini sebagai kode:

  • setup.sh mengskrip panduan penyediaan di atas dengan perintah aws yang sama, di trek ECS Fargate. Ini adalah idempoten: sumber daya yang ada terdeteksi dan dilewati, jadi menjalankannya kembali aman, dan default apa pun dapat ditimpa melalui variabel lingkungan. Anda masih membuat rahasia klien OIDC Okta dan sertifikat ACM sendiri: jalankan tanpa mereka melewati deploy ECS/ALB, menamai input yang hilang, dan mencetak perintah create-secret; buat keduanya dan jalankan kembali. Formulir kasus penggunaan Bedrock dan alias Route 53 dicetak sebagai langkah berikutnya daripada berjalan secara otomatis, dan push MDM klien tetap menjadi langkah manual dari halaman ini.
  • gateway.yaml.example adalah template konfigurasi dari langkah gateway.yaml, dengan kunci opsional disertakan berkomentar. Salin ke gateway.yaml dan ganti setiap REPLACE_ME sebelum membangun.
  • Dockerfile membangun gambar runtime dari biner linux-x64 yang telah dibangun sebelumnya dan menyalin gateway.yaml yang diisi di /etc/claude/gateway.yaml, ditambah bundel sertifikat AWS RDS yang menambatkan sslmode=verify-full toko. setup.sh mengunduh bundel hanya ketika belum ada dalam konteks build; hapus file dan bangun kembali di bawah tag baru untuk mengambil rotasi CA AWS. File konfigurasi tidak menyimpan nilai rahasia, karena setiap kredensial diselesaikan saat boot melalui ekspansi ${VAR}. Edit konfigurasi oleh karena itu berarti rebuild di bawah tag baru; setup.sh mengotomatisasi ini dengan menandai gambar dengan hash file.
  • terraform/ menyediakan cakupan ECS Fargate yang sama secara deklaratif: grup keamanan, peran IAM, repositori ECR, instans RDS, rahasia Secrets Manager, dan layanan ECS di belakang ALB internal. VPC dan subnet pribadi tetap menjadi prasyarat, dilewatkan sebagai variabel. Terraform membuat repositori ECR tetapi tidak membangun gambar, dan definisi layanan mereferensikan gambar, jadi apply adalah dua pass: apply tertarget untuk repositori, kemudian build dan push, kemudian apply penuh. terraform/README.md bundle mencakup variabel, status jarak jauh, dan teardown.

Seperti halaman ini, bundle adalah contoh yang berfungsi untuk infrastruktur yang dikelola pelanggan daripada deployment produksi yang didukung; tinjau dan sesuaikan dengan lingkungan Anda sendiri sebelum mengandalkannya.

Pemecahan masalah

Untuk error saat boot dan login gateway, lihat tabel pemecahan masalah yang tidak bergantung pada platform. Entri di bawah ini khusus untuk AWS.

Gejala Penyebab Perbaikan
CLI /login: Gateway hosts must be on your organization's private network; <host> resolves to the public (or unrecognized) address <ip> Nama gateway di-resolve ke setidaknya satu alamat publik. ALB internal dual-stack memublikasikan record AAAA dengan rentang publik, dan pemeriksaan jaringan privat mengharuskan setiap alamat hasil resolve bersifat privat Buat ALB dengan --ip-address-type ipv4, atau sajikan nama DNS terpisah yang hanya internal tanpa record AAAA publik
Setiap permintaan Bedrock mengembalikan 502; log menampilkan Could not load credentials from any providers Task berjalan pada launch type ECS EC2 tanpa task role, atau pod berjalan pada node EKS tanpa IRSA, sehingga kredensial berasal dari instance metadata, yang dihentikan di dalam container oleh batas hop default IMDSv2 sebesar 1. Tidak satu pun jalur di halaman ini yang terpengaruh: task role Fargate dan IRSA tidak menggunakan instance metadata Utamakan task role dan IRSA. Jika kredensial instance tidak dapat dihindari, naikkan batas hop dengan aws ec2 modify-instance-metadata-options --instance-id <id> --http-put-response-hop-limit 2; tabel yang tidak bergantung pada platform membahas trade-off-nya
Permintaan Bedrock mengembalikan 403 AccessDeniedException Akun belum mengirimkan formulir kasus penggunaan satu kali dari Anthropic, langganan AWS Marketplace otomatis yang dimulai pada invoke pertama akun belum selesai, atau kebijakan task role tidak mencantumkan ARN inference profile atau foundation model Kirimkan formulir kasus penggunaan dari Model catalog di konsol Bedrock; jika formulir baru saja dikirimkan atau ini adalah invoke pertama akun, coba lagi setelah beberapa menit. Berikan bedrock:InvokeModel dan bedrock:InvokeModelWithResponseStream pada kedua keluarga ARN.
Bedrock mengembalikan ValidationException yang menyatakan throughput on-demand tidak didukung Entri models: kustom dipetakan ke ID foundation model polos yang oleh region hanya dilayani melalui inference profile Petakan model ke ID inference profile lintas region-nya (us.anthropic.*) sebagai gantinya; katalog bawaan sudah melakukan hal ini
Task ECS berhenti dengan ResourceInitializationError sebelum gateway mencatat apa pun ke log Execution role tidak dapat membaca secret Secrets Manager, atau subnet privat tidak memiliki jalur ke Secrets Manager atau ECR Berikan secretsmanager:GetSecretValue pada ARN ketiga secret gateway- kepada execution role, dan sediakan egress melalui NAT gateway, atau, jika tidak ada, interface endpoint untuk Secrets Manager, ECR, dan CloudWatch Logs, yang dibutuhkan driver awslogs pada tahap yang sama, ditambah gateway endpoint S3
Boot gateway keluar dengan error timeout koneksi Postgres Security group database tidak mengizinkan security group gateway pada port 5432, atau service berjalan di luar VPC database Izinkan port 5432 dari security group gateway pada security group database, dan jalankan service di VPC yang sama dengan DB subnet group
Boot gateway keluar dengan error verifikasi sertifikat TLS Postgres Connection string menetapkan sslmode=verify-full tetapi image tidak memercayai bundle CA RDS: bundle tidak disalin ke dalam image, atau NODE_EXTRA_CA_CERTS tidak mengarah ke bundle tersebut Tambahkan dua baris Dockerfile dari langkah build yang menyalin bundle dan menetapkan NODE_EXTRA_CA_CERTS, lalu jalankan build ulang, push dengan tag baru, dan deploy ulang
Respons streaming terputus di tengah stream setelah periode sunyi Gateway yang lebih lama dari v2.1.229 dengan upstream Bedrock atau Claude Platform on AWS tidak mengirim apa pun selama upstream sunyi, misalnya selama extended thinking tanpa output yang di-stream. Secara default, ALB menutup koneksi setelah 60 detik tanpa data, sehingga memotong stream pada jeda tersebut. Gateway v2.1.229 dan yang lebih baru menjaga stream yang sunyi tetap di bawah timeout tersebut: pada upstream tersebut, gateway mengirimkan event SSE ping setelah sekitar 15 detik berlalu tanpa data stream, dan pada upstream Anthropic API, gateway meneruskan ping milik API itu sendiri Perbarui gateway ke v2.1.229 atau yang lebih baru, atau tetapkan atribut idle_timeout.timeout_seconds ke 3600, melalui modify-load-balancer-attributes atau anotasi Ingress load-balancer-attributes di EKS

Telemetry

Gateway memberikan Anda metrik penggunaan per-developer tanpa konfigurasi OTEL per-mesin apa pun. Claude Code memancarkan metrik OpenTelemetry (OTLP), log, dan trace opt-in; Monitoring usage mencakup semua yang dilaporkan CLI. Dalam sesi yang masuk melalui /login, CLI memberi stempel setiap ekspor dengan atribut identitas IdP yang diautentikasi user.id, user.email, dan user.groups, sehingga penggunaan terakumulasi per developer.

Gateway itu sendiri adalah relay OTLP yang diautentikasi. Atur telemetry.forward_to bersama dengan listen.public_url, dan itu mendorong pengaturan OTEL exporter ke setiap klien yang terhubung dan meneruskan lalu lintas OTLP mereka secara verbatim ke setiap tujuan yang Anda daftarkan. Setiap tujuan memilih metrik, log, dan trace secara independen, dan defaultnya hanya metrik; lihat referensi telemetry untuk bidang per-sinyal dan trade-off sensitivitasnya. Gateway tidak membuffer, mengagregasi, atau menyimpan telemetry, jadi tempat data mendarat sepenuhnya merupakan konfigurasi exporter collector.

Telemetry klien dimatikan secara default; mengonfigurasi telemetry.forward_to adalah apa yang mengaktifkannya untuk developer yang terhubung, dan setiap klien interaktif menampilkan dialog persetujuan keamanan untuk pengaturan yang didorong, seperti yang dijelaskan dalam referensi konfigurasi. Di AWS, setiap sinyal memetakan ke tujuan sebagai berikut.

Client metrics, logs, and traces

Arahkan telemetry.forward_to ke kolektor OpenTelemetry, seperti AWS Distro for OpenTelemetry (ADOT) collector, dan ekspor dari sana ke Amazon CloudWatch, Amazon Managed Service for Prometheus, atau backend OTLP apa pun.

Jalankan kolektor sebagai layanan internal tersendiri yang dapat dijangkau melalui https://; referensi telemetry mencakup pengecualian loopback dan CLAUDE_GATEWAY_ALLOW_LOOPBACK.

Gateway logs

Di ECS Fargate, tidak ada setup tambahan: driver awslogs mengirimkan stderr gateway, yang membawa acara audit dan log operasionalnya, ke grup log /ecs/claude-gateway yang dibuat di atas. Di EKS, log pod tidak mencapai CloudWatch secara default, jadi jejak audit hilang sampai Anda memasang pengumpulan log: add-on Amazon CloudWatch Observability dengan penangkapan log kontainer diaktifkan, atau DaemonSet Fluent Bit. Di kedua jalur, kueri log dengan CloudWatch Logs Insights dan jalankan alarm dari filter metrik.

Container metrics

Aktifkan Container Insights pada kluster dengan aws ecs update-cluster-settings --cluster claude-gateway --settings name=containerInsights,value=enabled untuk CPU per-task, memori, dan jaringan. Di EKS, pasang add-on Amazon CloudWatch Observability.

Spend

Telemetry menunjukkan penggunaan setelah fakta; spend limits adalah tampilan dan penegakan per-developer live gateway.

Atribusi biaya

Gateway menandatangani setiap permintaan Bedrock dengan principal-nya sendiri, peran tugas ECS atau peran IRSA EKS, jadi secara default AWS melihat semua pengeluaran itu di bawah satu principal IAM. Ada dua cara untuk membaginya dalam data penagihan AWS sendiri, dan keduanya dapat digabungkan.

Per pengembang dengan assume_role

Buat peran IAM kedua yang memegang izin Bedrock dan mempercayai principal gateway, berikan principal itu sts:AssumeRole padanya, dan atur assume_role dengan session_name: email pada upstream Bedrock. Gateway kemudian mengasumsikan peran itu sekali per pengembang per jam dengan nama sesi diatur ke email mereka dan menandatangani permintaan mereka dengan hasilnya. Memerlukan gateway yang menjalankan Claude Code v2.1.281 atau lebih baru. Peran juga dapat berada di akun AWS lain: lihat Bedrock di akun AWS lain. Di Terraform, di sebelah peran tugas dalam bundle Terraform:

resource "aws_iam_role" "bedrock_user" {
  name = "claude-gateway-bedrock-user"
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{ Effect = "Allow", Action = "sts:AssumeRole", Principal = { AWS = aws_iam_role.task.arn } }]
  })
}
resource "aws_iam_role_policy" "bedrock_user_invoke" {   # same Bedrock policy as the task role's
  role   = aws_iam_role.bedrock_user.id
  policy = aws_iam_role_policy.bedrock_invoke.policy
}
resource "aws_iam_role_policy" "task_assume_bedrock_user" {
  role   = aws_iam_role.task.id
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{ Effect = "Allow", Action = "sts:AssumeRole", Resource = aws_iam_role.bedrock_user.arn }]
  })
}

Dengan assume_role yang diatur, gateway menandatangani setiap panggilan Bedrock, panggilan CountTokens gratis untuk pengukuran pengeluaran yang disertakan, dengan kredensial peran yang diasumsikan, jadi principal gateway hanya memerlukan kebijakan Bedrock sendiri untuk upstream tanpa assume_role.

Karena gateway memanggil STS pada waktu permintaan, subnet pribadi memerlukan jalur ke sts.<region>.amazonaws.com. NAT gateway dari prasyarat menyediakan satu, dan begitu juga endpoint VPC antarmuka STS yang menjawab untuk nama host itu. Setiap pengembang aktif memerlukan satu panggilan STS per jam per replika gateway.

Permintaan setiap pengembang mencapai AWS sebagai principal arn:aws:sts::<account>:assumed-role/<role>/<email>. Untuk melihat pengeluaran per principal, gunakan ekspor penagihan yang mencakup data principal IAM; halaman alokasi biaya principal IAM AWS mencakup cara mengaktifkannya dan alat penagihan mana yang menampilkannya.

Per tim dengan profil inferensi aplikasi

Rute ini hanya menggunakan bagian models dan managed. Buat satu profil inferensi aplikasi Bedrock per tim dan model, tandai setiap profil dengan tim, dan aktifkan tag itu sebagai tag alokasi biaya. Kemudian berikan setiap tim id model-nya sendiri di gateway.yaml dan pin setiap grup IdP ke id tim-nya:

models:
  # Include the served model's id, such as claude-opus-4-8, in each id so the gateway's spend meter can price it.
  - id: platform-claude-opus-4-8
    upstream_model:
      bedrock: arn:aws:bedrock:us-east-1:123456789012:application-inference-profile/abc123
  - id: data-claude-opus-4-8
    upstream_model:
      bedrock: arn:aws:bedrock:us-east-1:123456789012:application-inference-profile/def456
managed:
  policies:
    - match: {groups: [team-platform]}
      cli: {availableModels: [platform-claude-opus-4-8], enforceAvailableModels: true}
    - match: {groups: [team-data]}
      cli: {availableModels: [data-claude-opus-4-8], enforceAvailableModels: true}
    - match: {}
      cli: {availableModels: [claude-opus-4-8, claude-sonnet-4-6], enforceAvailableModels: true}

Beritahu pengembang dalam tim yang dipasang untuk memulai Claude Code dengan --model platform-claude-opus-4-8, menggunakan id tim mereka, karena sesi yang dimulai tanpanya menjalankan model default, yang gateway tolak untuk mereka.

Gateway memberlakukan availableModels pada setiap permintaan, bukan hanya di pemilih model, dan penagihan AWS mengelompokkan pengeluaran berdasarkan tag yang Anda aktifkan. Tanpa catch-all match: {}, pengembang yang tidak cocok dengan kebijakan apa pun mendapatkan setiap model dalam katalog dan dapat menagih profil tim mana pun.

Biayanya:

  • Konfigurasi tumbuh dengan tim kali model
  • Peran yang menandatangani permintaan Bedrock upstream ini juga harus diizinkan untuk memanggil ARN application-inference-profile/*. Peran itu adalah principal gateway, atau dengan assume_role peran yang diasumsikannya.

Lihat Cara permintaan diberi harga untuk cara meter pengeluaran gateway sendiri menentukan harga id ini.

Izinkan pengembang memilih tim yang akan ditagih

Untuk mengizinkan pengembang yang bekerja untuk dua tim memilih tim mana yang ditagih oleh setiap sesi, berikan pasangan tim tersebut grup IdP dan kebijakannya sendiri.

1. Tambahkan grup untuk pasangan tersebut

Di IdP Anda, tambahkan pengembang ke grup baru, seperti team-platform-and-data. Jika mereka sudah masuk, minta mereka menjalankan /login lagi, atau tunggu penyegaran senyap berikutnya, agar gateway melihat grup baru tersebut.

2. Cantumkan kebijakannya terlebih dahulu

Letakkan kebijakan grup tersebut di atas kebijakan tim tunggal dan izinkan id kedua tim di dalamnya. Salin juga pengaturan lain yang ditetapkan oleh kedua kebijakan tim.

managed:
  policies:
    - match: {groups: [team-platform-and-data]}
      cli: {availableModels: [platform-claude-opus-4-8, data-claude-opus-4-8], enforceAvailableModels: true}
    - match: {groups: [team-platform]}
      cli: {availableModels: [platform-claude-opus-4-8], enforceAvailableModels: true}
    - match: {groups: [team-data]}
      cli: {availableModels: [data-claude-opus-4-8], enforceAvailableModels: true}
    - match: {}
      cli: {availableModels: [claude-opus-4-8, claude-sonnet-4-6], enforceAvailableModels: true}

3. Mulai setiap sesi dengan id tim

Minta pengembang memberikan id tim tempat pekerjaan tersebut dilakukan, seperti claude --model data-claude-opus-4-8.

Secara default, gateway menerapkan kebijakan pertama yang cocok, jadi pengembang yang hanya berada di dua grup tim mendapatkan kebijakan team-platform. Sesi mereka dengan id tim data gagal dengan is not in your role's availableModels allowlist, yang menyebutkan model default Claude Code dan bukan id yang mereka ketik. Jika Anda justru mencantumkan kedua grup tim dalam groups satu kebijakan, semua orang di kedua tim dapat menagih profil tim mana pun.

Dalam batas pengeluaran gateway sendiri, pengembang memiliki satu total dan satu batas per periode, secara default batas terendah dari grup-grup mereka, id mana pun yang digunakan sesi. Agar batas yang lebih rendah dari satu tim tidak menghentikan pekerjaan untuk tim lainnya, atur batas per pengguna untuk pengembang tersebut.

Langkah berikutnya