SpyBara
Go Premium

claude-apps-gateway-deploy.md 2026-07-15 22:00 UTC to 2026-07-16 22:59 UTC

4 added, 2 removed.

2026
Sat 18 16:02 Fri 17 22:57 Thu 16 22:59 Wed 15 22:00 Tue 14 23:01 Mon 13 23:57 Sat 11 19:03 Fri 10 17:00 Thu 9 23:58 Wed 8 16:02 Tue 7 16:02 Mon 6 23:57 Sat 4 03:01 Fri 3 23:00 Thu 2 23:59 Wed 1 21:01

Claude ์•ฑ ๊ฒŒ์ดํŠธ์›จ์ด ๋ฐฐํฌ ๋ฐ ์šด์˜

IdP์— ๊ฒŒ์ดํŠธ์›จ์ด๋ฅผ ๋“ฑ๋กํ•˜๊ณ , ์ปจํ…Œ์ด๋„ˆ๋ฅผ ๋นŒ๋“œํ•˜๋ฉฐ, Kubernetes ๋˜๋Š” Cloud Run์— ๋ฐฐํฌํ•˜๊ณ  ์šด์˜ํ•ฉ๋‹ˆ๋‹ค: ์ƒํƒœ ํ™•์ธ, ์‹œํฌ๋ฆฟ ๋กœํ…Œ์ด์…˜, ์—…๊ทธ๋ ˆ์ด๋“œ ๋ฐ ๋ณด์•ˆ.

์ด ํŽ˜์ด์ง€๋Š” Claude ์•ฑ ๊ฒŒ์ดํŠธ์›จ์ด ์‹คํ–‰์˜ ์šด์˜ ์ธก๋ฉด์„ ๋‹ค๋ฃน๋‹ˆ๋‹ค: ๊ฒŒ์ดํŠธ์›จ์ด๋ฅผ ID ๊ณต๊ธ‰์ž(IdP)์— ๋“ฑ๋กํ•˜๊ณ , ๊ฒŒ์ดํŠธ์›จ์ด๋ฅผ ์ปจํ…Œ์ด๋„ˆ๋กœ ๋ฐฐํฌํ•˜๋ฉฐ, ์ผ์ƒ์ ์œผ๋กœ ์šด์˜ํ•ฉ๋‹ˆ๋‹ค. ๊ฒŒ์ดํŠธ์›จ์ด๊ฐ€ ๋ถ€ํŒ… ์‹œ ์ฝ๋Š” gateway.yaml ํŒŒ์ผ์˜ ๋ชจ๋“  ์˜ต์…˜์— ๋Œ€ํ•ด์„œ๋Š” ๊ตฌ์„ฑ ์ฐธ์กฐ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

ํ”„๋กœ๋•์…˜ ๋ฐฐํฌ๋Š” ์ˆœ์„œ๋Œ€๋กœ 4๋‹จ๊ณ„๋ฅผ ๋”ฐ๋ฅด๋ฉฐ, ์•„๋ž˜ ์„น์…˜์ด ์ด๋ฅผ ์ผ์น˜์‹œํ‚ต๋‹ˆ๋‹ค. ์ฒ˜์Œ ๋‘ ๋‹จ๊ณ„๋Š” ์„ ํƒ์„ ํ•˜๋Š” ๊ณณ์ด๊ณ , ๋‚˜๋จธ์ง€ ๋‘ ๋‹จ๊ณ„๋Š” ์‹คํ–‰ ์ค‘์ผ ๋•Œ ์ฐธ์กฐํ•  ์ฐธ๊ณ  ์ž๋ฃŒ์ž…๋‹ˆ๋‹ค.

  1. ID ๊ณต๊ธ‰์ž ์„ค์ •: OAuth ํด๋ผ์ด์–ธํŠธ๋ฅผ ๋“ฑ๋กํ•˜๊ณ  Okta, Entra, Google์— ๋Œ€ํ•œ IdP๋ณ„ ์ฐธ๊ณ ์‚ฌํ•ญ ํ™•์ธ
  2. ๊ฒŒ์ดํŠธ์›จ์ด ๋ฐฐํฌ: ๊ณ ์ •๋œ ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€๋ฅผ ๋นŒ๋“œํ•˜๊ณ  Kubernetes, Cloud Run ๋˜๋Š” ์ž์‹ ์˜ ํ”Œ๋žซํผ์—์„œ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ด ์„น์…˜์€ ๋น„์šฉ, ์šฐํšŒ, ๋‹ค์ค‘ ๊ฒŒ์ดํŠธ์›จ์ด ๋ฐ ์„œ๋ฒ„๋ฆฌ์Šค ๊ฒฐ์ •๋„ ๋‹ค๋ฃน๋‹ˆ๋‹ค
  3. ์šด์˜ ์„ค์ •: ๋กœ๊ทธ, ์ƒํƒœ ํ”„๋กœ๋ธŒ, ์ค‘๋‹จ ๋™์ž‘, ์‹œํฌ๋ฆฟ ๋กœํ…Œ์ด์…˜ ๋ฐ ์—…๊ทธ๋ ˆ์ด๋“œ. ๋ชจ๋‹ˆํ„ฐ๋ง ๋ฐ ๋Ÿฐ๋ถ์„ ์—ฐ๊ฒฐํ•  ๋•Œ ์ฐธ์กฐํ•  ์ฐธ๊ณ  ์ž๋ฃŒ
  4. ๋ณด์•ˆ ํƒœ์„ธ ๊ฒ€ํ† : ๋ฐ์ดํ„ฐ๊ฐ€ ์–ด๋””๋กœ ํ๋ฅด๋Š”์ง€, ์œ„ํ˜‘ ๋ชจ๋ธ ๋ฐ ๊ทœ์ • ์ค€์ˆ˜ ๋‹ต๋ณ€. ๋ณด์•ˆ ๊ฒ€ํ† ๋ฅผ ์œ„ํ•œ ์ฐธ๊ณ  ์ž๋ฃŒ

๋กœ๊ทธ์ธ ๋˜๋Š” ๋ถ€ํŒ…์ด ์‹คํŒจํ•˜๋ฉด ๋ฌธ์ œ ํ•ด๊ฒฐ๋กœ ๋ฐ”๋กœ ์ด๋™ํ•˜์„ธ์š”. ์ด๋Š” ํ‘œ์‹œ๋˜๋Š” ์˜ค๋ฅ˜๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

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์˜ ์กฐ์ง ์ธ์ฆ ์„œ๋ฒ„๋Š” email ๋ฐ groups๋ฅผ ์ƒ๋žตํ•˜๋Š” ์–‡์€ 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 ๊ณต๊ธ‰์ž์— ๋Œ€ํ•œ ์ง€์›์€ ๋ฌธ์ œ ํ•ด๊ฒฐ์„ ์ฐธ์กฐํ•˜์„ธ์š”.

๋ฐฐํฌ

๊ฒŒ์ดํŠธ์›จ์ด๋Š” ๋‹จ์ผ 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๋กœ ์ง€์ •ํ•˜์„ธ์š”

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์„ ์„ค์ •ํ•˜์„ธ์š”

๊ฒŒ์ดํŠธ์›จ์ด URL์„ ๊ฐœ๋ฐœ์ž ๋จธ์‹ ์œผ๋กœ ํ‘ธ์‹œ

๊ฒŒ์ดํŠธ์›จ์ด๊ฐ€ ์ œ๊ณต๋˜๋ฉด, MDM์„ ํ†ตํ•ด ๋˜๋Š” OS๋ณ„ managed-settings.json์„ ์ง์ ‘ ์ž‘์„ฑํ•˜์—ฌ ๊ด€๋ฆฌํ˜• ์„ค์ •์„ ํ†ตํ•ด ๊ฐ ๊ฐœ๋ฐœ์ž์˜ ๋จธ์‹ ์œผ๋กœ forceLoginMethod ๋ฐ forceLoginGatewayUrl์„ ํ‘ธ์‹œํ•˜์„ธ์š”. ์ด ์—†์ด๋Š” /login์ด ๊ฒŒ์ดํŠธ์›จ์ด ์˜ต์…˜์ด ์—†๋Š” ํ‘œ์ค€ ๊ณ„์ • ์„ ํƒ๊ธฐ๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ํŒŒ์ผ ๊ฒฝ๋กœ๋Š” ํด๋ผ์ด์–ธํŠธ ์ธก ๊ด€๋ฆฌํ˜• ์„ค์ •์„ ์ฐธ์กฐํ•˜์„ธ์š”.

์šด์˜

๊ฒŒ์ดํŠธ์›จ์ด๊ฐ€ ํŠธ๋ž˜ํ”ฝ์„ ์ œ๊ณตํ•˜๋ฉด, ์ผ์ƒ์ ์ธ ์šด์˜์€ ๋กœ๊ทธ๋ฅผ ์ฝ๊ณ , ์ƒํƒœ๋ฅผ ํ”„๋กœ๋ธŒํ•˜๋ฉฐ, ์ผ์ •์— ๋”ฐ๋ผ ์‹œํฌ๋ฆฟ์„ ๋กœํ…Œ์ด์…˜ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์•„๋ž˜ ์„น์…˜์€ ๊ฐ๊ฐ์„ ๋‹ค๋ฃจ๊ณ , Postgres๊ฐ€ ๋ณด์œ ํ•œ ๊ฒƒ๊ณผ ์—…๊ทธ๋ ˆ์ด๋“œ ๋ฐ ๋กค๋ฐฑ์ด ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š”์ง€๋ฅผ ๋‹ค๋ฃน๋‹ˆ๋‹ค.

๋กœ๊ทธ

๊ฒŒ์ดํŠธ์›จ์ด๋Š” stderr์— ๋‘ ๊ฐœ์˜ ์ŠคํŠธ๋ฆผ์„ ์ž‘์„ฑํ•˜๋ฉฐ, ๋‘˜ ๋‹ค JSON ์นœํ™”์ ์ž…๋‹ˆ๋‹ค:

  • ๊ฐ์‚ฌ ์ด๋ฒคํŠธ: ๋ณด์•ˆ ๊ด€๋ จ ์ด๋ฒคํŠธ๋‹น ํ•œ ์ค„์˜ JSON. stderr๋ฅผ ๋กœ๊ทธ ์ˆ˜์ง‘๊ธฐ๋กœ ํŒŒ์ดํ”„ํ•˜์„ธ์š”. ๋‚ด๋ณด๋‚ธ ์ด๋ฒคํŠธ๋Š” config.load, session.mint, session.refresh, device.authorize, device.verify, auth.denied, access.denied, inference, managed.serve, spend.blocked ๋ฐ admin.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>'์„ ์ง์ ‘ ์‹คํ–‰ํ•˜์„ธ์š”. ์ด๋Š” ์ด๋ฉ”์ผ, ์ด๋ฆ„ ๋ฐ ๊ทธ๋ฃน์„ ๋ณด์œ ํ•˜๋Š” ์œ ์ผํ•œ ํ…Œ์ด๋ธ”์„ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค. spend ๋ฐ admin_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=1 ๋ฐ skipWebFetchPreflight: true๊ฐ€ ์„ค์ •๋˜์ง€ ์•Š์œผ๋ฉด ์—ฌ์ „ํžˆ WebFetch ํ˜ธ์ŠคํŠธ๋ช… ํ™•์ธ ๋ฐ ๋ฒ„์ „ ํ™•์ธ์„ Anthropic์œผ๋กœ ๋ณด๋ƒ…๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ ์‚ฌ์šฉ์„ ์ฐธ์กฐํ•˜์„ธ์š”.
  • ์„ค๋ฌธ ์กฐ์‚ฌ ํ‰๊ฐ€: ๊ฒŒ์ดํŠธ์›จ์ด ์ž๊ฒฉ ์ฆ๋ช…์€ Anthropic ๋ฐ”์šด๋“œ ํ‰๊ฐ€ ์‹ฑํฌ๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•˜๋ฏ€๋กœ ํ‰๊ฐ€๋Š” Anthropic์œผ๋กœ ์ „์†ก๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ํŠธ๋žœ์Šคํฌ๋ฆฝํŠธ ๊ณต์œ : ์„ค๋ฌธ ์กฐ์‚ฌ์˜ ํŠธ๋žœ์Šคํฌ๋ฆฝํŠธ ๊ณต์œ  ํ”„๋กฌํ”„ํŠธ์—์„œ ์˜ˆ๋ฅผ ์„ ํƒํ•˜๋ฉด Anthropic์œผ๋กœ ์—…๋กœ๋“œํ•˜๋Š” ๋Œ€์‹  ~/.claude/feedback-bundles/ ์•„๋ž˜์˜ ๋กœ์ปฌ ํŒŒ์ผ์„ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.
  • ํด๋ผ์ด์–ธํŠธ ์—…๋ฐ์ดํŠธ: ์—…๋ฐ์ดํŠธ ํ™•์ธ์€ ๊ฒŒ์ดํŠธ์›จ์ด ํŠธ๋ž˜ํ”ฝ๊ณผ ๋ณ„๊ฐœ์ž…๋‹ˆ๋‹ค. ์ž์‹ ์˜ ๋ฐฐํฌ๋ฅผ ํ†ตํ•ด ๋ฒ„์ „์„ ๊ณ ์ •ํ•˜๊ณ  ๋…ธํŠธ๋ถ์ด ๋ฆด๋ฆฌ์Šค๋ฅผ ๊ฐ€์ ธ์˜ค๋ฉด ์•ˆ ๋˜๋ฉด DISABLE_UPDATES๋ฅผ ์„ค์ •ํ•˜์„ธ์š”. DISABLE_AUTOUPDATER๋Š” claude 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/settings์˜ x-cc-gateway-version ์‘๋‹ต ํ—ค๋”์— ํ‘œ์‹œ๋จ), ์ตœ๊ทผ์— ๋ณ€๊ฒฝ๋œ ๊ฒƒ
  • ๋กœ๊ทธ์ธ ๋ฌธ์ œ: ๊ฐœ๋ฐœ์ž๋Š” claude --debug-file ./claude-debug.txt๋ฅผ ์‹คํ–‰ํ•˜๊ณ , ์žฌํ˜„ํ•˜๋ฉฐ, ํ•ด๋‹น ํŒŒ์ผ๊ณผ ๋™์ผํ•œ ์ฐฝ์˜ ๊ฒŒ์ดํŠธ์›จ์ด ๊ฐ์‚ฌ ๋กœ๊ทธ๋ฅผ ๋ณด๋ƒ…๋‹ˆ๋‹ค
  • ์ถ”๋ก  ๋ฌธ์ œ: ์š”์ฒญ๋œ ๋ชจ๋ธ, ๊ตฌ์„ฑ๋œ ์—…์ŠคํŠธ๋ฆผ, ์š”์ฒญ์˜ ๊ฒŒ์ดํŠธ์›จ์ด ๊ฐ์‚ฌ ๋กœ๊ทธ(์–ด๋А ์—…์ŠคํŠธ๋ฆผ์ด ์ œ๊ณตํ–ˆ๋Š”์ง€ ๋ฐ ์‘๋‹ต ์ƒํƒœ๋ฅผ ๊ธฐ๋กํ•จ)
์ฆ์ƒ ์›์ธ ์ˆ˜์ •
๊ฐœ๋ฐœ์ž์˜ /login์ด Cloud ๊ฒŒ์ดํŠธ์›จ์ด ํ™”๋ฉด ๋Œ€์‹  ํ‘œ์ค€ ๊ณ„์ • ์„ ํƒ๊ธฐ๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค 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 ์ฃผ์†Œ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. Anthropic์ด ์šด์˜ํ•˜๋Š” ๊ณต๊ฐœ ๊ฒŒ์ดํŠธ์›จ์ด ์—”๋“œํฌ์ธํŠธ๋Š” ํ™•์ธ์—์„œ ์ œ์™ธ๋˜๋ฉฐ, /login์€ https://๋ฅผ ํ†ตํ•ด ์ด๋“ค์„ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค. v2.1.206 ์ด์ „์—๋Š” /login์ด ๋‹ค๋ฅธ ๊ณต๊ฐœ ์ฃผ์†Œ์ฒ˜๋Ÿผ ์ด๋“ค์„ ๊ฑฐ๋ถ€ํ–ˆ์Šต๋‹ˆ๋‹ค ๊ฒŒ์ดํŠธ์›จ์ด ์ด๋ฆ„์ด ๊ฐœ๋ฐœ์ž ๋จธ์‹ ์—์„œ ํ”„๋ผ์ด๋น— ์ฃผ์†Œ๋กœ๋งŒ ํ™•์ธ๋˜๋„๋ก ํ•˜์„ธ์š”. ์ด์ค‘ ์Šคํƒ ์ด๋ฆ„์˜ ๊ฒฝ์šฐ ๊ณต๊ฐœ ๋ฒ”์œ„ ๋ ˆ์ฝ”๋“œ๋ฅผ ์‚ญ์ œํ•˜๊ฑฐ๋‚˜ ๋ณ„๋„์˜ ๋‚ด๋ถ€ ์ „์šฉ DNS ์ด๋ฆ„์„ ์ œ๊ณตํ•˜์„ธ์š”. ํ”„๋ผ์ด๋น— ๋„คํŠธ์›Œํฌ ์ „์ œ์กฐ๊ฑด์„ ์ฐธ์กฐํ•˜์„ธ์š”.
CLI /login: Gateway login requires a direct connection and does not support connecting through an HTTP proxy HTTPS_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 binary Node ๋Œ€์‹  ๋„ค์ดํ‹ฐ๋ธŒ ๋ฐ”์ด๋„ˆ๋ฆฌ์—์„œ ์‹คํ–‰ ์ค‘์ž…๋‹ˆ๋‹ค ๋…๋ฆฝ ์‹คํ–‰ํ˜• ์„ค์น˜ ๋ฐฉ๋ฒ• ์ค‘ ํ•˜๋‚˜๋กœ 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 claim IdP๊ฐ€ ๊ธฐ๋ณธ์ ์œผ๋กœ 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๋ฅผ ์„ค์ •ํ•˜์„ธ์š”.
๋ชจ๋“  Amazon 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 scope IdP๊ฐ€ ์ธ์‹ํ•˜์ง€ ๋ชปํ•˜๋Š” ๋ฒ”์œ„๋ฅผ ๊ฑฐ๋ถ€ํ•ฉ๋‹ˆ๋‹ค 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์œผ๋กœ ์„ค์ •ํ•˜์„ธ์š”. ์ฒซ ์—ฐ๊ฒฐ ์ง€๋ฌธ ํ”„๋กฌํ”„ํŠธ๋Š” ์—ฌ์ „ํžˆ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค.