์ธ์ฆยท์ธ๊ฐ, ์ํฌ๋ฆฟ, ๋คํธ์ํฌ, ๋ชจ๋ธ ์ ๋ ฅ๊ณผ ์ ์ฅ ๋ฐ์ดํฐ์ ๋ณด์ ๊ฒฝ๊ณ๋ฅผ ์ค๋ช ํ๋ค. ์ค์ ๋ง์ผ๋ก ๋ณด์ฅํ๋ ๊ฒ๊ณผ ๋ฐฐํฌ ํ๊ฒฝ์ด ์ฑ ์์ง๋ ๊ฒ์ ๊ตฌ๋ถํ๋ค.
๊ด๋ จ ๋ฌธ์: ์ฌ๊ธฐ์ ์ธ๊ธํ๋ ๋ณ์๋ CONFIGURATION.md, ์๋ํฌ์ธํธ๋ณ ์ธ๊ฐ๋ API.md, ์กฐ๊ฐ๋ค์ด ์ด๋ป๊ฒ ๋ง๋ฌผ๋ฆฌ๋์ง๋ ARCHITECTURE.md.
Better Auth์ advanced.cookiePrefix๋ agent-studio๋ค. ๊ธฐ๋ณธ ์ธ์
์ฟ ํค๋
agent-studio.session_token์ด๋ฉฐ HTTPS ์ค์ ์์๋ __Secure-๊ฐ ๋ถ๋๋ค. ํ์ด์ง ๊ฒ์ดํธ๋ ๊ฐ์
์ ๋์ด๋ฅผ ์ฌ์ฉํ๋ค. Agent Memory์ agent-memory ์ฟ ํค์ ๋ถ๋ฆฌํ๋ฉฐ ์ด์ better-auth ์ฟ ํค๋
์ฝ์ง ์๋๋ค. ์ ๋์ด ๋ณ๊ฒฝ์ ๋ฐฐํฌํ๋ฉด ๊ธฐ์กด ๋ธ๋ผ์ฐ์ ์ธ์
์ ๋ค์ ๋ก๊ทธ์ธํด์ผ ํ๋ค.
๋ฉํฐ ๋๋ฉ์ธ ๋ก๊ทธ์ธ์ BETTER_AUTH_ALLOWED_HOSTS์ ์ ํํ ํธ์คํธ๋ง ํ์ฉํ๋ค.
config.authBaseUrl์ด BETTER_AUTH_URL์ ํ๋กํ ์ฝ๊ณผ ํ์ฉ ๋ชฉ๋ก์ Better Auth์ ์ ๋ฌํ๊ณ ,
์์ฒญ์ ๋ณด์กด๋ Host(์์ผ๋ฉด request URL)๋ก ์ฝ๋ฐฑ์ ๊ฒฐ์ ํ๋ค. ์ ๋ฌ๋ ํธ์คํธยทํ๋กํ ์ฝ ํค๋๋
์ ๋ขฐํ์ง ์๋๋ค. ์ธ์
ยทOAuth state ์ฟ ํค๋ host-only์ด๋ฉฐ HTTPS์ด๋ฉด Secure๋ค. ๋ก๊ทธ์ธ ์คํจ์
์๋ Location: /login?error=๋ ์ฝ๋ฐฑ ๋๋ฉ์ธ์ ์ ์งํ๋ค. ์ค์ ยทprovider ๋ฑ๋ก์
์ค์น ์ ์ฐจ๋ฅผ ๋ฐ๋ฅธ๋ค.
Better Auth 1.7์ ์ฑ์ ์ปค๋ฅ์
ํ ์์์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์์ ์ Postgres ์ด๋ํฐ๋ก ๋๋ค.
user, session, account, verification ์ ๊ทธ๊ฒ์ด ์์ ํ๋ ํ
์ด๋ธ์ด๊ณ (migrations.ts ๊ฐ
๋ง๋ ๋ค), emailยทtoken ์ ์ ์ผ์ฑ์ ํ
์ด๋ธ์ ์ ๋ํฌ ์ ์ฝ์ด๋ค.
๊ณ์ ์ ์๋ณ์๋ providerId + accountId์ด๋ฉฐ ์ด ์กฐํฉ์ unique index๋ฅผ ๋๋ค. issuer๋
๊ธฐ์กด ๊ฐ์ ๋ณด์กดํ๋ nullable ์ด๋ ฅ ์ปฌ๋ผ์ด๊ณ ์ ๊ณ์ ์๋ ์ฐ์ง ์๋๋ค. ๊ฐ์ ๊ณ์ ํค์ ์ค๋ณต์
unique index๊ฐ ๊ฑฐ๋ถํ๋ค. ์๋ก ๋ค๋ฅธ ์ฌ์ฉ์๋ฅผ ์๋ ๋ณํฉํ๊ฑฐ๋ provider๋ฅผ ์์๋ก ๋ฐ๊พธ์ง ์๋๋ค.
๋ก๊ทธ์ธ ์๋จ์ ์ ๋ถ ์ ํ์ด๊ณ ์ค์น๊ฐ ๊ณ ๋ฅธ๋ค (src/lib/config.ts ์ authProviders,
๊ทธ๋๋ก auth.ts ์ ๋ก๊ทธ์ธ ํ์ด์ง๋ก):
| ์๋จ | ์ผ๋ ๊ฒ | ์ฑ์ง |
|---|---|---|
| Keycloak | KEYCLOAK_ISSUER + KEYCLOAK_CLIENT_ID + KEYCLOAK_CLIENT_SECRET |
Better Auth์ Keycloak helper์ genericOAuth๋ก discovery๋ฅผ ์ฝ๊ณ PKCE(S256)๋ฅผ ์ด๋ค. ์ฝ๋ฐฑ /api/auth/callback/keycloak |
| ํ์ค OIDC | OIDC_ISSUER + OIDC_CLIENT_ID + OIDC_CLIENT_SECRET |
genericOAuth๋ก discovery ๋ฌธ์์์ ์ฐพ๊ณ PKCE๋ฅผ ์ด๋ค. ์ฝ๋ฐฑ /api/auth/callback/oidc |
GOOGLE_CLIENT_ID + GOOGLE_CLIENT_SECRET |
์ฝ๋ฐฑ /api/auth/callback/google |
|
| ์ด๋ฉ์ผ + ๋น๋ฐ๋ฒํธ | AUTH_PASSWORD=true |
๊ฐ์
ํผ์ด ์๋ค(disableSignUp): ์ ์ ์ ๊ณต์๊ฐ ๋ณด์ฆํ๋ ์ฌ๋์ ์ฒซ ๋ก๊ทธ์ธ์ผ๋ก ์ฌ์ฉ์๊ฐ ๋์ง๋ง, ๋น๋ฐ๋ฒํธ ๊ณ์ ์ ์๋ฌด๋ ๋ณด์ฆํ์ง ์์ผ๋ฏ๋ก ๋ถํธ์คํธ๋ฉ ๊ด๋ฆฌ์(BOOTSTRAP_ADMIN_EMAIL/PASSWORD, ๋ถํ
๋ ํ ๋ฒ)์ ๊ด๋ฆฌ์๊ฐ ์๋์ ์ผ๋ก ๋ง๋ ๊ณ์ ๋ฟ์ด๋ค. ์ฒซ ๊ด๋ฆฌ์์ ์ ๊ณต์๊ฐ ์ฃฝ์์ ๋์ ๋น์ ์ ๊ทผ์ฉ์ด๋ค |
Keycloakยทํ์ค OIDCยทGoogle์ ํจ๊ป ์ค์ ํ๋ฉด ๊ฐ ๋ก๊ทธ์ธ ๋ฒํผ์ ํ์ํ๋ค. Keycloak์ discovery์ issuerยทJWKS๊ฐ ์์ด์ผ ๋ฑ๋กํ๋ฉฐ ID ํ ํฐ์ ์๋ช ยทissuerยทaudience์ ์์ฒญ๋ณ nonce๋ฅผ Better Auth๊ฐ ๊ฒ์ฆํ๋ค. ๋ก๊ทธ์ธ ๋ฒํผ์ ์ค์ ์ ์กด์ฌ๋ฅผ ๋ํ๋ด๋ฏ๋ก discovery ์คํจ ์์๋ ํ์๋์ง๋ง ์ธ์ฆ์ ์คํจํ๋ค. ์ ๊ณต์ ๋ณต๊ตฌ ๋ค ์ฑ์ ์ฌ์์ํด discovery๋ฅผ ๋ค์ ์ฝ๋๋ค. Keycloak issuer๋ ๋ฐฐํฌ ์ด์์๊ฐ ํ๊ฒฝ ๋ณ์๋ก ์ง์ ํ๋ฉฐ ์ฌ๋ด ์ฃผ์๋ฅผ ํ์ฉํ๋ค. ๋ธ๋ผ์ฐ์ ์ ์๋ฒ ๋ชจ๋ ๊ทธ ์ฃผ์์ ์ ๊ทผํ ์ ์์ด์ผ ํ๋ค. Keycloak role์ ์ฑ tier๋ก ๋งคํํ์ง ์๋๋ค. ๊ธฐ์กด ๊ด๋ฆฌ์ ์ค์ ๊ณผ ๋ฉค๋ฒ tier ์ ์ฑ ์ ์ ์ฉํ๋ค. Keycloak์ผ๋ก ๋ก๊ทธ์ธํ ์ฌ์ฉ์์ ์ฑ ๋ก๊ทธ์์์ ์ฑ ์ธ์ ๋ง ์ข ๋ฃํ๋ฉฐ Keycloak SSO ์ธ์ ์ ์ ์งํ๋ค. GoogleยทOIDCยทKeycloak ๋ก๊ทธ์ธ์ ๊ธฐ์กด ๊ณ์ ์๋ ์ ๊ณต์์ ์ต์ ์ฌ์ฉ์ ์ ๋ณด๋ฅผ ๋ฐ์ํด ์ด๋ฆ๊ณผ ํ๋กํ ์ด๋ฏธ์ง๋ฅผ ๊ฐฑ์ ํ๋ค. ์ ๊ณต์๊ฐ ์ฌ์ง์ ๋ฐํํ์ง ์์ผ๋ฉด ์ ์ฅ๋ ์ด๋ฏธ์ง๋ฅผ ์ ์งํ๋ค. ํ๋กํ ๋๊ธฐํ๋ ChatยทAgent ์์ ๊ถ์ ์ฌ์ฉํ๋ ๊ธฐ์กด ์ด๋ฉ์ผ์ ๋ณ๊ฒฝํ์ง ์๋๋ค. ์ ๊ณต์๊ฐ ์ ์ด๋ฉ์ผ์ ๋ณด๋ด๋ฉด ํ์ฉ ๋๋ฉ์ธ์ ๋ค์ ๊ฒ์ฌํ์ง๋ง, ์์ ๊ถ ์ด๋ฉ์ผ๊ณผ ํด๋น ์ด๋ฉ์ผ์ ์ธ์ฆ ์ํ๋ ๋ณด์กดํ๋ค. ์ฑ์ tier๋ ์ ๊ณต์ ํ๋กํ์์ ๊ฐ์ ธ์ค์ง ์์ผ๋ฉฐ ๊ธฐ์กด ๊ด๋ฆฌ์ยท๋ฑ๊ธ ์ ์ฑ ์ ๋ฐ๋ฅธ๋ค.
STAGE=alpha|prod๋ ๋ก๊ทธ์ธ ์๋จ์ด ํ๋๋ ์์ผ๋ฉด ๋ถํ
์ ๊ฑฐ๋ถํ๋ค(assertAccessControlConfig);
local ์ scripts/dev-session.ts ๊ฐ ์ธ์
์ ๋ง๋ค์ด ์ฃผ๋ฏ๋ก ์์ด๋ ๋๋ค. ๋ก๊ทธ์ธ์ ์๋จ๊ณผ
๋ฌด๊ดํ๊ฒ ALLOWED_EMAIL_DOMAINS ๋ก ์ ํ๋๋ค. ์ฌ์ฉ์ ์์ฑ๊ณผ ์ธ์
์์ฑ ์์ชฝ์ ํ
์์, ๊ทธ๋์
์ด๋ฏธ ์๋ ์ฌ์ฉ์๋ ๋๋ฉ์ธ์ด ๋ชฉ๋ก์์ ๋น ์ง๋ฉด ๋ค์ ๋ก๊ทธ์ธ์ ๊ฑฐ์ ๋๋ค. ๋น ๋ชฉ๋ก์ ๋ชจ๋ ๋๋ฉ์ธ์
ํ์ฉํ๋ค. STAGE=alpha|prod ๋ ๊ทธ ์ํ๋ก ์ ์ ๋ถํ
ํ๋ค
(๋ถํ
์ ๊ฒ์ฆ ์ฐธ๊ณ ).
admin ์ ์ฉ ๋ฉค๋ฒ ๋ชฉ๋ก์ Better Auth ์ user ํ์ ์ฝ๋๋ค. createdAt ์ ๊ฐ์
์๊ฐ์ด๊ณ ,
lastLoginAt ์ ์ธ์
์์ฑ์ ์ฑ๊ณตํ ๋ค ๊ฐฑ์ ๋๋ค. ๊ทธ ์ด์ ๋ถํฐ ์๋ ์ฌ์ฉ์๋ ๋ค์ ๋ก๊ทธ์ธํ๊ธฐ
์ ๊น์ง ๋ง์ง๋ง ๋ก๊ทธ์ธ ๊ฐ์ด ์๋ค. ํ์์คํฌํ ๊ฐฑ์ ์คํจ๋ ๋ก๊ทธ์ ๋จ์ง๋ง, ์ ์ ์ ๊ณต์ ๋ก๊ทธ์ธ์
์ฑ๊ณตํ ๊ฒ์ ์ธ์ฆ ์คํจ๋ก ๋ฐ๊พธ์ง๋ ์๋๋ค.
| ํ๋ฉด | ๊ฒ์ดํธ | ๋ฌด์์ ๊ฒฐ์ ํ๋๊ฐ |
|---|---|---|
| ํ์ด์ง | src/proxy.ts |
๋ก๊ทธ์์ ์ํ์ ๋ฐฉ๋ฌธ์๋ฅผ /login?next=โฆ ๋ก ๋ฆฌ๋ค์ด๋ ํธ |
| API ๋ผ์ฐํธ | withAuth / withMemberAuth / withAdminAuth (src/lib/session.ts) |
์ธ์
์ด ์์ผ๋ฉด 401. member gate๋ tier๋ฅผ, admin gate๋ ์๋์ effective admin ํ์ ์ ์ฌ์ฉํ๋ค. ์คํจ๋ 403์ด๋ฉฐ ์ฑ๊ณตํ๋ฉด SessionUser๋ฅผ ๊ฑด๋จ๋ค |
src/shared/pageAccess.ts ๋ ์ด๋ค ํ์ด์ง๊ฐ ๊ณต๊ฐ์ธ์ง์ ๋ํ ๋จ์ผ ์์ ์๋ค. /, /login, /guide.
๊ฐ์ด๋๋ ๋ก๊ทธ์ธ ์์ด ์ฝ๋ ์ ์ ์๋ด์ด๋ฉฐ, ๊ฐ์ด๋์์ ์ฐ๊ฒฐํ๋ Agentยท์ค์ ํ์ด์ง์ API๋
๊ฐ์์ ์ธ์ฆยท๊ถํ ๊ฒ์ฌ๋ฅผ ์ ์งํ๋ค.
src/proxy.ts์ ๋ธ๋ผ์ฐ์ ์ ๋ง๋ฃ ์ธ์
redirect๊ฐ ๊ฐ์ ํ์ ์ ์ฝ๋๋ค. matcher ๊ฐ ๋ฟ๋ ๋๋จธ์ง
์ ๋ถ๋ ์ธ์
์ ์๊ตฌํ๋ฏ๋ก ์ ๋ผ์ฐํธ๋ ๊ธฐ๋ณธ์ด ๋ณดํธ ์ํ ๋ค. ๊ทธ ๋ฐฉํฅ์
์๋์ ์ด๋ค. ๊ณต๊ฐ ํ์ด์ง๋ฅผ ๋ชฉ๋ก์ ๋ฃ๋ ๊ฒ์ ์์ผ๋ฉด ์ฌ์ฉ์๊ฐ 1๋ถ ์์ ์ ๊ณ ํ๋ ๋ฆฌ๋ค์ด๋ ํธ๊ฐ
์๊ธฐ์ง๋ง, ๋น๊ณต๊ฐ ํ์ด์ง๋ฅผ ๋ฃ๋ ๊ฒ์ ์์ผ๋ฉด ์กฐ์ฉํ ์คํจํ๋ค.
ํ์ด์ง ๊ฒ์ดํธ๋ ์ธ์
์ฟ ํค์ ์ ํจ์ฑ์ด ์๋๋ผ ์กด์ฌ ๋ฅผ ํ์ธํ๋ค. ์ ํจ์ฑ๊น์ง ํ์ธํ๋ ค๋ฉด ๋ชจ๋
๋ด๋น๊ฒ์ด์
๋ง๋ค ์ธ์
์ ์ฝ์ด์ผ ํ๊ณ , ๊ทธ๋ฌ๊ณ ๋ ๊ทธ๊ฒ์ ์ธ๊ฐ ๊ฒฐ์ ์ด ์๋๋ค. ์ธ๊ฐ๋ ์ค์ ๋ก
๋ฐ์ดํฐ๋ฅผ ๋ง์ง๋ ์์ฒญ์ ๋ณด๋ withAuth ์ assertAgentOwner ์์ ์๋ฒ ์ธก์ ๋จ๋๋ค.
๋ฐ๋ผ์ ์กด์ฌํ์ง๋ง ์ ํจํ์ง ์์ ์ฟ ํค๋ ํ์ด์ง์ ๋๋ฌํ๊ณ ๊ทธ ๋ค์ API ์์ 401 ์ ๋ฐ๋๋ค.
๋ธ๋ผ์ฐ์ ์ ๊ณตํต ์๋ต ๊ฒฝ๊ณ๋ ๊ฐ์ origin์ /api/* 401์ ๋ฐ์ผ๋ฉด ํ์ฌ pathยทqueryยทfragment๋ฅผ
next๋ก ๋ณด์กดํด /login์ผ๋ก full navigationํ๋ค. Root layout์ด ์ด๋ฏธ ์ธ์
์ ์ ํจํ์ง ์๋ค๊ณ
ํ์ ํ ๋ณดํธ ํ์ด์ง๋ ๊ฐ์ ๊ฒฝ๋ก๋ฅผ ํ๋ค. ๊ฒ์ดํธ๊ฐ ์์ ๋ ๊ฒ์ ํ๋ฒํ ๋ก๊ทธ์์ ์ํ์ด๋ฉฐ,
๊ทธ ๋ฐฉ๋ฌธ์์๊ฒ ์ฝ์ shell์ด๋ API error box๋ฅผ ๋ ๋๋งํ์ง ์๋๋ค.
/api ๋ matcher ๋ฐ์ ์๋ค. ๊ทธ ๋ผ์ฐํธ๋ค์ ์ค์ค๋ก ์ธ์ฆํ๋ฉฐ, ํ๋ก๊ทธ๋จ ํธ์ถ์์๊ฒ๋ HTML
๋ฆฌ๋ค์ด๋ ํธ๊ฐ ์๋๋ผ ๋ฐ๋์ 401 ๋ก ๋ตํด์ผ ํ๋ค.
next ํ๋ผ๋ฏธํฐ๋ ์ฃผ์์ฐฝ์์ ์ค๋ฏ๋ก /login ์ ๊ทธ๊ฒ์
safeNextPath(src/shared/safeNextPath.ts)๋ก ๋์ฝ๋๋ค. //host ์ /\host ๋ฅผ ๊ฑฐ๋ถํ์ง
์์ผ๋ฉด ๋ก๊ทธ์ธ ํ๋ก์ฐ๊ฐ ์คํ ๋ฆฌ๋ค์ด๋ ํธ๊ฐ ๋๋ค.
๋ก๊ทธ์ธ ์ค๋ฅ๋ signInError.ts์ ์ฝ๋๋ก ์ ๋ฌํ๊ณ ๋ก๊ทธ์ธ ํ์ด์ง๊ฐ ์๊ธฐ ๋ฌธ๊ตฌ๋ก ํ์ํ๋ค.
์ ์ ์๋ error ๊ฐ์ ์ผ๋ฐ ์ค๋ฅ๋ก ๋ฐ๊พธ๋ฉฐ ์ ๊ณต์์ ํ
์คํธ๋ ํ์ฉ ๋๋ฉ์ธ ๋ชฉ๋ก์ ๊ทธ๋๋ก ๋ฐ์ฌํ์ง ์๋๋ค.
Agent ๋ ๊ณต์ ์นดํ๋ก๊ทธ์ด๋, ๊ณต๊ฐ ๋ฒ์(visibility)๋ฅผ ๊ฐ๋๋ค. public(๊ธฐ๋ณธ๊ฐ์ด์
visibility ํ๋๊ฐ ์์ ๋์ ์๋ฏธ)์ ๋ก๊ทธ์ธํ ์ฌ์ฉ์๊ฐ ์กฐํํ๊ณ member ์ด์์ด ์คํยท๋ณต์ ํ๋ค. private์ ์์ ์๋ง ์ ๊ทผํ ์ ์์ผ๋ฉฐ ๊ด๋ฆฌ์๋ ์คํยท๋ณต์ ๊ถํ์ ์ป์ง ์๋๋ค.
์ค์ ๊ด๋ฆฌ ๊ถํ์ ๋ณ๋ ๊ฒ์ฌํ๋ค. ๊ณต๊ฐ ๋ฒ์ ํ์ ์ src/domain/agent/access.ts์
mayAccessAgent๊ฐ ์์ ํ๊ณ , Agent ์กฐํ๋ฅผ ํฌํจํ ๊ฒ์ฌ๋ assertAgentAccessible์ ์ฌ์ฉํ๋ค.
์ฝ์ยทChat๊ณผ ๊ฐ์ธ API ํ ํฐ์ ์ธ์ฆ๋ ์ฌ์ฉ์์ ํ์ฌ assertAgentAccessible ํ์ ์ ์ ์ฉํ๋ค.
๊ฐ์ธ ํ ํฐ์ Agent ์์ ์๊ฐ ์๋๋ผ ๋ฐ๊ธ ์ฌ์ฉ์ ID์ ๋ฌถ์ธ๋ค. SlackยทTelegramยทTeams๋
์ ๋ฌ ์ธ์ฆ ํ ์ฐ๊ฒฐํ Studio ์ฌ์ฉ์์ ํ์ฌ ๊ณ์ ยทmember ๋ฑ๊ธยท
Agent ์ ๊ทผ์ ํ์ธํ๋ค. ์ด๋ฉ์ผ์ด๋ bot ์์ ์๋ง์ผ๋ก ํธ์ถ์๋ฅผ ์ถ์ ํ์ง ์๋๋ค.
Slack ์ฑ์ ์ฑ๋ ํค์๋ ์๋ฆผ์ ํค์๋๋ฅผ ์ ์ฅํ ์ธ์ฆ ๊ณ์ ์ ์ฌ์ฉ์ ID์ revision์ผ๋ก ์คํํ๋ค.
ํ์ฌ ๊ณ์ ยทAgent ์ ๊ทผยท์ฐ๋ ํ์ฑํยท๋ฑ๋ก revision์ ๋ชจ๋ธยท๋๊ตฌยทWorkspace ํจ๊ณผ ์ ์ ๋ค์ ๊ฒ์ฌํ๋ฉฐ,
ํค์๋ ๋ณ๊ฒฝยท์ญ์ ๋ก ๊ถํ์ ์ฒ ํํ๋ค. ๋ค๋ฅธ ์ฑ์ DMยทthread ๋ต๊ธ๊ณผ ๋ด ์์ ์ ๋ฉ์์ง๋ ์คํํ์ง ์๋๋ค.
Slack์ ๋ช
๋ นยทnative ์ค๋จยทthread-start๋ ์ฌ๋์ ์ฐ๊ฒฐ ๊ฒ์ฌ๋ฅผ ์ง๋๋ค.
TriggerยทWebhook์ ์ ๋ฌ ์ธ์ฆ์ ๋จธ์ ์์ฒญ ์ธ์ฆ์ ๋ฐ๋ฅธ๋ค.
private agent ๋ฅผ local subagent ๋ก ๋ฐ์ธ๋ฉ ํ๋ ๊ฒ๋ ์ฝ๊ธฐ๋ค: ํธ์ง์๊ฐ ์ ๊ทผํ ์ ์๋
agent ๋ Agent ์ค์ ์ ์ฅ ์์ ์ ๊ฑฐ์ ๋๋ค (assertSubavailableAgentsAccessible). ์ด๋ฏธ ๋ฐ์ธ๋ฉ๋
์ฐธ์กฐ๋ agent ๊ฐ ๋ค๋ฆ๊ฒ private ์ด ๋์ด๋ ํธ์ง ๊ฐ๋ฅ์ฑ์ ์์ง ์๋๋ค. ์คํ ์์ ์ transfer
๋ ํ์ฌ ํธ์ถ์์ Agent ์ ๊ทผ ๊ถํ์ ๋ค์ ํ์ธํ๋ค. ๋น์ฉ ๋์๋ณด๋์ agent ํฉ๊ณ ๋
visibility ์ด์ ์ฒ๋ผ ์ด๋ ค ์๋ค: ์ด๋ฆ๊ณผ ์ง์ถ ์ง๊ณ๋ ์นดํ๋ก๊ทธ ์ด์์ ์ผ๋ถ๋ก ๋จ๊ฒจ ๋ ๊ฒฐ์ ์ด๋ค.
| ๋ฆฌ์์ค | ์ฝ๊ธฐ | ์ฐ๊ธฐ |
|---|---|---|
| Agent, Agent ์ค์ | ์ ๊ทผ ๊ฐ๋ฅํ ์ฌ์ฉ์ (assertAgentAccessible, public ์ ์ ์, private ์ ์์ ์) |
์์ ์ (assertAgentOwner) |
| Agent trace | ์์ ์ | โ |
| Agent Slack ์ค์ | ์์ ์ | ์์ ์ |
| ๊ฐ์ธ Agent API token | ๋ฐ๊ธ ์ฌ์ฉ์ ๋ณธ์ธ๊ณผ ํ์ฌ Agent ์ ๊ทผ | ๋ฐ๊ธ ์ฌ์ฉ์ ๋ณธ์ธ; ์์ฑยทreveal์ ํ์ฌ token ์ฌ์ฉ tier๋ ๊ฒ์ฌ |
| trigger | ์์ ์ | ์์ ์ |
| ๊ฐ์ธ MCP ์ฐ๊ฒฐ | member ์ด์์ธ ๋ณธ์ธ๊ณผ ํ์ฌ Agent ์ ๊ทผ | ๋์ผ ์ฌ์ฉ์๋ง ์ฐ๊ฒฐยทํด์ ; binding ์ด์ ํค๋ ๊ฒ์ฌ๋ Agent ์์ ์ |
ํธ์ถ์๋ณ usage (usage/actors) |
์์ ์ | โ |
| Agent usage ํฉ๊ณ | ๋ก๊ทธ์ธํ ๋ชจ๋ ์ฌ์ฉ์ | โ |
| Skill / MCP ์๋ฒ / plugin | guest๋ฅผ ํฌํจํ ๋ก๊ทธ์ธ ์ฌ์ฉ์ (withAuth) |
admin (withAdminAuth) |
| ์ฑ ์ค์ | admin | admin |
| ๋ชจ๋ธ ์ฆ๊ฒจ์ฐพ๊ธฐ | ๋ก๊ทธ์ธํ ์ฌ์ฉ์ ๋ณธ์ธ | member ์ด์์ธ ์ฌ์ฉ์ ๋ณธ์ธ |
| ๋ฉค๋ฒ ๋๋ ํฐ๋ฆฌ | admin | admin (tier ๋ณ๊ฒฝ, member.set-tier ๋ก ๊ฐ์ฌ) |
| Chat | ์์ ์๋ง (์์ ์๊ฐ ์๋๋ฉด 404) | ์์ ์๋ง |
| Workspace | ์์ ์์ ํ์ฌ Agent ์ ๊ทผ ๊ฒ์ฌ | ์์ ์; ์คํยทGit ์น์ธ์ ํ์ฑํยท์ ์ฑ ยท์น์ธ ์ํ๋ ๊ฒ์ฌ |
| Audio ๊ณต์ ์ฒ๋ฆฌ ์ค์ | ์ ๊ทผ ๊ฐ๋ฅํ member | Agent ์์ ์ |
| ์ค๋์ค jobยท๋น๊ณต๊ฐ source ํ์ผ | ์์ /ํ์ผ ์์ ์์ Agent ์ ๊ทผ ๊ฒ์ฌ | ์์ ์ ๋ฒ์์ job/file ์ํ์ ๋ฐ๋ฅธ ์กฐ์ |
| ์ผ๋ฐ Artifact | ์์ฑยท์ฒจ๋ถ ์์ ์ ๋๋ Agent ์์ ์ | member ์ด์์ด๋ฉฐ ๊ฐ์ ์์ ๊ถ ๋ฒ์์์ ์ญ์ . ๋น๊ณต๊ฐ source ํ์ผ์ ์ ์ ์ฉ ๊ฒฝ๊ณ |
trace ์ Slack ์ค์ ์ ์ฝ๊ธฐ ๋ ๊ฒ์ดํธ๋๋๋ฐ, ๋ค๋ฅธ ์ฌ์ฉ์์ ๋ฐํ์ ์
์ถ๋ ฅ๊ณผ ๋ง์คํน๋ ์๊ฒฉ
์ฆ๋ช
์ ๊ฐ์ฅ์๋ฆฌ๋ฅผ ๋
ธ์ถํ๊ธฐ ๋๋ฌธ์ด๋ค. agent ํฉ๊ณ ๋ ์นดํ๋ก๊ทธ๊ฐ ๊ณต์ ๋๋ฏ๋ก ์ด์ด ๋๋ค.
ํธ์ถ์๋ณ ๋ด์ญ์ ๊ฐ์ธ์ ์ง๋ชฉํ๋ฏ๋ก usage/actors ๋ ๊ทธ๋ ์ง ์๋ค. capability ๋ ์ง์คํธ๋ฆฌ๋
guest๋ member์ ๊ฐ์ ๋ฉ๋ด์์ ์กฐํํ๋ค. guest๋ Agentยท์ฐ๋ยท๋ ์ง์คํธ๋ฆฌยท๋ชจ๋ธ ์ฆ๊ฒจ์ฐพ๊ธฐ๋ฅผ
๋ณ๊ฒฝํ๊ฑฐ๋ Artifact๋ฅผ ์ญ์ ํ ์ ์์ผ๋ฉฐ, ๊ฐ๋ฑ๋ ๊ธฐ์กด Agent ์์ ์์๊ฒ๋ ๊ฐ์ ์ ํ์ด ์ ์ฉ๋๋ค.
Agent ๋ณ๊ฒฝ API๋ withMemberAuth์ ์์ ๊ถ ๊ฒ์ฌ๋ฅผ ํจ๊ป ์ฌ์ฉํ๋ค. ์ด์ preview์ MCP ์ฐ๊ฒฐ
ํ
์คํธ๋ ์ธ๋ถ ์๋น์ค ์์ฒญ์ ์คํํ๋ฏ๋ก member ์ด์์ ์๊ตฌํ๋ค.
Agent ์คํยทChat ์ ์กยท์น์ธ ์ฌ๊ฐยทWorkspace ์ ์์
์ member ์ด์์๊ฒ ํ์ฉํ๋ค. guest๋
๊ธฐ์กด ๋ณธ์ธ ๊ธฐ๋ก์ ์กฐํํ๊ณ ์คํ ์ค๋จยท์ข
๋ฃยท์น์ธ ํ๊ธฐ๋ฅผ ํ ์ ์๋ค. ์คํ ์ค ๊ฐ๋ฑ๋ ์ ๋ชจ๋ธยท๋๊ตฌ ํจ๊ณผ๋ฅผ ์ฐจ๋จํ๋ค.
์ค์น ๊ณต์ฉ ์์์ ๊ด๋ฆฌ์ ๊ถํ๊ณผ Agent ์์ ๊ถ์ ๋ณ๊ฐ๋ค.
isAdminEmail์ ๊ณต์ฉ ๋ ์ง์คํธ๋ฆฌยท์ค์ ์ ๊ด๋ฆฌ์ ๋ชฉ๋ก์ ํ์ธํ๋ฉฐ, ๋ชฉ๋ก์ด ๋น๋ฉด member ์ด์์๊ฒ
์ด๊ธฐ ๊ด๋ฆฌ ๊ถํ์ ํ์ฉํ๋ค. isEffectiveAdmin์ ์ด ๊ท์น๊ณผ ์ ์ฅ๋ admin tier๋ฅผ ํฉ์น๋ค.
isConfiguredAdmin์ ADMIN_EMAILS์ ๋ช
์๋ ๊ณ์ ์ ์ฐพ์ admin ์น๊ฒฉ๊ณผ tier ์ ๊ธ์ ์ฌ์ฉํ๋ค.
์ด๋ ๊ด๋ฆฌ์ ํ์ ๋ ๋ค๋ฅธ ์ฌ๋์ Agent ๊ด๋ฆฌ ๊ถํ์ ๋ถ์ฌํ์ง ์๋๋ค.
GET /api/me๋ email, tier, ๊ณต์ฉ ์์ ๊ด๋ฆฌ์ฉ isAdmin์ ๋ฐํํ๋ค. Agent ํธ์ง ์ฌ๋ถ๋
isAgentOwner์ tierMayEdit๋ก ํ๋จํ๋ค. ์๋ฒ์ assertAgentOwner๊ฐ ๊ฐ์ ์์ ๊ถ์ ๊ฒ์ฌํ๋ค.
ADMIN_EMAILS์ ์ง์ ๋ ์ฃผ์๋ ๋ก๊ทธ์ธ ๋๋ ๋ฉค๋ฒ/ํ๋กํ ์กฐํ ๋ admin tier๋ก ์น๊ฒฉ๋๊ณ ,
๋ชฉ๋ก์ ์๋ ๋์ tier๊ฐ ์ ๊ธด๋ค. ๋ชฉ๋ก์์ ์ ๊ฑฐํด๋ ์๋ ๊ฐ๋ฑํ์ง ์์ผ๋ฉฐ ๊ด๋ฆฌ์๊ฐ ๋ฑ๊ธ์ ๋ณ๊ฒฝํ๋ค.
tier๋ Better Auth user ํ์ ์๋ฒ ์ ์ฉ ํ๋๋ค. ์คํ์ ์ฌ์ฉ์ ID๋ก ํ์ฌ ๊ณ์ ยท๋ฑ๊ธยทAgent ์ ๊ทผ์
ํ์ธํ๋ค. ์ด๋ฉ์ผ ๊ธฐ๋ฐ tier ์กฐํ์ ์บ์๋ 30์ด์ด๋ฉฐ ๋ณ๊ฒฝ์ ์ฒ๋ฆฌํ ์ธ์คํด์ค์์ ๋ฌดํจํ๋๋ค.
์ ๋น์ฉ ํ๋๋ Settings โ Access์ memberTiers์ memberTierLimits๊ฐ ์ ํ๋ค.
admin์ ๋ฌด์ ํ์ด๋ฉฐ guest๋ ํ๋์ ๋ฌด๊ดํ๊ฒ ์คํํ์ง ๋ชปํ๋ค. ๋๋จธ์ง ๋ฑ๋ก ๋ฑ๊ธ์ member ๊ถํ์
๊ฐ๋๋ค. ๋ฏธ๋ฑ๋ก ๋ฑ๊ธ์ guest๋ก ํด์ํ๋ค. ๋ฑ๊ธ ์ญ์ ์ ์ฌ์ฉ์ ๋ฐฐ์ ์ ๊ณต๋ transaction lock์
์ฌ์ฉํ๋ฉฐ ์ฌ์ฉ์๊ฐ ๋จ์ ๋ฑ๊ธ์ ์ญ์ ํ ์ ์๋ค. ์ ํ๋๋ ์ค์ ์บ์ TTL์ ๋ฐ๋ผ ์ ํ๋๋ค.
์ ์ํ์ ChatยทWorkspace๋ฅผ ํฌํจํ ๋ฉค๋ฒ ์์ ์ ์ผ๋ณ ํ์ UTC ์ 1์ผ๋ถํฐ ํฉ์ฐํ๋ค. ์คํ ์ ์ ์ด๋ฏธ ํ๋์ ๋๋ฌํ๋ฉด ์ ์คํ์ ๊ฑฐ์ ํ๋ค. ๋ฑ๊ธยท์ฌ์ฉ๋ ์กฐํ ์คํจ๋ ์คํ์ ์ค๋จํ๋ค. ์๋ฃ๋ ์ฌ์ฉ๋์ ๊ธฐ์ค์ผ๋ก ๊ฒ์ฌํ๋ฏ๋ก ์งํ ์ค์ธ ์คํ์ด ์์ก์ ์ด๊ณผํ ์ ์๋ค. ํ๋กํ ํ์ด์ง๊ฐ ์ฝ๋ ๊ฒ๊ณผ ๊ฐ์ ์ฐฝ, ๊ฐ์ ํ์ด๋ค. ๋ชจ๋ ํธ์ถ ์ถ์ฒ์๋ ํ์ธ๋ Studio ์ฌ์ฉ์๊ฐ ์๊ณ ๊ฐ์ ์ฌ์ฉ์ ID์ ๊ฐ์ธ ํ๋๋ฅผ ๊ณต์ ํ๋ค. ํ๋ซํผ actor๋ ์ถ์ฒ ๊ธฐ๋ก์ ์ํด ์ ์งํ๋ค. ๊ฐ์ธ API token์ ๋ฐ๊ธ ์ฌ์ฉ์์ ์์ ์ ์ธ ID์ ๋ฌถ์ด๋ฉฐ ์ธ์ฆ๋ง๋ค ํ์ฌ ๊ณ์ ยท๋ฑ๊ธยทAgent ์ ๊ทผ์ ๊ฒ์ฌํ๋ค. ๊ณ์ ์กด์ฌ ์ฌ๋ถ์ ํ์ฌ tier๋ ์ด๋ฉ์ผ tier ์บ์ ๋์ ์ฌ์ฉ์ ID๋ก ์กฐํํ๋ค. ํ์ธ๋ ์ฌ์ฉ์์ ํธ์ถ ๊ถํ ๊ฑฐ์ ์ 403, ์๋ชป๋ credential์ด๋ ์ญ์ ๋ ๋ฐ๊ธ ๊ณ์ ์ 401์ด๋ค. ๊ถํ ์ ์ฅ์ ์ฅ์ ๋ ์ธ์ฆ์ ํ์ฉํ์ง ์๋๋ค.
Agent ์ค์ ยท์ฐ๋ยทWorkspace ์ ์ฑ
์ ๋ณ๊ฒฝ๊ณผ Agent ๊ด๋ฆฌ ์๋ฃยทTraceยทํธ์ถ์๋ณ Usage ์กฐํ๋
assertAgentOwner๋ก ์์ ์๋ฅผ ํ์ธํ๋ค. public์ ๊ณต์ ์คํ ๋ฒ์์ด๋ฉฐ ํธ์ง ๊ถํ์ ๋ถ์ฌํ์ง ์๋๋ค.
์ผ๋ฐ Artifact๋ ์์ฑ์ ๋๋ ํด๋น Agent ์์ ์๊ฐ ๊ด๋ฆฌํ๋ฉฐ, ๋น๊ณต๊ฐ source ํ์ผ์ ํ์ผ ์์ ์๋ง
์ ๊ทผํ๋ค. ์กฐํ๋ ๋ณ๊ฒฝ ๊ฐ์ฌ ํ์ ์์ฑํ์ง ์๋๋ค.
์ ์ฅ๋๋ ๋ชจ๋ ์๊ฒฉ ์ฆ๋ช
. MCP ์๋ฒ ํค๋, Agent๋ณ ํค๋ ์ค๋ฒ๋ผ์ด๋, MCP OAuth ์
access/refresh tokenยทclient secretยท์ธ๊ฐ ์ค์ธ PKCE verifier, Slack ๋ด token ๊ณผ ์๋ช
์ํฌ๋ฆฟ,
Telegram ๋ด token ๊ณผ webhook ์ํฌ๋ฆฟ, Teams(Azure Bot) ํด๋ผ์ด์ธํธ ์ํฌ๋ฆฟ, ๊ฐ์ธ APIยทWebhook token, ๊ทธ๋ฆฌ๊ณ ์ํฌ๋ฆฟ์ธ ์ฑ
์ค์ (LLM API ํค์ plugins ์ ์ฅ์์ GitHub token)์ AES_ENCRYPTION_KEY ๋ก AES-256-GCM
์ํธํ๋๋ค(src/infrastructure/crypto/secretEncryption.ts). ์ ๊ฐ์ ๋ชจ๋ enc:v2: ๋ก ์ด๋ค.
v2 ๋ row ์ field ์ ์ฒด์ฑ์ AES-GCM AAD ๋ก ๋ฌถ์ผ๋ฏ๋ก ์ํธ๋ฌธ๋ง ๋ค๋ฅธ ์์น๋ก ์ฎ๊ธฐ๋ฉด ์ธ์ฆ์
์คํจํ๋ค. ๊ธฐ์กด enc:v1: ๊ฐ์ ๋ค์ ์ ์ฅํ๊ฑฐ๋ ์ฌ๋ฐ๊ธํ๊ธฐ ์ ๊น์ง ๊ทธ๋๋ก ์ฝ๋๋ค.
๊ฐ์ธ credential์ agent + purpose + userId + credentialId์ ๋ฌถ์ธ๋ค. Slack ์ bot tokenยทsigning secret, Telegram ์ bot
tokenยทwebhook secret, Teams ์ app password ๋ agent + integration + field ๋ฅผ ์ด๋ค.
MCP registry header ๋ ํญ๋ชฉ ์ด๋ฆ๊ณผ header ์ด๋ฆ์, managed MCP ์ environment ๋
ํญ๋ชฉ ์ด๋ฆ๊ณผ ๋ณ์ ์ด๋ฆ์ ๋ฌถ์ธ๋ค. HTTP header์ override ๋ณํฉ๋ง ์ด๋ฆ์ ๋์๋ฌธ์๋ฅผ ๋ฌด์ํ๊ณ ,
AAD ๋ environment์ ๊ฐ์ ๊ณตํต map ๊ท์น์ ๋ฐ๋ผ ์ ์ฅ๋ ํค ์ฒ ์๋ฅผ ๊ทธ๋๋ก ์ด๋ค.
Agent์ MCP header override๋ agent + configuration + mcp + server + header์ ๋ฌถ์ธ๋ค. ํ์ฌ ์ค์ ์
๊ฐ์ Agent์์ ์์ ํด๋ ์ํธํ ๋ฌธ๋งฅ์ ์ ์ง๋๋ฉฐ ๋ค๋ฅธ Agent๋ก ๋ณต์ ํ ๋๋ ์ํฌ๋ฆฟ์ ๋ณต์ฌํ์ง
์๋๋ค.
์ฝ๊ธฐ๋ ๊ธธ์ด๋ฅผ ๋ณด์กดํ๋ ๋ง์คํฌ ๋ฅผ ๋ฐํํ๋ค. ์ฝ์์ด ๊ฐ์ ๋ณด์ฌ ์ฃผ์ง ์์ผ๋ฉด์ ์ด๋ค ์๊ฒฉ ์ฆ๋ช ์ด ์ค์ ๋ผ ์๋์ง๋ ๋ณด์ฌ ์ค ์ ์๊ฒ ํ๊ธฐ ์ํด์๋ค:
| ํ๋ฌธ ๊ธธ์ด | ๋๋ฌ๋๋ ๋ถ๋ถ |
|---|---|
| 9์ ๋ฏธ๋ง | ์์ (* ร ๊ธธ์ด) |
| 9์ ์ด์ | ์ 4์์ ๋ค 4์ |
๋๋ฌ๋ ๋ ๊ฐ์ฅ์๋ฆฌ๊ฐ ๋ง๋๋ ์ผ์ ๊ฒฐ์ฝ ํ์ฉ๋์ง ์๋๋ค. ๊ฐ์ฅ์๋ฆฌ๋ฅผ ๋๋ฌ๋ด๋ ค๋ฉด ํ๋ฌธ์ด ํ์ํ๋ฏ๋ก ๋ง์คํน์ ๋ณตํธํ๋ฅผ ํ๋ค. ๊ทธ๊ฒ์ ํธ์ถํ๋ admin/์์ ์ ๊ฒ์ดํธ๊ฐ ๊ฑธ๋ฆฐ ์ฝ๊ธฐ ๋ทฐ ์์์๋ง์ด๊ณ , ๋ณตํธํ ์คํจ๋ ์๋ฌ๋ฅผ ๋ด๋ ๋์ ๊ฐ์ ํต์งธ๋ก ๊ฐ์ถ๋ค. ์๋ฌด๊ฒ๋ ๋๋ฌ๋์ง ์์ ๋งํผ ์งง์ ๊ฐ์ ์์ ๋ณตํธํ๋์ง ์์ผ๋ฉฐ, ๊ทธ ํ๋จ์ ์ํธ๋ฌธ ๊ธธ์ด๋ก ๋ด๋ฆฐ๋ค(AES-GCM ์ ํ๋ฌธ ๊ธธ์ด๋ฅผ ๋ณด์กดํ๋ค).
์
๋ฐ์ดํธ ์ ๋ง์คํน๋ ๊ฐ์ด๋ ๋น ๊ฐ์ ์ ์ฅ๋ ์ํฌ๋ฆฟ์ ๋ณด์กดํ๋ค. ์ ์ฅ๋ ์๋๊ฐ ์๋ ํค์ ์จ
๋ง์คํน๋ ๊ฐ์ ๋ฒ๋ฆฐ๋ค. ๋ง์คํฌ๋ ์ด๋ฏธ ์๋ ์ํฌ๋ฆฟ์ ํ์ธํด ์ค ์๋ง ์๊ณ , ๋ง๋ค์ด ๋ผ ์๋
์๋ค. ํค๋ ์ค๋ฒ๋ผ์ด๋ ๋งต์ null ์ ๋ช
์์ ์ ๊ฑฐ๋ก ๊ทธ๋๋ก ํต๊ณผํ๋ค. ์ ๊ฑฐ๋ ์ํฌ๋ฆฟ์ด ์๋๋ค.
ํค๋ ์ด๋ฆ์ ์ผ๋ฐ ๋ฐ์ดํฐ ํค๋ก ์ฒ๋ฆฌํ๋ค. API ๊ฒ์ฆยท์ํธํ ๋ณํฉยทMCP ์ ์ก์์ __proto__ ๊ฐ์
์ด๋ฆ๋ ๋๋ฝํ์ง ์์ผ๋ฉฐ, SDK๊ฐ ๋ง๋ ํ๋กํ ์ฝ ํค๋๋ ๋ฑ๋กํ ๊ธฐ๋ณธ ํค๋๋ณด๋ค ์ฐ์ ํ๋ค.
์๋ก ์
๋ ฅํ ๊ฐ์ enc:v1: ๋๋ enc:v2: ๋ก ์์ํ๋๋ผ๋ ํ๋ฌธ์ผ๋ก ์ทจ๊ธํด ํญ์ ์๋ก ์ํธํํ๋ค. ์ํธ๋ฌธ ์ ๋์ฌ๋
์ ์ฅ์์์ ์ฝ์ ๊ฐ์ ํ์์ผ ๋ฟ, API ์
๋ ฅ์ด ์ ๋ขฐํ ์ ์๋ ์ ์ฅ ๊ฐ์ด๋ผ๋ ์ฆ๊ฑฐ๊ฐ ์๋๋ค.
Agent๋ณ MCP ๋ฌธ์์ด ์ค๋ฒ๋ผ์ด๋๋ ์ ์ฅ ๋น์ registry URL ์ fingerprint ์ ํจ๊ป ๋ณด๊ดํ๋ค. ๊ฐ์
์ด๋ฆ์ URL ์ด ๋ฐ๋๊ฑฐ๋ fingerprint ๊ฐ ์๋ ์์ ๊ฐ์ด๋ฉด ์ ์ํฌ๋ฆฟ์ ๋ณด๋ด์ง ์๋๋ค. ์ endpoint
์ฉ ์๊ฒฉ ์ฆ๋ช
์ ๋ค์ ์
๋ ฅํด์ผ ํ๋ค.
์ด ์ฑ์ด ๋ฐ๊ธํ๋ ์ํฌ๋ฆฟ ์ค ๋์ ํ๋ฌธ์ผ๋ก ๋์ฝ์ ์ ์๋ค:
| ์ํฌ๋ฆฟ | ์๋ํฌ์ธํธ | ๋๊ฐ |
|---|---|---|
| ๊ฐ์ธ Agent API token | POST /api/agents/{name}/token/reveal |
๋ฐ๊ธ ์ฌ์ฉ์ ๋ณธ์ธ |
| ๊ฐ์ธ Webhook token | POST /api/agents/{name}/webhook-token/reveal |
๋ฐ๊ธ ์ฌ์ฉ์ ๋ณธ์ธ |
๋ ๋ชจ๋ ์ฝ๊ธฐ์๋ POST๋ฅผ ์ฌ์ฉํ๋ค. ์๋ต ๋ณธ๋ฌธ์ด ์ด์ ์๋ ์๊ฒฉ ์ฆ๋ช ์ด๋ฏ๋ก ์บ์ยท๋ธ๋ผ์ฐ์ ๊ธฐ๋กยท ํ๋ฆฌํ์น ๋ฐ๊นฅ์ ๋๋ค. ๋ชจ๋ reveal์ ์ค์ ์ํ์์ email๊ณผ ํจ๊ป ๊ฐ์ฌ ํ์ ๋จ๊ธด๋ค.
๋ฐ๋ผ์ ๋์ ํด์๊ฐ ์๋๋ผ ์ํธํํด์ ์ ์ฅ๋๋ฉฐ, ์ด๋ ์๋๋ ํธ๋ ์ด๋์คํ๋ค. ๋ฐ์ดํฐ์คํ ์ด๋ง์ผ๋ก๋
ํ๋๋ ์ธ ์ ์์ง๋ง, ๋ฐ์ดํฐ์คํ ์ด ๋ํ๊ธฐ AES_ENCRYPTION_KEY ๋ฉด ์ธ ์ ์๋ค. ๊ทธ ํค๋ฅผ ํ
์ด๋ธ
๋คํ์ ์ด์ ์๋ agent ์๊ฒฉ ์ฆ๋ช
์ฌ์ด์ ์ ์๋ ๊ฒ์ผ๋ก ๋ค๋ค๋ผ. ๊ณต์ฉ agent token์ ๊ฐ์ธ credential๋ก ๊ฐ์ฃผํ์ง ์์ผ๋ฉฐ ์ ์ฌ์ฉ์๋ณ ํ ํฐ์ ๋ฐ๊ธํด์ผ ํ๋ค.
์ด ์ฑ์ด ๋ฐ๊ธํ๋ ์ํฌ๋ฆฟ์ GitHub ์ ghp_/gho_ ์ฒ๋ผ ์ ํ๊ณผ ์ข
๋ฅ๋ฅผ ๋ฐํ๋ ์ ๋์ฌ๋ฅผ
์ง๋
(src/shared/generatedSecret.ts), ์ ์ถ๋ ๋ฌธ์์ด์ด ๋ฌด์์ ์ฌ๋์ง ์ถ์ ํ ์ ์๋ค:
| ์ ๋์ฌ | ์ํฌ๋ฆฟ |
|---|---|
ast_ |
๊ฐ์ธ Agent API token (๋ฐ๊ธ ์ฌ์ฉ์ ๊ด๋ฆฌ) |
asw_ |
๊ฐ์ธ Webhook token (๋ฐ๊ธ ์ฌ์ฉ์ ๊ด๋ฆฌ) |
asl_ |
๋ฉ์ ์ ์ฌ์ฉ์ ์ฐ๊ฒฐ์ฉ ์ผํ์ฉ ์ฝ๋ (10๋ถ, ํด์๋ง ์ ์ฅ) |
asg_ |
Telegram webhook ์ํฌ๋ฆฟ (agent ๋ง๋ค ๋ฐํ. Telegram ์๊ฒ๋ง ๊ฑด๋ค๊ณ ๊ฒฐ์ฝ reveal ํ์ง ์๋๋ค) |
๋๋ค secret์ 32๋ฐ์ดํธ(256๋นํธ)๋ค. ๊ฐ์ธ APIยทWebhook token์ ๊ณต๊ฐ credential UUID์ secret์ ํจ๊ป ์ฌ์ฉํ๋ฉฐ UUID๋ง์ผ๋ก๋ ์ธ์ฆ๋์ง ์๋๋ค. ๊ณผ๊ฑฐ ๊ณต์ฉ ํ ํฐ์ ๊ฐ์ธ ์ฌ์ฉ์๋ฅผ ์ถ์ ํ๋ ๊ทผ๊ฑฐ๋ก ์ฐ์ง ์๋๋ค.
agent token ์ ํ์์ฉ ๋ง์คํฌ๋ ์์ฑ ์์ ์ ๊ณ์ฐ๋ผ ์ํธ๋ฌธ ์์ ์ ์ฅ๋๋ฏ๋ก, token ์ ๋์ดํ๋ ๋ฐ๋ ๋ณตํธํ ๋น์ฉ์ด ๋ค์ง ์๋๋ค. ๊ทธ ๋ง์คํฌ๋ ์ ๋์ฌ์ ๊ฐ์ฅ์๋ฆฌ ๋ฌธ์๋ง ์ค์ด ๋๋ฅด๋ฉฐ, token ์ ๋ณต์ํ๊ธฐ์ ์ถฉ๋ถํ ์ ์ ๊ฒฐ์ฝ ์๋ค.
์ธ์ ์ฟ ํค๊ฐ ์๋ ํธ์ถ์๋ ํ๋ฉด๋ณ ์๊ฒฉ ์ฆ๋ช ์ ์ฌ์ฉํ๋ค:
| ํ๋ฉด | ์๊ฒฉ ์ฆ๋ช | ๊ฒ์ฆ |
|---|---|---|
์คํ ์๋ํฌ์ธํธ (predict, chat/completions, agent) |
Authorization: Bearer ast_โฆ |
๊ฐ์ธ credential์ ์์ ์๊ฐ ๋น๊ต, ํ์ฌ ๋ฐ๊ธ ๊ณ์ ยทtierยทAgent ์ ๊ทผ ๊ฒ์ฌ. ๋ฐ๊ธ ์ฌ์ฉ์๋ก์ ์คํ๋๋ค (authenticateExecution) |
| Slack ์ด๋ฒคํธ | Slack ์๋ช ์ํฌ๋ฆฟ | HMAC + timingSafeEqualString, 5๋ถ ๋ฆฌํ๋ ์ด ์๋, agent ๋ณ ์ํฌ๋ฆฟ |
| Telegram webhook | X-Telegram-Bot-Api-Secret-Token |
์ด ํ๋ซํผ์ด webhook ์ ๋ฑ๋กํ ๋ ์ด agent ๋ณ ์ํฌ๋ฆฟ(asg_โฆ)๊ณผ timingSafeEqualString ๋น๊ต. Telegram ์ด ๋ฐฐ๋ฌ๋ง๋ค ๊ทธ๋๋ก ๋๋๋ ค์ฃผ๋ฉฐ, ๊ทธ ๋ฐ์ ํ์ธํ ์๋ช
์ ์๋ค |
| Teams messaging endpoint | Bot Framework bearer ํ ํฐ (JWT) | RS256 ์๋ช
์ ์๋น์ค๊ฐ ๊ณต๊ฐํ JWKS(login.botframework.com) ๋ก ๊ฒ์ฆํ๊ณ , ๋ฐ๊ธ์ https://api.botframework.com, audience = ๊ทธ ๋ด์ App ID, exp/nbf(5๋ถ skew), ๊ทธ๋ฆฌ๊ณ serviceurl ํด๋ ์ = activity ์ serviceUrl ์ ์๊ตฌํ๋ค. ๋ต์ ๊ทธ ์ฃผ์๋ก ์ด ์ฑ์ ํ ํฐ์ ๋ถ์ฌ ๋๊ฐ๋ฏ๋ก. Emulator ํ ํฐ์ ๋ฐ์ง ์๋๋ค (src/infrastructure/teams/client.ts) |
| Webhook trigger | X-Trigger-Secret ๋๋ GitHub X-Hub-Signature-256 |
๊ฐ์ธ Webhook ํ ํฐ์ ์์ ์๊ฐ ๋น๊ต ๋๋ ๊ณต๊ฐ credential ์๋ณ์๋ก ์ ํํ ํ ํฐ์ HMAC-SHA256 ๊ฒ์ฆ. ๋ฐ๊ธ ์ฌ์ฉ์ ID๋ก ํ์ฌ ๊ณ์ ยทAgent ์ ๊ทผ์ ํ์ธํ๋ค. GitHub ํค๋๊ฐ ์์ผ๋ฉด ์๋ช ๊ฒ์ฆ์ ๊ฐ์ ํ๊ณ ์ผ๋ฐ ์ํฌ๋ฆฟ์ผ๋ก ํด๋ฐฑํ์ง ์๋๋ค. ์๋ช ๋ ping์ ์คํํ์ง ์์ผ๋ฉฐ GitHub delivery ID๋ก ์ค๋ณต์ ์ฐจ๋จํ๋ค |
| Workspace GitHub webhook | X-Hub-Signature-256๊ณผ X-GitHub-Delivery |
๋ณ๋ ๋ฐฐํฌ ์ํฌ๋ฆฟ์ผ๋ก ๊ฒ์ฆํ๊ณ PR/CI ๋ฉํ๋ฐ์ดํฐ๋ง ๊ฐฑ์ ํ๋ค. Git ์คํ ์น์ธ์ด ์๋๋ค |
CronJob ํฑ. schedule ์ค์บ(/api/triggers/scan), ์นดํ๋ก๊ทธ ์ฌ์์ธ(/api/catalog/reindex), plugins sync(/api/plugins/sync/scan) |
X-Scan-Token |
SCHEDULE_SCAN_TOKEN ๊ณผ timingSafeEqualString ๋น๊ต. ์ค์ ๋ผ ์์ง ์์ผ๋ฉด 503 ์ผ๋ก ๋ตํ๊ณ , ๊ฑฐ๋ถ๋ token ์ ์
๋ชจ๋์์ ๊ฒฝ๊ณ ๋ฅผ ๋ก๊ทธ์ ๋จ๊ธด๋ค |
ํ๋์ token ์ด ์ธ ํฑ์ ๋ชจ๋ ์ฐ๋ค. ์ธ endpoint ์ ์ฒด์ ์ฐ๊ธฐ ๊ถํ์ ์ฃผ๋ ๋ฐฐํฌ credential์ด๋ค. CronJob ์ด ์ด๋ค schedule ์ด ๋๋ํ๋์ง ๋ฌผ์ ์ ์๊ฒ ํด ์ฃผ๋ ๊ทธ ๋ฌธ์์ด์ด plugins sync ๋ ์คํํ๊ณ , ๊ทธ sync ๋ ๋ ๋ ์ง์คํธ๋ฆฌ skill ๊ณผ MCP ์๋ฒ. ๋ฅผ ๋ชจ๋ ์ด๋ค. ์ ์ฅ์๊ฐ ์ ์ธํ ์ด๋ฆ์ ์ฑํํ๊ณ provenance ๋ฅผ ๊ทธ๊ฒ์ผ๋ก ๋ค์ ์ด๋ค. ๊ทธ๊ฒ์ ํ๋ก๋ธ๊ฐ ์๋๋ผ ์ฐ๊ธฐ ์๊ฒฉ ์ฆ๋ช ์ผ๋ก ๋ฒ์๋ฅผ ์ก๊ณ ํ์ ์์ผ๋ผ.
trigger ์ํฌ๋ฆฟ์ ํ์ฑํ ํ๋๊ทธ๋ฅผ ์ฝ๊ธฐ ์ ์ ๋น๊ต๋๋ค. ๋นํ์ฑ trigger ๊ฐ ํ๋ฆฐ ์ํฌ๋ฆฟ์ ํ์ฑ trigger ์ ๋ค๋ฅด๊ฒ ๋ตํ ์ ์๊ฒ ํ๊ธฐ ์ํด์๋ค. ๊ทธ ์ฐจ์ด๋ ์ด๋ค trigger ๊ฐ ์กด์ฌํ๋์ง์ ๋ํ ์ค๋ผํด์ด๋ค.
์์ ์๊ฐ ๋น๊ต๋ ์์ ์๊ฐ ํ๋, src/shared/timingSafe.ts ์ด๊ณ
tests/architecture.test.ts ๊ฐ ๊ณ ์ ํ๋ค.
๋ฆฌํ๋ ์ด ์ต์ ๋ Slack event_id, Telegram์ agentยทbotยทupdate_id,
Teams์ agentยทApp IDยทconversationยทactivity ID๋ฅผ ํค๋ก ํ ์กฐ๊ฑด๋ถ claim์ ์ฌ์ฉํ๋ค.
์๋ฃ claim์ ์ค๋ณต์ ๋ง๊ณ , ์คํจ ๋๋ ๋ง๋ฃ๋ ์ฒ๋ฆฌ lease๋ ์ฌ์ ๋ฌ ์ ๋ค์ claimํ ์ ์๋ค.
ACK ํ ์คํํ๋ ๊ณผ์ ๊ณผ ์ธ๋ถ ๋๊ตฌ ํจ๊ณผ๋ฅผ ํ๋์ transaction์ผ๋ก ๋ฌถ์ง๋ ์์ผ๋ฏ๋ก
end-to-end exactly-once๋ฅผ ๋ณด์ฅํ์ง ์๋๋ค. ํ๋ซํผ์ด ์ฌ์ ๋ฌํ์ง ์์ผ๋ฉด ์ ์ค ์ด๋ฒคํธ๋ฅผ
์ค์ค๋ก ๋ณต๊ตฌํ๋ worker๋ ์๋ค. Agent webhook์ ๋ฉฑ๋ฑ ๊ณ์ฝ์ Trigger ์ค๊ณ๋ฅผ ๋ฐ๋ฅธ๋ค.
Teams signing metadata๋ HTTP ์ฑ๊ณต ์๋ต๋ง ์ฌ์ฉํ๋ค. ์กฐํ ์คํจ๋ ์ฌ์๋ ๊ฐ๊ฒฉ์ ํฌํจํ๋ฉฐ ๋ง๋ฃ๋ ํค๋ฅผ ์ฅ์ ์ค ์ธ์ฆ์ ์ฌ์ฉํ์ง ์๋๋ค. ์กฐํยท์บ์์ ํ์ฌ ๊ณ์ฝ์ Teams ์ค๊ณ๋ฅผ ๋ฐ๋ฅธ๋ค.
JSON ๋ณธ๋ฌธ์ schema ๊ฒ์ฆ ์ ์ bounded reader๋ฅผ ์ง๋๋ค. ๊ด๋ฆฌยทํธ์ง ์์ฒญ์ Skill ์ ์ฒด ํ์ผ ํ๋์์
ํ์ํ editor ํ๋, ์ด๋ฏธ์งยท๋ฌธ์๋ฅผ ์ค์ ์ ์๋ ์คํ ์์ฒญ์ attachment ํ๋์์ ํ์ํ turn
ํ๋๋ฅผ ์ด๋ค. ๋ชจ๋ธ ๋ฑ๋ก์ editor ํ๋๋ฅผ ์ฌ์ฉํ๋ค. webhook ๋ค ์ข
๋ฅ๋ ์๋ช
๊ฒ์ฆ์ ํ์ํ raw
๋ณธ๋ฌธ์ ๊ณตํต 1MB ํ๋ ์๋์์ ์ฝ๋๋ค. ์ ์ธ๋ Content-Length๊ฐ ํ๋๋ฅผ ๋์ผ๋ฉด body๋ฅผ ์ฝ์ง ์๊ณ
413์ ๋ตํ๊ณ , chunked body๋ ๋์ ๋ฐ์ดํธ๊ฐ ํ๋๋ฅผ ๋๋ ์ฆ์ stream์ ์ทจ์ํ๋ค.
256KiB prose allowance๋ฅผ ๋๋ ํฐ ์คํ ๋ณธ๋ฌธ์ ํ๋ก์ธ์ค ๋จ์์ ๋ฐ์ดํธ ์์ฐ์ ๊ณผ๊ธ๋๋ค.
์์ฐ์ ์ต๋ turn ๋ณธ๋ฌธ ๋ ๊ฐ ๋ถ๋์ด๊ณ , ์์ฒญ์ ์๊ธฐ๊ฐ ์ค์ ๋ก ์ฝ์ ๋ฐ์ดํธ๋งํผ๋ง ์ด๋ค. ๊ณผ๊ธ์
ํ์ฑ๋ถํฐ run ๋๋ stream์ด ์
๋ ฅ์ ๋์ ๋๊น์ง ์ ์ง๋๊ณ , ์ฐ๊ฒฐ์์ ๋ถ๋ฆฌ๋์ด ๊ณ์ ๋๋ chat์
๋ด๋ถ drain ์๋ฃ๊น์ง ์ ์งํ๋ค. ์ผ๋ฐ text turn์ ์๋ฌด๊ฒ๋ ์ฐ์ง ์๋๋ค. ์์ฐ์ด ๋ชจ์๋ผ๋ฉด body๋ฅผ
์ทจ์ํ ๋ค Retry-After๋ฅผ ํฌํจํ 429๋ฅผ ๋ตํ๋ค.
์์ฐ์ ์์ฒญ ์๊ฐ ์๋๋ผ ๋ฉ๋ชจ๋ฆฌ์ ์ ์งํ๋ ํฐ ๋ณธ๋ฌธ์ ๋ฐ์ดํธ๋ฅผ ์ผ๋ค. ์ ํํ ์ํ๊ณผ ์์ ํ์ผ์ ๊ณ ์ ์ ํ์ ๋ฐ๋ฅธ๋ค.
tests/architecture.test.ts๋ API route์ ์ง์ request.json()๊ณผ request.formData() ํธ์ถ์
๊ฑฐ๋ถํ๋ค. Zod์ ํ๋ ํฌ๊ธฐ ๊ฒ์ฌ๋ ํ์ฑ ๋ค์ ๊ฐ ๊ท์น์ด์ง, ํ์ฑ ์ ์ ๋ฐ์ํ๋ ๋ฉ๋ชจ๋ฆฌ ํ ๋น ์ ํ์ด
์๋๋ค.
Cookie session์ผ๋ก ์ธ์ฆํ๋ POSTยทPUTยทPATCHยทDELETE๋ Origin์ด request origin ๋๋
์ค์ ๋ PUBLIC_BASE_URL origin๊ณผ ์ ํํ ๊ฐ์์ผ ํ๋ค. ๋ฉํฐ ๋๋ฉ์ธ์์๋ ํ์ฉ ๋ชฉ๋ก์ ์๋
์์ฒญ Host์ ์ธ์ฆ ์ค์ ์ ํ๋กํ ์ฝ๋ก ๋ง๋ origin๊ณผ ์ ํํ ๊ฐ์์ผ ํ๋ฉฐ, ๋ค๋ฅธ ํ์ฉ ๋๋ฉ์ธ์
origin๋ ๊ฑฐ๋ถํ๋ค. Origin์ด ์๊ฑฐ๋ null์ด๊ฑฐ๋ URL๋ก
ํด์๋์ง ์์ผ๋ฉด 403์ด๋ค. ์ธ session wrapper๊ฐ ์ผ๋ฐ console API๋ฅผ ํ ๋ฒ์ ๋ณดํธํ๊ณ , agent
์คํ API๋ Authorization ํค๋๊ฐ ์์ ๋๋ง cookie session์ ์ฌ์ฉํ๋ฉฐ ๊ฐ์ ๊ฒ์ฌ๋ฅผ
์ ์ฉํ๋ค. bearer token, webhook signature์ฒ๋ผ cookie๋ฅผ ์ฐ์ง ์๋ ๋จธ์ ํธ์ถ์๋ CSRF
๊ฒ์ฌ๋ฅผ ์ ์ฉํ์ง ์๋๋ค.
๋ฆฌ๋ฒ์ค ํ๋ก์ ๋ฐ์ origin๊ณผ ์ฑ์ด ๋ณด๋ request origin์ด ๋ค๋ฅด๋ฉด ๋จ์ผ ๋๋ฉ์ธ์ PUBLIC_BASE_URL์
์ค์ ํ๊ณ , ๋ฉํฐ ๋๋ฉ์ธ์ BETTER_AUTH_ALLOWED_HOSTS๋ฅผ ์ค์ ํ ๋ค ์๋ Host๋ฅผ ์ ๋ฌํ๋ค.
next.config.ts๋ ์ผ๋ฐ ๊ฒฝ๋ก์ framing ์ฐจ๋จ CSP,
X-Frame-Options: DENY, nosniff, strict-origin-when-cross-origin์ ์ ์ฉํ๋ค.
์ผ๋ฐ ์ฝ์์๋ script/style์ ๋ก๋๋ฅผ ์ ํํ๋ CSP๊ฐ ์์ผ๋ฏ๋ก ์ด ์ ์ฑ
์ด script injection๊น์ง
์ฐจ๋จํ๋ค๊ณ ๋ณด์ง ์๋๋ค.
/api/artifacts/{id}/view์ /api/objects/*๋ ์ด ๊ท์น์์ ์ ์ธํ๊ณ ๊ฐ route๊ฐ ์์ฒด sandbox
์ ์ฑ
์ ์ค์ ํ๋ค. ์ค๋ฅ ์๋ต์๋ ํค๋๊ฐ ํ์ํ๋ค. ๋ผ์ฐํธ์ CSP๋ฅผ ๋ฐ๊ฟ ๋๋ ์ ์ญ ํค๋๊ฐ
๋ฎ์ด์ฐ์ง ์๋์ง ์ค์ ์๋ต์ ํ์ธํ๋ค. ํ์ผ๋ณ ์ ์ฑ
์ ๋ฐ์ดํฐ ๋
ธ์ถ๊ณผ ๋ณด์กด์ ๋ฐ๋ฅธ๋ค.
์ด์์๊ฐ ๋ฑ๋กํ MCP ์๋ฒ URL์ src/infrastructure/net/ssrfGuard.ts๊ฐ
๋ฑ๋ก ์์ ๊ณผ ๋์คํจ์น ์์ ๋ชจ๋ ์์ ๊ฒ์ฆํ๋ค. ๊ฑฐ๋ถ๋๋ ๊ฒ: http(s) ๊ฐ ์๋ ์คํด,
userinfo ๋ฅผ ์ค์ URL(https://user:pass@host, ์ฃผ์ ์์ ์๊ฒฉ ์ฆ๋ช
์ ์ฌ๊ธฐ์ ๋ฌด์ธ๊ฐ๋ฅผ ์ธ์ฆํ๋
๋ฐฉ์์ด ์๋๊ณ , ํธ์คํธ๋ฅผ ๋ค๋ฅธ ๊ฒ์ฒ๋ผ ์ฝํ๊ฒ ๋ง๋๋ ์ํฌ์ ์๋จ์ด๋ค), ๊ทธ๋ฆฌ๊ณ
์ฌ์คยท๋ฃจํ๋ฐฑยท๋งํฌ๋ก์ปฌ(ํด๋ผ์ฐ๋ ๋ฉํ๋ฐ์ดํฐ ์ฃผ์ 169.254.169.254 ํฌํจ) ๋๋ ๊ทธ ๋ฐ์ ์์ฝ ๋์ญ์ผ๋ก
ํด์๋๋ ํธ์คํธ.
DNS ์กฐํ๊ฐ ์์ธ๋ก ์คํจํ๋ฉด ์ฃผ์ ๊ฑฐ๋ถ๋ก ๋ฐ๊พธ์ง ์๊ณ ํธ์ถ ์คํจ๋ก ์ ๋ฌํ๋ค. ์กฐํ๊ฐ ์ ์์ ์ผ๋ก
๋๋ฌ์ง๋ง ์ฃผ์๊ฐ ์๊ฑฐ๋ ๊ธ์ง ๋์ญ์ ํฌํจํ๋ฉด ๊ฑฐ๋ถํ๋ค.
IPv6 ๋ ์ฃผ์ ํ๋์ ์ฒ ์๊ฐ ์ฌ๋ฟ์ด๋ฏ๋ก, ํ
์คํธ๊ฐ ์๋๋ผ 8๊ฐ ๊ทธ๋ฃน์ผ๋ก ํผ์น ๊ฐ์ผ๋ก ํ์ ํ๋ค.
IPv4 ๋ฅผ ์์ ๋ด๋ ์ ๋์ฌ(IPv4-mapped, IPv4-compatible, NAT64 64:ff9b::/96, 6to4
2002::/16)๋ ํต์งธ๋ก ๋ง์ง ์๊ณ ๋ด๊ธด IPv4 ๋ก ํ์ ํ๋ค โ IPv6 ์ ์ฉ ๋ง์์ ๊ณต์ธ ์ฃผ์์
๋ฟ๋ ์ ์ ๊ฒฝ๋ก๊ฐ ๊ทธ๊ฒ์ด๊ธฐ ๋๋ฌธ์ด๋ค. 64:ff9b::8.8.8.8 ์ ํต๊ณผํ๊ณ 64:ff9b::10.0.0.1 ์
๊ฑฐ๋ถ๋๋ค.
์ด registry์ ๊ณต๊ฐ ์ฃผ์ ๋์คํจ์น๋ fetchPublicUrl(src/infrastructure/net/publicFetch.ts)์ ์ง๋๋ค.
๋ฐฐํฌ๊ฐ ์ง์ ํ LLMยท์ธ์ฆยท์คํ ๋ฆฌ์งยท์นดํ๋ก๊ทธ endpoint๊น์ง ๋ชจ๋ ์ด ๊ฐ๋๋ก ๊ฒ์ฌํ๋ ๊ฒ์ ์๋๋ค.
๊ทธ ์ฃผ์๋ค์ ๋ฐฐํฌ ์ค์ ์ ์ ๋ขฐ ๊ฒฝ๊ณ๋ค.
LLM ์ ๊ณต์ ์์ฒญ์ src/infrastructure/llm/providerFetch.ts์์ ๋ชจ๋ redirect๋ฅผ ๊ฑฐ๋ถํ๋ค.
SDK์ ์ฑํ
ยท์๋ฒ ๋ฉยท์ด๋ฏธ์ง ์์ฒญ, SigV4, decisionยทrerankยท์ค๋์ค, Workspace์ native ์์ฒญ๊ณผ
์ ๊ณต์ discoveryยท์ฐ๊ฒฐ probe๊ฐ ๊ฐ์ ๊ท์น์ ์ ์ฉํ๋ค. ๋ฐ๋ผ์ 307/308 ์๋ต์ผ๋ก ํ๋กฌํํธยท๋ฌธ์ยท
์ค๋์คยท์๊ฒฉ ์ฆ๋ช
์ ๋ค๋ฅธ ์ฃผ์์ ๋ค์ ๋ณด๋ด์ง ์๋๋ค. ์ ๊ณต์๋ ์ต์ข
endpoint๋ก ๋ฑ๋กํ๋ค.
๊ณต๊ฐ registry ์์ฒญ์๋ ๋ค์ ๊ฒ์ฌ๋ฅผ ์ ์ฉํ๋ค:
- DNS๋ ๋ชจ๋ ์์ฒญ๊ณผ redirect ํ์์ ๋ค์ ํ์ธํ๊ณ ์ปค๋ฅ์ ์ ๊ฒ์ฆํ ์ฃผ์์ ๊ณ ์ ํ๋ค. ๋ฑ๋ก ์ ๊ฒ์ฆ๋ง์ผ๋ก ์ฐ๊ฒฐ์ ์์ ์ ๋ณด์ฅํ์ง ์๋๋ค.
- ๋ค์ดํฐ๋ธ ๋ฆฌ๋ค์ด๋ ํธ ์ถ์ข ์ ๊บผ์ ธ ์๊ณ ๊ต์ฐจ ์ถ์ฒ ๋ฆฌ๋ค์ด๋ ํธ๋ ๊ฑฐ๋ถํ๋ค. ์ ์ฅ๋ ์๊ฒฉ ์ฆ๋ช ์ด ๋ค๋ฅธ ํธ์คํธ๋ก ์ ๋ฌ๋ ์ ์๊ฒ ํ๊ธฐ ์ํด์๋ค.
- ๋์คํจ์ฒ๋ ์ปค๋ฅ์
์ฌ์ฌ์ฉ์ ์ํด
origin|pinned address๋ณ๋ก ํ๋ง๋๋ค. ์ด๊ฒ์ด ์บ์ํ๋ ๊ฒ์ ์ ์ก ๊ณ์ธต๋ฟ ์ด๋ค. ๊ฐ๋๋ ์ฌ์ ํ ์์ฒญ๋ง๋ค ๋๊ธฐ ๋๋ฌธ์, ์ฌ์ค ์ฃผ์๋ก ํด์๋๊ธฐ ์์ํ ํธ์คํธ๋ ํ๋ง๋ ๋์คํจ์ฒ์ ๋ฟ๊ธฐ ์ ์ ๊ฑฐ๋ถ๋๊ณ , ๋ค๋ฅธ ๊ณณ์ผ๋ก ํด์๋๋ ํธ์คํธ๋ ๋ค๋ฅธ ํค๋ฅผ ๋ฐ๋๋ค.
Slack ์ด๋ฏธ์ง ์
๋ก๋์ files.getUploadURLExternal ์๋ต์ HTTPS files.slack.com/upload/v1/
์ฃผ์์ธ์ง ํ์ธํ ๋ค ๋ฐ์ดํธ๋ฅผ ๋ณด๋ด๋ฉฐ, ์
๋ก๋ ์์ฒญ์ redirect๋ ๋ฐ๋ฅด์ง ์๋๋ค.
๋ชจ๋ธ ์
๋ ฅ์ ์ด๋ฏธ์ง๋ URL๋ก ๊ฐ์ ธ๊ฐ์ง ์๋๋ค. ์คํ API๋ ์ง์ํ๋ ์ด๋ฏธ์ง
๋ฐ์ดํธ๋ฅผ ์์ฒญ ์์ ์ธ๋ผ์ธ์ผ๋ก ๋ฐ์ผ๋ฉฐ, LLM ์ฑ๋์ ๋ชจ๋ image_url์ด bounded data: URL์ธ์ง
๋ง์ง๋ง์ผ๋ก ๋ค์ ํ์ธํ๋ค. https://๋ง ๊ฒ์ฌํ ๋ค ์๊ฒฉ URL์ ์ ๊ณต์์๊ฒ ๊ทธ๋๋ก ๋๊ธฐ๋ฉด ์์ฒญ์ ์ด
์ฑ์ด ์๋๋ผ ์ ๊ณต์ ๋คํธ์ํฌ์์ ๋ฐ์ํ๋ค. ๊ทธ ๊ฒฝ๋ก์๋ fetchPublicUrl์ DNSยท์ฃผ์ยทredirect
๊ฒ์ฌ๊ฐ ๋ฟ์ง ์์ผ๋ฏ๋ก ํ์ฉํ์ง ์๋๋ค. ๋ชจ๋ธ์ด ์น์ ์ด๋ฏธ์ง๋ฅผ ์ฝ์ด์ผ ํ๋ฉด FetchUrl ๋๊ตฌ๊ฐ ์ด
์ฑ์ ์์๋ฐ์ด๋ ๊ฒฝ๊ณ๋ก ๋ฐ์ดํธ๋ฅผ ๊ฐ์ ธ์ ๊ฐ์ inline ํ์์ผ๋ก ๋๋ ค์ค๋ค.
๊ณต๊ฐ URL ์ด๋ฉด ๋ฌด์์ด๋ ํ์ฉ๋๋ค. ์ ๋ขฐํ๋ ์๋ํฌ์ธํธ๋ง ๋ฑ๋กํ๋ผ. Registry endpoint URL ์
userinfo, query parameter ์ fragment ๋ฅผ ๋ฐ์ง ์๋๋ค. ์ด ๊ฐ๋ค์ ๋ฉค๋ฒ๊ฐ ์ฝ๋ registry view ์ ์ด์ ๋ก๊ทธ์์
์๊ฒฉ ์ฆ๋ช
์ ๋
ธ์ถํ๊ธฐ ์ฌ์ฐ๋ฏ๋ก, ์ธ์ฆ ์ ๋ณด๋ encrypted header ๋๋ OAuth ์ฐ๊ฒฐ์ ๋๋ค. ์ด์ ํ์
๋จ์ userinfo, query ์ fragment ๋ ์ ์ฅ๋ ์ฃผ์์๋ง ๋จ๊ณ reader-facing view ์์๋ ์ ๊ฑฐํ๋ค. ์ด ๊ท์น์
์ฃผ์๊ฐ ์ค์ ๋ก ๋ฐ๋ ๋๋ง ์ ์ฉํ๋ค. ์ ์ฅ๋ ์ฃผ์๋ฅผ ๊ทธ๋๋ก, ๋๋ ์ฝ์์ด ๋ณด์ฌ ์ค redacted ํํ๋ก
๋๋๋ ค ๋ณด๋ด๋ ์ ์ฅ์ ์ด๋์ด ์๋๋ฏ๋ก ๊ฑฐ์ ํ์ง๋, ์ ์ฅ๋ credential ์ ๋ฒ๋ฆฌ์ง๋ ์๋๋ค
(resolveRegistryUrlPatch). ๊ทธ๋ฌ์ง ์์ผ๋ฉด ํธ์ง ํผ์ด ์๊ธฐ๊ฐ ์ฝ์ ๊ฐ์ ๋๋๋ ค ๋ณด๋ด๋ ๊ฒ๋ง์ผ๋ก
๋ ๊ฑฐ์ ํญ๋ชฉ์ด ๋ค๋ฅธ endpoint ๋ฅผ ๊ฐ๋ฆฌํค๊ฒ ๋๊ณ , ์๋ ์ฃผ์๋ ๋ค์ ์
๋ ฅํ ์๋ ์๋ค.
LLM provider์ ์ด๋ฆยท์ข
๋ฅยทendpointยท์ธ์ฆ ๋ฐฉ์๊ณผ credential์ ํ ๋ณด์ ๋จ์๋ค.
๋ฑ๋ก provider์ endpointยท์ข
๋ฅยท์ธ์ฆ ๋ฐฉ์์ ๋ฐ๊พธ๋ฉด ๊ธฐ์กด key์ ๋ง์คํฌยท๋น ์
๋ ฅ์ผ๋ก ์ฎ๊ธธ ์ ์๋ค.
key๊ฐ ํ์ํ ์ ์ฐ๊ฒฐ์๋ ์ ๊ฐ์ ์
๋ ฅํ๋ฉฐ SigV4๋ API key ์์ด AWS credential chain์ ์ฌ์ฉํ๋ค.
์คํ ๋ชจ๋ธ์ Settings์์ ์ ํํ ๋ฑ๋ก ๋ชจ๋ธ์ด์ด์ผ ํ๋ค. ๊ธฐ๋ณธ ๋ชจ๋ธ ์ ํ์ด ๋ณ๋ ๊ธฐ๋ณธ ์ฑ๋์ ๋ง๋ค์ง๋ ์๋๋ค.
MCP ํด๋ผ์ด์ธํธ๋ @modelcontextprotocol/client ์์์ ๋๊ณ , ๊ฐ๋๋ ๊ทธ ์์ ๋์ด๋ ๋์ ๊ทธ ์์ผ๋ก
์ฃผ์
๋๋ค. ํธ๋์คํฌํธ์ fetch ๋ก ์ฃผ์ด์ง๋ ๊ฒ์ด
boundedFetch(src/infrastructure/mcp/session.ts)์ด๋ฏ๋ก ํ๋ก๋ธ, ํธ๋์
ฐ์ดํฌ, ๋ชจ๋ ๋๊ตฌ ํธ์ถ,
์ธ์
ํด์ ๊น์ง ์ ๋ถ ๊ฐ์ ๊ฒฝ๊ณ๋ฅผ ์ง๋๋ค. SDK ๋ฅผ ์๊ธฐ fetch ์ ๋งก๊ฒจ ๋๋ฉด ์ด์์๊ฐ ๋ฃ์ URL ์
๊ณง์ฅ ๋คํธ์ํฌ๋ก ๊ฐ์ ธ๊ฐ ๊ฒ์ด๋ค. ๊ฐ์ ๋ํผ๊ฐ ์๋ต ๋ฐ์ดํธ ์ํ๋ ํจ๊ป ๋๋ฅด๋๋ฐ, SDK ์๋ ๊ทธ๋ฐ ๊ฐ๋
์์ฒด๊ฐ ์๋ค.
ํด๋ฌ์คํฐ์์ ์ด ์ฑ์ด ๋ถ๋ฅด๊ธฐ๋ก ๋์ด ์๋ MCP ์๋ฒ๋ค์ ๊ตฌ์กฐ์ ์ฌ์ค์ด๋ค. Kubernetes Service ๋
๊ฐ๋๊ฐ ๊ฑฐ๋ถํ๋ ClusterIP ๋ก ํด์๋๋ค. MCP_INTERNAL_HOST_SUFFIXES ๋ ๋ฐฐํฌ๊ฐ ๊ทธ ์ด๋ฆ๋ค์ด
๋ฌด์์ธ์ง ๋ฐํ๋ ๋ฐฉ๋ฒ์ด๋ค:
MCP_INTERNAL_HOST_SUFFIXES=agent-mcps.svc.cluster.local
๋ก์ปฌ ์ฑ์ MCP๋ฅผ ์ฐ๊ฒฐํ๋ ค๋ฉด localhost๋ฅผ ๋ช
์์ ์ผ๋ก ์ถ๊ฐํ๋ค. ์๋ฅผ ๋ค์ด
MCP_INTERNAL_HOST_SUFFIXES=agent-mcps.svc.cluster.local,localhost๋
http://localhost:3100/api/organizations/opspresso/mcp๋ฅผ ํ์ฉํ๋ค. localhost๋ ์ ํํ
๊ทธ ํธ์คํธ๋ง ํ์ฉํ๋ฉฐ ํ์ ๋๋ฉ์ธ๊ณผ IP ์ฃผ์๋ ํฌํจํ์ง ์๋๋ค. ๊ธฐ๋ณธ๊ฐ์ ๊ณ์ ์ฐจ๋จ์ด๋ฉฐ,
์ด MCP ์ค์ ์ ์ถ๊ฐํด๋ ๋ชจ๋ธ์ FetchUrl ํ์ฉ ๋ชฉ๋ก์ ๋ฐ๋์ง ์๋๋ค.
์ ์ธ๋ ์ ๋ฏธ์ฌ ์๋์ ํธ์คํธ๋ ๊ทธ ์ง๋ฌธ์ด ๋์ ธ์ง๋ ๋ชจ๋ ๊ณณ์์ public URL ๊ฐ๋๋ฅผ ๊ฑด๋๋ด๋ค.
ํญ๋ชฉ์ ๋ฑ๋กํ ๋์ ํธ์งํ ๋, ์ฝ์์ "Test connection" ํ๋ก๋ธ, admin ์ด ํญ๋ชฉ์ OAuth ๋ฉํ๋ฐ์ดํฐ๋ฅผ
์ฝ์ ๋, agent ์์ ์ ๋๊ตฌ ๋ชฉ๋ก, ๊ทธ๋ฆฌ๊ณ ๋์คํจ์น. ๊ฐ๊ฐ skipsUrlGuard ๋ฅผ ํตํด์๋ค. ์ฐจ๋จ๋
์ฃผ์ ๋์ญ์ด ๋์ด์ง๋ ๊ฒ์ ์๋๋ค. ๋ค๋ฅธ ๋ชจ๋ ํญ๋ชฉ์ ์ฌ์ ํ ์๋ ๋ฐ๋ ๊ฒ์ฌ๋ฅผ ๋ฐ๋๋ค. ์ด๊ฒ์
๊ฐ๋๋ฅผ ๋์จํ๊ฒ ํ๋ ๊ฒ์ด ์๋๋ผ managed ๋ฃจํ๋ฐฑ ์์ ๋์ธ ๋ ๋ฒ์งธ ์ข์ ์์ธ๋ค.
๋ด๋ถ ์ฃผ์ ์์ธ๋ ์๋ redirect ์ถ์ข
์ ํ์ฉํ์ง ์๋๋ค. MCP ์ธ์
ยทOAuth ๋ฉํ๋ฐ์ดํฐยท๋ด๋ถ
FetchUrl์ src/infrastructure/net/redirectPolicy.ts์ fetchSameOrigin์ ํตํด ์ต๋ 5ํ๋ง
๊ฐ์ ์ถ์ฒ๋ก ์ด๋ํ๋ค. ๊ณต๊ฐ URL๋ ๊ฐ์ redirect ๊ท์น์ ์ฌ์ฉํ๋ฉฐ, ๊ฐ ์์ฒญ ์ง์ ์ DNS๋ฅผ ๊ฒ์ฆํ๊ณ
ํ์ธ๋ ์ฃผ์๋ก ์ฐ๊ฒฐํ๋ค. ๋ค๋ฅธ ์ถ์ฒ๋ก ์ด๋ํ๋ ์๋ต์ ๋ณธ๋ฌธ์ ํด์ ํ ๋ค ๊ฑฐ๋ถํ๋ค.
์ด๋ฆ์ ๋ง์ถ๋ ์ ์ด๋ ํ๋๋ค. src/domain/security/internalHosts.ts ์
isDeclaredInternalHost. ๊ทธ๋ฆฌ๊ณ ๋ชฉ๋ก์ ๋์ด๋ค. MCP_INTERNAL_HOST_SUFFIXES ๋ ์ด ์ฑ์ด
๋ถ๋ฅด๊ธฐ๋ก ๋์ด ์๋ ์๋น์ค๋ฅผ, URL_FETCH_INTERNAL_HOST_SUFFIXES ๋ ๋ชจ๋ธ์ด
์ฝ์ด๋ ๋๋ ํ์ด์ง๋ฅผ ๋งํ๊ณ , ๋ ๋ชฉ๋ก์ ์๋์ ์ผ๋ก ์๋ก๋ฅผ ๋ชจ๋ฅธ๋ค. ์ ์ด๊ฐ domain ์ ์ค๋ฆฝ ๋ชจ๋์
์๋ ์ด์ ๊ฐ ๊ทธ๊ฒ์ด๋ค: skipsUrlGuard(MCP ์ชฝ, provenance ์ ํฉ์น ํํ) ์์ ๋๋ฉด FetchUrl
๋ฆฌ๋๊ฐ MCP ๋ชจ๋์ import ํ๊ฒ ๋๋๋ฐ, ๊ทธ ๋ฆฌ๋๋ MCP ๋ชฉ๋ก์ ์ฝ์ด์๋ ์ ๋๋ค.
๊ทธ ์ข์์ด ์ค๊ณ์ ์ ๋ถ์ด๊ณ , ๊ฐ ๋ถ๋ถ์ tests/internalHosts.test.ts ๊ฐ ๊ณ ์ ํ๋ค:
- ์ค์ ์ผ๋ก๋ง. ๋ชฉ๋ก์ ํ๊ฒฝ์์ ์จ๋ค. ๋ ์ง์คํธ๋ฆฌ ํญ๋ชฉ์ด ์๊ธฐ ์์ธ๋ฅผ ์ค์ค๋ก ์ง์ ํ ์ ์๊ณ , ์๋์ ์ผ๋ก ๋ฐํ์ ์ค์ ์ด ์๋๋ค. ์์๋ฐ์ด๋ ๊ฒฝ๊ณ๋ฅผ ๋ํ๋ ์ผ์ ๊ทธ๋ admin ์ ์ฅ ์ฌ๋์ด ์ ์ถํ๋ ํผ์ด ์๋๋ผ ๋ฐฐํฌ๋ฅผ ๊ฑฐ์ณ์ผ ํ๋ค.
- ๋ ์ด๋ธ ๋จ์๋ก ๊ณ ์ .
agent-mcps.svc.cluster.local์mcp-url-fetch.agent-mcps.svc.cluster.local์ ํ์ฉํ๊ณevil-agent-mcps.svc.cluster.local์ ๊ฑฐ๋ถํ๋ค. ๋จ์ํ "โฆ๋ก ๋๋๋ค"์๋ค๋ฉด ํต๊ณผ์์ผฐ์ ์์ฌ์์ฌํ ๊ฒฝ์ฐ๋ค. ์์ ๋ถ์ ์ ์ ํ์ฉ๋๋ฉฐ ๊ฐ์ ๋ป์ด๋ค. - ๋จ์ผ ๋ ์ด๋ธ ์ ๋ฏธ์ฌ๋ ์๋ค.
local์ด๋internal์ ์ด๋ฆ ๊ณต๊ฐ ํ๋๋ฅผ ํต์งธ๋ก ํ์ฉํ๊ฒ ๋๋ค. ์๋๋ผ๊ธฐ๋ณด๋ค ์คํ์ผ ๊ฐ๋ฅ์ฑ์ด ํจ์ฌ ๋์ผ๋ฏ๋ก ์กด์คํ์ง ์๋๋ค. ๋ช ์ํlocalhost๋ง ์ ํํ ํธ์คํธ ์ผ์น๋ก ํ์ฉํ๋ฉฐ, ์ ๋ฏธ์ฌ๋ก ํ์ฅํ์ง ์๋๋ค. - IP ๋ฆฌํฐ๋ด์ ๊ฒฐ์ฝ ์ ๋๋ค. ๊ทธ ์์ธ๋ ๋๊ตฐ๊ฐ ๊ฒ์ํ ์ด๋ฆ์ ์ํ ๊ฒ์ด๋ค. ์ฃผ์์๋ ๋ง์ถ ์ด๋ฆ์ด ์์ผ๋ฏ๋ก, ์ฌ์ค ์ฃผ์๋ ์ฌ์ ํ provenance ๋ก ์๊ธฐ ๊ธธ์ ์ป์ด์ผ ํ๋ค.
http(s)๋ง, ๊ทธ๋ฆฌ๊ณ userinfo ๋ก ํธ์คํธ ๊ฒ์ฌ๋ฅผ ์ง๋์ณ ์ ๋ฏธ์ฌ๋ฅผ ๋ฐ๋ฐ์ ํ ์ ์๋ค.
๊ทธ ๋๊ฐ: ๊ทธ ์ ๋ฏธ์ฌ ์๋์ ํธ์คํธ๋ admin ์ด ์ ์ฅํ ์ ์๋ ์ด๋ค URL ๋ก๋ ๋๋ฌ ๊ฐ๋ฅํด์ง๊ณ , ๊ทธ๊ฒ์ด ๋ฐ๋ก ๊ฐ๋๊ฐ ํ์์ ์์ ๋ ๋ฅ๋ ฅ์ด๋ค. ๊ทธ ์๋ฒ๋ค์ ์ค์ ๋ก ๋๋ฆฌ๋ ๋ค์์คํ์ด์ค๋งํผ ์ ๋ฏธ์ฌ๋ฅผ ๊ตฌ์ฒด์ ์ผ๋ก ์ ์งํ๋ผ.
managed MCP ์๋ฒ(runtime: "managed")๋ ์ด ์ฑ์ด ์๊ธฐ ํธ์คํธ์์ ์ง์ ๋์ด ์ปจํ
์ด๋์ด๊ณ
127.0.0.1:<port> ๋ก ๋ฟ๋๋ค. ์ด์์๊ฐ ํ์ดํํ ๊ฒ์ด๋ผ๋ฉด ๊ฐ๋๊ฐ ์ ํํ ๊ฑฐ๋ถํ ์ฃผ์๋ค. ์ ๋ขฐ๋
๋์ provenance ์ ๋์ธ๋ค. ํ๋ก๋น์ ๋๊ฐ ํฌํธ๋ฅผ ๋ฐ์ธ๋ฉํ ๋ค ๊ทธ ์ฃผ์๋ฅผ ๊ธฐ๋กํ๋ค.
isManagedLoopback(src/domain/mcp/types.ts)์ด ์ด ์ฐํ๊ฐ ์ ์ฉ๋๋์ง๋ฅผ ๊ฒฐ์ ํ๋ ์ ์ผํ
์๋ฆฌ์ด๊ณ , ์๋์ ์ผ๋ก ์ข๋ค. ํญ๋ชฉ์ managed ๋ฅผ ์ฃผ์ฅํด์ผ ํ๊ณ ๊ทธ๋ฆฌ๊ณ ๋ฆฌํฐ๋ด ๋ฃจํ๋ฐฑ ์ฃผ์๋ฅผ
์ง๋
์ผ ํ๋ค:
127.0.0.1๋ก ํด์๋๋ ํธ์คํธ๋ช ์ ๊ฑฐ๋ถ๋๋ค. ํ์ธ๊ณผ ์์ฒญ ์ฌ์ด์ ๋ค๋ฅธ ๊ณณ์ผ๋ก ํด์๋ ์ ์๋ค.- ๋ฃจํ๋ฐฑ์ ๊ฐ๋ฆฌํค๋
remoteํญ๋ชฉ์ ๊ฑฐ๋ถ๋๋ค. ๊ทธ ์ฃผ์๋ ํ์ดํ๋ ๊ฒ์ด๋ค. - ๋ ์ง์คํธ๋ฆฌ๋ managed ํญ๋ชฉ์ URL ์ ์ฎ๊ธฐ๊ธฐ๋ฅผ ๊ฑฐ๋ถํ๋ค.
- ๋ผ์ดํ์ฌ์ดํด use case ๋ ํ๋ก๋น์ ๋๊ฐ ๋ณด๊ณ ํ๋๋ผ๋ ๋ฃจํ๋ฐฑ์ด ์๋ ์ฃผ์๋ฅผ ์ ์ฅํ๊ธฐ๋ฅผ ๊ฑฐ๋ถํ๊ณ , ๊ทธ๊ฒ์ด ์ง๋ชฉํ ์ปจํ ์ด๋๋ฅผ ์ ์ง์ํจ๋ค. ์ ์ง๊น์ง ์คํจํ๋ฉด ์๋ ๊ฑฐ๋ถ์ cleanup ์คํจ๋ฅผ ํจ๊ป ๋๋ฌ๋ด๋ฉฐ ์ปจํ ์ด๋๊ฐ ์ ๋ฆฌ๋๋ค๊ณ ์ฃผ์ฅํ์ง ์๋๋ค.
ํ๋ก๋น์ ๋๋ ์ด๋ฏธ์ง ๋ ํผ๋ฐ์ค, ํฌํธ, ๊ทธ๋ฆฌ๊ณ ์ ํ์ ์ธ argv ๋ฐฐ์ด ์ ๋ฐ๋๋ค. ์
ธ ๋ช
๋ น์ ๊ฒฐ์ฝ ๋ฐ์ง
์๋๋ค. ์ ์ผํ ๋ฐํ์์ธ Docker ํ๋ก๋น์ ๋(MANAGED_MCP_RUNTIME=docker,
src/infrastructure/mcp/dockerProvisioner.ts)๋ argv ๋ฅผ execFile ๋ก Docker CLI ์ ๋ฐฐ์ด์งธ
๋๊ธฐ๊ณ , ๊ตฌ์กฐ์ ์ผ๋ก ์ฐ์ด๋ ๊ฐ. ์ด๋ฆ(MANAGED_NAME), ์ด๋ฏธ์ง ๋ ํผ๋ฐ์ค, ํ๊ฒฝ ํคยท๊ฐ, argv,
endpoint path. ์
src/domain/mcp/provisioner.ts์ ํจํด์ผ๋ก API ์
๋ ฅ๊ณผ Docker ์คํ ์์ชฝ์์ ๊ฒ์ฌํ๋ค. ํญ๋ชฉ์
ํธ์งํ ์ ์๋ ์ด์์๊ฐ ๊ทธ๊ฒ์ผ๋ก ํธ์คํธ์์ ์์ ์ฝ๋๋ฅผ ๋๋ฆด ์๋ ์์ด์ผ ํ๋ค. ํธ์คํธ ํ์ผ
๊ฒฝ๋ก๋ ์
๋ ฅ์ผ๋ก ๋ฐ์ง ์์ผ๋ฉฐ, ์ ์ฅ๋ ํ๊ฒฝ ๊ฐ๋ง ํ๋ก์ธ์ค๊ฐ ๋ง๋ 0600 ์์ env file ๋ก ์ ๋ฌํ๋ค.
์ปจํ
์ด๋๋ ๊ฐ๊ฐ ๋ฉ๋ชจ๋ฆฌ์ memory+swap์ ๋ชจ๋ 512MiB, CPU 1๊ฐ, PID 256๊ฐ๋ก ์ ํํ๊ณ Linux
capability๋ฅผ ๋ชจ๋ ๋ฒ๋ฆฌ๋ฉฐ no-new-privileges๋ก ์คํ๋๋ค. root filesystem์ read-only์ด๊ณ
/tmp๋ง noexec,nosuid 64MiB tmpfs๋ก ์ธ ์ ์๋ค. ๋ฐ๋ผ์ managed image๋ ์์ ๋ก์ปฌ ์ฐ๊ธฐ๋ฅผ
๊ฐ์ ํ๋ฉด ์ ๋๋ค. ํ ํธ์คํธ์๋ managed ํญ๋ชฉ์ 8๊ฐ๊น์ง๋ง ๋ง๋ค ์ ์๊ณ ์๋ก ๋ค๋ฅธ ์ด๋ฆ์ ๋์
์์ฑ๋ count-then-create ๊ตฌ๊ฐ์์ ์ง๋ ฌํ๋๋ค. ๊ธฐ์กด ํญ๋ชฉ์ restartยทreconcile์ ์ด ์ํ ๋๋ฌธ์
๋งํ์ง ์๋๋ค.
application/mcpMetadataHeaders.ts๊ฐ ์ ์ฅ๋ ์์ฝ header๋ฅผ ์ ๊ฑฐํ๊ณ ํ์ธํ ์ ์์ ๋ถ์ธ๋ค.
๋ค๋ฅธ ๋์๋ฌธ์ ํ๊ธฐ๋ ๊ฐ์ ์ด๋ฆ์ผ๋ก ์ทจ๊ธํ๋ฉฐ OAuth ๊ฐ์ฉ์ฑ ๊ฒ์ฌ ์ ์ ์ ๊ฑฐํ๋ค.
์ฌ์ฉ์๊ฐ ์ ์ header๋ฅผ ์ ์ฅํด ๋ค๋ฅธ ์ฌ๋ยทAgentยท๋ํ๋ฅผ ์ฌ์นญํ ์ ์๋ค.
| Header | ์๋ฏธยท๋ฒ์ |
|---|---|
X-Tenant-Id |
์คํ Agent ์ด๋ฆ. Agent๋ณ ๋๊ตฌ ๋ชฉ๋ก๊ณผ discovery cache๋ฅผ ๊ตฌ๋ถํ๋ค |
X-User-Email |
ํ๋ฉด์ด ๊ฒ์ฆํ Studio ์ฌ์ฉ์์ ํ์ฌ ์ด๋ฉ์ผ. ๋ฉ์ ์ ๋ ์ฐ๊ฒฐ ์ฌ์ฉ์, Webhook์ ํ ํฐ ๋ฐ๊ธ์, Schedule์ ๋ฑ๋ก์ ID๋ก ํ์ธํ๋ฉฐ ์ ์ cache key์ ํฌํจํ๋ค |
X-Conversation-Id |
๋ํ ์ฃผ์. ์์ฒญ์ context header์ด๋ฉฐ discovery cache key์ ํฌํจํ์ง ์๋๋ค |
์ด๋ฉ์ผ์ MCP discovery๋ถํฐ ํ๋ฌธ์ผ๋ก ์ ์กํ๋ฉฐ PII ํํฐ๊ฐ ๊ฐ๋ฆฌ์ง ์๋๋ค. ์๋ฒ ๋ฑ๋ก์ ์ฌ์ฉ์ ์ด๋ฉ์ผ๊ณผ ๋ณต์๋ ๋๊ตฌ ์ธ์ ๊ณต๊ฐ๋ฅผ ํฌํจํ๋ ์ ๋ขฐ ๊ฒฐ์ ์ด๋ค. ์ด header๋ง์ผ๋ก ์ธ์ฆ๋์ง ์์ผ๋ฉฐ ์๋ฒ๋ ๋ณ๋ BearerยทOAuth grant์ ํจ๊ป ์์ ์ ์์ ๊ฒ์ฆํด์ผ ํ๋ค.
registry Test์ Agent ๋๊ตฌ ์กฐํ๋ ์์ฒญ ์ฌ์ฉ์ email์ ์ ์กํ๋ค. ์นดํ๋ก๊ทธยทmanaged health probe์๋ ์ฌ์ฉ์ยท๋ํ๊ฐ ์๋ค. Agent ๋๊ตฌ ์กฐํ๋ OAuth์ override๋ฅผ ์ฌ์ฉํ์ง๋ง tenant header๋ ๋ณด๋ด์ง ์๋ ํ์ฌ ์ฐจ์ด๊ฐ ์๋ค. ๋ฐ๋ผ์ tenant๋ง๋ค ๋๊ตฌ ๋ชฉ๋ก์ด ๋ค๋ฅธ ์๋ฒ์์๋ probe์ ๋ฐ์ ๋ชฉ๋ก์ด ๋ค๋ฅผ ์ ์๋ค.
API ๋ํ ์ฃผ์์ caller ๋ถ๋ถ์ ๋ฐฐํฌ ํค๋ก ๋ง๋ digest๋ค. ์ด๋ฉ์ผ์ ํ๋ฌธ hash๊ฐ ์๋์ง๋ง ๋์ผ ์ฌ์ฉ์๋ฅผ ์ฐ๊ฒฐํ ์ ์๋ ๊ฐ๋ช ์ด์ง ์ต๋ช ํ๋ ์๋๋ค. ๋ฉ์ ์ ยทChat์ ์ฃผ์ ํ์์ ๊ด์ธก์ฑ ์ค๊ณ๋ฅผ ๋ฐ๋ฅธ๋ค. firing์ด๋ ๋ํ ID ์๋ ์์ฒญ์ ๋ํ header๋ฅผ ๋ณด๋ด์ง ์๋๋ค.
FetchUrl์ ๋ชจ๋ธ์ด ์ง๋ชฉํ ์ฃผ์๋ฅผ src/infrastructure/net/httpResource.ts๋ก ์์ฒญํ๋ค.
registry์ ๋ฑ๋ก ์ ๊ฒ์ฆ์ ๊ฑฐ์น์ง ์์ผ๋ฏ๋ก ํธ์ถ ์์ฒด์ URLยทDNSยทredirectยทbyte ์ ํ์ด ๊ฒฝ๊ณ๋ค.
๊ฐ์ ๊ณต๊ฐ fetch ๊ฒฝ๊ณ๋ Teams ์ฒจ๋ถ์ source ํ์ผ ์ฃผ์์๋ ์ ์ฉํ์ง๋ง ๊ฐ ๊ฒฝ๋ก์ credentialยท
๋ด๋ถ ํธ์คํธ ์์ธ๋ ๋ณ๋ ์ ์ฑ
์ ๋ฐ๋ฅธ๋ค.
- MCP ์ ๋ด๋ถ ํธ์คํธ ์์ธ๋ ๊ฒฐ์ฝ ์ฐธ์กฐํ์ง ์๋๋ค.
MCP_INTERNAL_HOST_SUFFIXES๋ ์ด ์ฑ์ด ์๊ธฐ ํด๋ฌ์คํฐ์ MCP ์๋น์ค์ ๋ฟ์ ์ ์๊ฒ ํ๋ ค๊ณ ์กด์ฌํ๋ค. ์ฌ๊ธฐ์ ๊ทธ๊ฒ์ ์กด์คํ๋ฉด ํ๋กฌํํธ ์ธ์ ์ ํ๋๊ฐhttp://mcp-argocd.agent-mcps.svc.cluster.local/์ ์ฝ๋ ์ผ๋ก ๋ฐ๋๋ค. ์ด๋ํฐ๊ฐskipsUrlGuard๋ฅผ import ํ๊ฑฐ๋ ๊ทธ ๋ชฉ๋กยทprocess.envยทlib/config์ ๋ฟ๊ธฐ๋ง ํด๋tests/architecture.test.ts๊ฐ ์คํจํ๋ค. - ์๊ธฐ ๋ชฉ๋ก์ ๋ฐ๋ก ์๋ค.
URL_FETCH_INTERNAL_HOST_SUFFIXES. ์ฌ๋ด ์ํค๋ ๋ด๋ถ API ๊ฐ ๊ตฌ์กฐ์ ์ฌ์ค ์ฃผ์์ธ ์ค์นํ ๋คํธ์ํฌ๋ฅผ ์ํ ๊ฒ์ด๊ณ , composition root ๊ฐ ์ฃผ์ ํ๋ฉฐ ๋ฐฐํฌ๋ก๋ง ๋์ด์ง๋ค. ๊ทธ ์ ๋ฏธ์ฌ ์๋์ ํธ์คํธ(isDeclaredInternalHost, ๊ฐ์ ์ ์ด, ๊ฐ์ ์ฃผ์: ๋ ์ด๋ธ ๊ฒฝ๊ณ, ๋จ์ผ ๋ ์ด๋ธ ๊ฑฐ๋ถ, IP ๋ฆฌํฐ๋ด ๊ฑฐ๋ถ,http(s)๋ง)๋ ์ฃผ์ ๊ฐ๋ ์์ด ์์ฒญ๋์ง๋ง, ๋๋จธ์ง๋ ๊ทธ๋๋ก๋ค: ๊ฐ์ 15์ด ํ์์์, ๊ฐ์ ๋ ํค๋, ๊ฐ์ ๋ฆฌ๋ค์ด๋ ํธ ์ํ(5)์ด๊ณ , ๋ฆฌ๋ค์ด๋ ํธ๋ ๋ค์ดํฐ๋ธ ์ถ์ข ์์ด ํ๋ง๋ค ํ์ธ๋์ด ์ ์ธ๋ ์งํฉ์ ๋ฒ์ด๋๊ฑฐ๋ ์ถ๋ฐ origin ์ ๋ฒ์ด๋๋ฉด ๊ฑฐ๋ถ๋๋ค. ์์ธ๊ฐ ๋ฆฌ๋ค์ด๋ ํธ ํ ๋ฒ์ผ๋ก ๋์ด์ ธ์๋ ์ ๋๋ ์ ์ผํ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ด๋ค. ๋น ๋ชฉ๋ก(๊ธฐ๋ณธ)์ ๋ชจ๋ ๋ชจ๋ธ ์ ํ URL ์ด ๊ฐ๋๋ฅผ ๋ง์ฃผํ๋ค๋ ๋ป์ด๋ค. ๊ทธ ๋๊ฐ๋ MCP ๋ชฉ๋ก์ ๊ฒ๊ณผ ๊ฐ๋ค: ์ ๋ฏธ์ฌ ์๋์ ๋ชจ๋ ํ์ด์ง๊ฐ ํ๋กฌํํธ ์ธ์ ์ ํ๋๋ก ์ฝํ๋ค. ์ ๋ง๋ก ๋ชจ๋ธ์ด ์ฝ์ด๋ ๋๋ ์กด๋งํผ ์ข๊ฒ ์ ์ธํ๋ผ. - ์๋ฌด๊ฒ๋ ์ธ์ฆํ์ง ์๋๋ค. ํ
๋ํธ ํค๋ ์์, MCP OAuth token ์์, Slack token ์์,
ํธ์ถ์ ํค๋ ์ ๋ฌ ์์. ํญ์ GET ์ด๊ณ ๋ณธ๋ฌธ์ ๊ฒฐ์ฝ ์๋ค. ๊ต์ฐจ ์ถ์ฒ ๋ฆฌ๋ค์ด๋ ํธ๋ ์ ์ด์ ๋ถ์ง
์์ ๊ฒ์ ์ ๋ฌํ ์ ์๊ณ .
fetchPublicUrl์ด ์ด์ฐจํผ ๊ทธ๊ฒ์ ๊ฑฐ๋ถํ๋ค. - ๊ฑฐ๋ถ๋ ์ผ๋ฐํ๋๋ค.
PublicFetchError๋ ์๊ธฐ๊ฐ ๊ฑฐ๋ถํ ํธ์คํธ๋ฅผ ์ง๋ชฉํ๋ค. ๊ทธ๊ฒ์ ๋ชจ๋ธ์๊ฒ ๊ฑด๋ค๋ฉด ๋๊ตฌ๊ฐ ์ด๋ค ๋ด๋ถ ์ด๋ฆ์ด ์กด์ฌํ๋์ง์ ๋ํ ์ค๋ผํด์ด ๋๋ค. ํธ์ถ์๋ "๊ทธ ์ฃผ์๋ ์ฌ๊ธฐ์ ๋๋ฌํ ์ ์๋ค"๋ฅผ ๋ฐ๊ณ , ์์ธ๋ origin ๋ง ๋ก๊ทธ๋ก ๊ฐ๋ค. URL ์์ฒด๊ฐ ์๊ฒฉ ์ฆ๋ช ์ธ ๊ฒฝ์ฐ๊ฐ ๋ง๋ค. - ๋ฐ๋น ์ ํ๋๋ค.
MAX_URL_FETCHES_PER_RUN(20)์ ์์ฒญ์ ๊ฐ์ ๋ฅผ ์ ํํ๋๋ฐ, ๋ค๋ฅธ ์ด๋ค ์์ฐ๋ ๊ทธ๋ ๊ฒ ํ์ง ์๋๋ค. "๋ง์ ์์ฒญ, ์ ๋ถ ์คํจ"๋ ๋คํธ์ํฌ ์ค์์ด ์ทจํ๋ ๋ชจ์์ด๋ค. - ๊ธฐ๋ณธ์ ๊บผ์ง. Agent๊ฐ
parameters.urlFetch๋ก ์ตํธ์ธํ๋ค. ๊ทธ capability ๋ ์ฃผ์ ๋ ์์กด์ฑ์์ ํ์๋๋ฏ๋ก Playground ํ๋ฆฌ๋ทฐ์ ๋ฐ์ด ์๋ก ์ด๊ธ๋ ์ ์๋ค.
์ด๊ฒ์ด ๋ง์ง ๋ชปํ๋ ๊ฒ. ๊ณต๊ฐ๋ผ ์์ง๋ง ๋ฏผ๊ฐํ ํธ์คํธ. ํ๋์ ์ด๊ทธ๋ ์ค ์ฃผ์๋ฅผ ์ ๋ขฐํ๋ IP
ํ์ฉ๋ชฉ๋ก ๊ธฐ๋ฐ SaaS. ๋ ๊ฐ๋๋ฅผ ํต๊ณผํ๋ค. ์ ์ถ๋ ๋ง์ฐฌ๊ฐ์ง๋ค. https://attacker.example/?leak=โฆ
์ ์์ฒญํ๋๋ก ์ค๋๋นํ ๋ชจ๋ธ์ ํ๋ฒํ ์์๋ฐ์ด๋ ์์ฒญ์ ํ๋ ๊ฒ์ด๊ณ , PII ํํฐ๋ง์ ๋์์ด ๋์ง
์๋๋ค. fetch ์๋ ๋ณต์๋ ์ธ์๊ฐ ํ์ํ๊ธฐ ๋๋ฌธ์ด๋ค(๋ง์คํน๋ URL ์ ํด์๋์ง ์๋๋ค). ์ด๊ฒ์
์๋์์ MCP ๋๊ตฌ ์ธ์์ ๋ํด ์ด๋ฏธ ๋งํ ๊ฒ๊ณผ ๊ฐ์ ํ๊ณ๋ค. ์ฐจ์ด๋ URL ์ด ๋ง์ฐฐ์ด ๋ ์ ์ ํต๋ก๋ผ๋
์ ์ด๋ค.
์ด HTTP ์์ฒญ์ ์ฑ ํ๋ก์ธ์ค์์ ์ํํ๋ค. SSRF ๊ฐ๋์ ๋ณ๊ฐ๋ก ๋ฐฐํฌ์ egress ์ ์ฑ ์ ์ ์ฉํ๊ณ , ํ์ฉํ ๋ด๋ถ ํ์ด์ง์ IP ๊ธฐ๋ฐ ์ ๋ขฐ ์๋น์ค๊ฐ ๋ชจ๋ธ์ ๋ ธ์ถ๋ ์ ์์์ ๊ณ ๋ คํ๋ค.
๊ด๋ฆฌ์๋ registry์ OAuth ๋ฉํ๋ฐ์ดํฐ์ ์ ํ์ ๊ณต์ client๋ฅผ ๋ฑ๋กํ๊ณ , connection์ Studio ์ฌ์ฉ์ IDยทMCP ์๋ฒ๋ณ๋ก ๋ณธ์ธ์ grant๋ฅผ ๋ณด๊ดํ๋ฉฐ Agent ๊ฐ์ ์ฌ์ฌ์ฉํ๋ค. ์คํ ๊ฒฝ๋ก๋ well-known ๋ฌธ์๋ฅผ ๋ค์ ์ฝ์ง ์๊ณ ์ ์ฅ๋ ๊ณ์ฝ์ผ๋ก token์ ํด์ํ๋ค. ๋ฐ๊ฒฌยท์ฐ๊ฒฐยทcallback์ HTTP ํํ๋ API, refresh ์๋ช ์ MCP ์ค๊ณ๋ฅผ ๋ฐ๋ฅธ๋ค.
protected-resource ๋ฌธ์๋ MCP ์ฃผ์์ 401 challenge๊ฐ ์ง์ ํ URL์ ์ฐ์ ํ๋ค. challenge๊ฐ ์์ผ๋ฉด well-known ํ๋ณด๋ฅผ ์ฝ๋๋ค. resource ๋ฌธ์๋ ๊ทธ MCP ํญ๋ชฉ์ ๋ด๋ถ ํธ์คํธ ์์ธ๋ฅผ ์ฌ์ฉํ ์ ์์ง๋ง, ๋ฌธ์๊ฐ ์ง๋ชฉํ authorization server๊น์ง ๊ฐ์ ์์ธ๋ฅผ ์ฃผ์ง๋ ์๋๋ค. authorizationยทtokenยทregistration endpoint๋ HTTPS์ URL ์ ์ฑ ์ผ๋ก ๊ฒ์ฌํ๋ค. ๋ฉํ๋ฐ์ดํฐ ์กฐํ ์คํจ ๋ฉ์์ง์๋ ํ๋ณด ์ฃผ์์ userinfoยทqueryยทfragment์ ์ ์ก ์ค๋ฅ ์๋ฌธ์ ์ฃ์ง ์๋๋ค.
resource identifier๋ ๋ฌธ์๋ฅผ ์ฐพ์ ๋์๊ณผ ์ผ์นํด์ผ ํ๋ค. ์ ํ๋ ์์ธ๋
https://mcp.slack.com/mcp๊ฐ ๊ณต์ well-known ๋ฌธ์๋ฅผ ์ง๋ชฉํ ๋
๋ฌธ์์ resource: https://mcp.slack.com์ ํ์ฉํ๋ ์กฐํฉ์ด๋ค.
๋ค๋ฅธ originยท๊ฒฝ๋ก ์กฐํฉ์ผ๋ก ์ผ๋ฐํํ์ง ์๋๋ค.
authorization server๋ RFC 8414 path-inserted, OpenID path-inserted, OpenID path-appended
์์๋ก ๋ฐ๊ฒฌํ๋ค. ๊ฒฝ๋ก๋ฅผ ๊ฐ์ง issuer์์ root ๋ฌธ์๋ก ํํดํ์ง ์์ผ๋ฉฐ ๋ฌธ์์ issuer๋ฅผ ๊ฒ์ฆํ๋ค.
Google discovery๋ ๊ด๊ณ ์ฃผ์ https://accounts.google.com/์ ๋ํด ๋ฉํ๋ฐ์ดํฐ์
https://accounts.google.com๋ง ์ถ๊ฐ๋ก ํ์ฉํ๋ค. callback์ iss์๋ ์ด ์์ธ๋ฅผ ์ ์ฉํ์ง ์๋๋ค.
Entra์ common endpoint์ฒ๋ผ ๋ฌธ์๊ฐ ๋ค๋ฅธ tenant issuer๋ฅผ ๋๋ ค์ฃผ๋ฉด ์ผ์น ๊ฒ์ฌ๋ฅผ ํต๊ณผํ์ง ๋ชปํ๋ฏ๋ก
resource๊ฐ ์ฌ์ฉํ tenant issuer๋ฅผ ์ง์ ๊ด๊ณ ํด์ผ ํ๋ค.
registry URL ๋ณ๊ฒฝ์ ์ด์ auth๋ฅผ ํ๊ธฐํ๋ค. ์ ์ฃผ์์ Discover๊ฐ ํ์ํ๋ฉฐ ์ด์ ์ฐ๊ฒฐ์ ๊ฐ์
์ด๋ฆ์ด๋ผ๋ ์ด์ ๋ก ์ฌ์ฌ์ฉํ์ง ์๋๋ค. OAuth ๋ฉํ๋ฐ์ดํฐ์ ๊ณต์ ์ฑ ์ ์ฅ์ ์ฝ์ auth์ ๋ํ
์กฐ๊ฑด๋ถ ์ฐ๊ธฐ๋ก ๋์ ๋ณ๊ฒฝ์ ๋ณดํธํ๋ค.
| ๊ฒ์ฌ | ๊ตฌํ ๊ณ์ฝ |
|---|---|
| client ์ ํ | ๊ธฐ์กด credential โ ์ฌ์ฉํ ์ ์๋ Client ID Metadata Document โ dynamic registration โ ์ค์ ์ค๋ฅ |
| PKCE | S256 ํ์. ๊ด๊ณ ํ์ง ์๋ ์๋ฒ๋ ๊ธฐ๋ณธ ๊ฑฐ์ ํ๋ฉฐ ๋ฐฐํฌ์ MCP_OAUTH_ALLOW_UNADVERTISED_PKCE๋ง ์์ธ๋ฅผ ํ์ฉ |
| state | ์ผํ์ฉยท10๋ถ ๋ง๋ฃ. ์ฌ์ฉ์ IDยทemail, verifier, client, issuer, resource์ redirect URI๋ฅผ ํจ๊ป ๋ณด๊ด |
| redirect URI | ์๋ฒ ๊ณต๊ฐ base์ ๊ณ ์ callback. Tools์ ์๋ ๊ฐ๋ ๊ฐ์ ์ฃผ์์ฌ์ผ ํจ |
| resource | authorization๊ณผ token ์์ฒญ์ ๋์ resource๋ฅผ ํฌํจ |
| callback issuer | code ๊ตํ ์ ์ pending state์ issuer์ ๋ฌธ์ ๊ทธ๋๋ก ๋น๊ต. provider๊ฐ ์ง์์ ๊ด๊ณ ํ๋๋ฐ iss๊ฐ ์์ผ๋ฉด ๊ฑฐ์ |
| ์ค๋ฅ callback | issuer๋ฅผ ๊ฒ์ฆํ ์ ์๋ ์๋ต์ error_description์ ๊ทธ๋๋ก ์ ๋ฌํ์ง ์์ |
| callback ๊ถํ | ์์ํ ์ฌ์ฉ์ IDยทemail, ํ์ฌ ๊ณ์ ยทmember ๋ฑ๊ธยทAgent ์ ๊ทผ๊ณผ clientยทresource๋ฅผ ๋ค์ ํ์ธ |
| token endpoint ์ธ์ฆ | ๋ฑ๋กํ ์ธ์ฆ ๋ฐฉ์์ ์ฐ๊ฒฐ์ ์ ์ฅยท์ฌ์ฉ. basic์ client ID์ secret์ form encoding ํ Base64. secret ์๋ client๋ none |
| ๋์ ๋ฑ๋ก | application_type: "web"์ ๋ช
์ํ๊ณ token ์์ฒญ๊ณผ ๊ฐ์ ์ธ์ฆ ๋ฐฉ์์ผ๋ก ๋ฑ๋ก |
๋ฑ๋ก client credential์ ๋ฐ๊ธ issuer์, token์ ๋ฐ๊ธ ๋น์ resource์ ๋ฌถ์ธ๋ค. ์ด ํ๋๊ฐ ์๋ ์ฐ๊ฒฐ์ด๋ pending state๋ฅผ ํ์ฌ registry์ ์ํ๋ค๊ณ ์ถ์ธกํ์ง ์๋๋ค. ์ ์ฐ๊ฒฐ์ด ํ์ํ๋ค๊ณ ์๋ฆฌ๊ณ grant ์ฌ์ฉยท์ธ๊ฐ ์๋ฃ๋ฅผ ๊ฑฐ์ ํ๋ค.
๊ณต์ ์ฑ์ clientFromRegistry์ Client ID๋ฅผ ๊ธฐ๋กํ๊ณ code ๊ตํยทrefresh ๋ ํ์ฌ Secret์ ์ฝ๋๋ค.
Secret ํ์ ์ ๊ธฐ์กด grant์ ๋ฐ์ํ์ง๋ง Client ID์ ๊ต์ฒดยท์ ๊ฑฐ๋ ๊ธฐ์กด grant๋ฅผ ์ฐจ๋จํ๋ค.
๊ฐ๋ณ ๋์ ๋ฑ๋ก Secret์ ํด๋น ์ฌ์ฉ์์ connection์ ๋ณด๊ดํ๋ค.
์ฐ๊ฒฐ ํ๋ฉด์ ์๋น์ค ๊ณ์ ์ ์ธ์ฆยท์ ๊ทผ ํ์ ์ ์ฌ์ฉํ์ง ์๋๋ค. ๊ณต์ OAuth endpoint ์กฐํฉ์
GitHubยทGoogle ๊ธฐ๋ณธ ์กฐํ๋ ํด๋น ์ ๊ณต์์ ๊ณ ์ ๊ณ์ API๋ฅผ ์ฌ์ฉํ๋ค. ์ผ๋ฐ OIDC๋ ๊ฒ์ฆํ discovery์
UserInfo endpoint๋ฅผ ์ฌ์ฉํ๋ฉฐ, ๊ด๋ฆฌ์ ์ง์ HTTP ๊ณ์ฝ๋ HTTPSยทURL ์ ์ฑ
์ผ๋ก ์ ์ฅ๊ณผ dispatch ๋ ๊ฒ์ฆํ๋ค.
NotionยทPlaud token๊ณผ ์๋ MCP ๊ณ์ฝ์ ๋ฐ๊ธ๋ resource์ ํด๋นํ๋ ํ์ฌ registry URL์ ํ์ฌ ์ฌ์ฉ์
์กฐํ ๋๊ตฌ์๋ง ์ฌ์ฉํ๋ค. ์๋ MCP ๊ณ์ฝ์ ์๋ฒ๊ฐ readOnlyHint: true๋ก ์ ์ธํ ๋๊ตฌ๋ง ํธ์ถํ๋ค.
lookup ์ค์ ์ ๊ด๋ฆฌ์ ์ ์ฉ์ด๋ฉฐ ์๋ ์ ํ์ผ๋ก ์์์ ๋๊ตฌ๋ ์ฐ๊ธฐ ์์
์ ์คํํ์ง ์๋๋ค.
๋ชจ๋ ์์ฒญ์ ๊ณต๊ฐ URL ๊ฐ๋์ ๋์ผ origin redirect ์ ์ฑ
์ ๋ฐ๋ฅธ๋ค. ๊ณ์ ์กฐํ ์๋ต์ ์ ํํ ๊ณ์ label๋ง ๋ณด๊ดํ๊ณ ์ค๋ฅ ์๋ฌธ์ด๋ token์
ํ๋ฉดยท๋ก๊ทธ์ ์ ๋ฌํ์ง ์๋๋ค. Studio ์ฌ์ฉ์ ์ด๋ฉ์ผ์ ์๋น์ค ๊ณ์ ์ผ๋ก ์ถ์ ํ์ง ์๋๋ค.
์๋ JSON Pointer์ ๋๊ตฌ ์ธ์์ tokenยทpassword ๋ฑ ์๊ฒฉ ์ฆ๋ช
ํ๋๋ฅผ ํ์ฉํ์ง ์์ผ๋ฉฐ, ์๋ฒ ์๋ต์ด
์กฐํ token์ label์ ํฌํจํด ๋ฐ์ฌํ๋๋ผ๋ ๊ณ์ ํ์ยท์ ์ฅ์ผ๋ก ๋์ด๊ฐ์ง ์๋๋ค.
Client IDยทSecret ์๋ ์
๋ ฅ์ ๊ด๋ฆฌ์ ๊ณต์ฉ ์ฑ ์ค์ ์๋ง ์ ๊ณตํ๋ค. ๊ฐ์ธ ์ฐ๊ฒฐ ๋ชฉ๋ก์
Client Secret๊ณผ access/refresh token์ ๋ฐํํ์ง ์๋๋ค. issuerยทresource๊ฐ ๋ฐ๋ grant๋
์คํ์์ ๊ฑฐ์ ํ๋ฉฐ ์ฌ์ฉ์๋ ํ์ฌ ์๋ฒ ์ค์ ์ผ๋ก ๋ค์ ์ธ๊ฐํ๋ค.
/api/mcps/oauth/client-metadata๋ authorization server๊ฐ ์ฟ ํค ์์ด ๊ฐ์ ธ๊ฐ๋ ๋ฌธ์๋ค.
secret์ ์๊ณ client ์ด๋ฆยทclient ID URLยท๊ณ ์ redirect URI๋ฅผ ์ ๊ณตํ๋ค.
์์ฒญ Host ๋์ ์ค์ ๋ ๊ณต๊ฐ base๋ก ์ฃผ์๋ฅผ ๋ง๋ ๋ค. ์ด URL์ ์ค์ client ID๋ก ์ ํํ๋
์ธ๊ฐ ์ค๋น ๋จ๊ณ์์ HTTPSยท๊ณต๊ฐ ๋๋ฌ ๊ฐ๋ฅ ์กฐ๊ฑด์ ํ์ธํ๋ค.
๋ฌธ์๋ Agent ์ด๋ฆ์ด๋ ์ฌ์ฉ์ ์ ๋ณด๋ฅผ ํฌํจํ์ง ์๋๋ค. ์ค์ callback์ ์์ํ ์ฌ์ฉ์์ IDยทstateยท์ฐ๊ฒฐยทํ์ฌ Agent ์ ๊ทผ ๊ถํ์ ์๊ตฌํ๋ค. ๊ณต๊ฐ base๊ฐ ์๊ฑฐ๋ provider๊ฐ ๊ฐ์ ธ๊ฐ ์ ์๋ ์ฃผ์๋ฉด metadata ๋ฐฉ์ ๋์ ์ง์๋๋ ๋ฑ๋ก ๊ฒฝ๋ก๋ฅผ ์ฌ์ฉํ๊ฑฐ๋ ์ค์ ์ค๋ฅ๋ฅผ ๋ฐํํ๋ค.
metadata client๋ ์๊ธฐ ํธ์คํ URL์ด๋ฏ๋ก ๋ฑ๋ก client์ ๋ฌ๋ฆฌ issuer ๋ณ๊ฒฝ ๋ client ID ์์ฒด๋ฅผ ํ๊ธฐํ ํ์๋ ์๋ค. ๋ค๋ง grant์ issuerยทresource ๊ฒ์ฌ๋ ๊ทธ๋๋ก ์ ์ฉํ๋ค. ๋ฐฐํฌ์ ๊ณต๊ฐ base๊ฐ ๋ฌ๋ผ์ง๋ฉด ์ ๋ฌธ์ ์ฃผ์๋ก ๊ฐฑ์ ํ๋ค.
refresh ๊ฒฐ๊ณผ๋ connection revision์ ๋น๊ตํด ์ ์ฅํ๋ค. refresh token์ ์๋ตํ ์๋ต์ ์ด์ ๊ฐ์ ์ ์งํ๊ณ ์ ๊ฐ์ด ์์ผ๋ฉด ๊ต์ฒดํ๋ค. ๊ฒฝ์์์ ์ง ์์ฒญ์ ์๋ issuerยทresource์ ์ํ connected ์ํ์ ์น์ grant๋ง ์ฌ์ฉํ๋ค.
ํ์ ํ refresh credential์ provider ์์ฒญ ์ ์ DB claim์ ํ๋ณดํ ํ๋ก์ธ์ค๋ง ์ฌ์ฉํ๋ค.
๋ค๋ฅธ ํ๋ก์ธ์ค๋ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋ค๋ฆฌ๊ณ , ๋ง๋ฃ๋ claim์ด๋ ์ ์ก ๊ฒฐ๊ณผ๊ฐ ๋ถ๋ช
ํํ ๊ฐฑ์ ์ ๋ค์ ์คํํ์ง ์๋๋ค.
๊ธฐ์กด credential ๋ฐ์ดํฐ๋ ๋ณด์กดํ์ง๋ง needs_reauth๋ก ํ์ํด ์ฌ์ฉ์๊ฐ ๋ค์ ์ธ์ฆํ๋๋ก ํ๋ค.
403 insufficient_scope๋ ๊ทธ ์์ฒญ์ typed challenge์์ scope๋ฅผ ์ป์ด ์ฌ์ธ๊ฐ์ ๋ณดํ ๋ค.
๋ณ๋ ฌ ๋๊ตฌ ํธ์ถ์ ๊ฒฐ๊ณผ๋ฅผ ์ธ์
์ ์ฒด์ ๋ง์ง๋ง challenge๋ก ํด์ํ์ง ์๋๋ค.
token์ registryยทAgent header๋ณด๋ค ์ฐ์ ํ๋ ๋ง์ง๋ง credential์ด๋ค. OAuth ์๋ฒ๋ ํธ์ถ์์ ์ ํจํ ๊ฐ์ธ grant๊ฐ ์์ผ๋ฉด warning๊ณผ ํจ๊ป ์ ์ธํ๋ค. Agent ์์ ์ยท๋ค๋ฅธ ์ฌ์ฉ์ยทregistry์ ์ ์ ์ธ์ฆ์ผ๋ก ๋์ ํธ์ถํ์ง ์๋๋ค. ์์ฝ ์ ์ header๋ credential๋ก ๊ณ์ฐํ์ง ์๋๋ค.
Workspace๋ chat ์์ ์์๊ฒ๋ง ๊ณต๊ฐ๋๋ฉฐ ์คํยท์น์ธ์ ํ์ฌ Agent ์ ๊ทผ๋ ๋ค์ ํ์ธํ๋ค.
Workspace ์ค์ ์ฐ๊ธฐ๋ Agent ์์ ์์๊ฒ ํ์ ํ๊ณ revision ์กฐ๊ฑด๊ณผ Agent ์๋ช
๊ฒฝ๊ณ๋ก ๋ณดํธํ๋ค.
Agent์ ๋๊ตฌ ํ์ฑํ๋ ํด๋น Agent์ ๋ช
์์ ์ผ๋ก ์ฐ๊ฒฐํ GitHub MCP ๊ณ์ ์ ์ ์ฑ
๋ฒ์ ๋ด ์ฌ์ฉํ๋ ๊ฒ์ ํ์ฉํ๋ค.
Runtime ๋ชจ๋ธ ์ ํ์ ๊ด๋ฆฌ์์๊ฒ ํ์ ํ๋ฉฐ ๋๊ตฌ๋ฅผ ๋๋ฉด ์ ์คํยทGit ์น์ธ์ ๊ฑฐ์ ํ๋ค.
๋ฑ๋ก ์ ์ฅ์ยท์ ํํ ์์ ์ ํ์ฉ์ DB์์ ํ์ฌ ๊ฐ์ ์ฝ์ผ๋ฉฐ ์ผ๋ฐ Agent๊ฐ ์์ ํ์ง ์๋๋ค.
์์ ์ ํ์ฉ์ ํด๋น ๊ณ์ ์ ํฅํ ์ ์ฅ์๋ ํฌํจํ๋ฏ๋ก ๊ด๋ฆฌ ํ๋ฉด์์ ๊ทธ ๋ฒ์๋ฅผ ๋ช
์ํ๋ค. ์กฐํ ์คํจ๋
์ ๊ทผ์ ๊ฑฐ์ ํ๊ณ selected์ ๋น ๋ชฉ๋ก์ ๋ชจ๋ Git ๋์์ ์ฐจ๋จํ๋ค. all์ ํด๋น Agent์ GitHub MCP ๊ถํ
์์์ ๋ชจ๋ ์ ์ฅ์๋ฅผ ํ์ฉํ๋ค. new์ ์๋ ๋ฑ๋ก์ ์๋ฒ์ ์ค์ ์์ฑ ์ฑ๊ณต์๋ง ์ ์ฉํ๊ณ MCP ๊ฒฐ๊ณผ๋
๋ชจ๋ธ์ด ์ฃผ์ฅํ ์์ฑ ์ฌ์คยท์๊ฐ์ ๊ถํ ๊ทผ๊ฑฐ๋ก ์ฌ์ฉํ์ง ์๋๋ค. ์์ฑ receipt์ ๋ฑ๋ก์ ์์์ ์ผ๋ก ์ ์ฅํ๋ฉฐ
๋ถ๋ช
ํํ ์์ฑ์ ๋ฐ๋ณตํ์ง ์๋๋ค. ์ ์ฅ์ ์ ์ฑ
์ Sandbox ์์ยท๋คํธ์ํฌ๋
Agent์ GitHub MCP ์๊ฒฉ์ฆ๋ช
, ๊ฐ๋ณ ๊ฒ์ ์น์ธ์ ๋ณ๊ฒฝํ์ง ์๋๋ค. ๋ณ๊ฒฝ์ settings.update ๊ฐ์ฌ์ ๊ธฐ๋กํ๋ค.
Sandbox์๋ ํธ์คํธ mount, Docker socket, ๋ฐฐํฌ ์๊ฒฉ์ฆ๋ช
๊ณผ ์ฅ๊ธฐ Git ์๊ฒฉ์ฆ๋ช
์ ์ ๋ฌํ์ง ์๋๋ค.
Git ๋ฉํ๋ฐ์ดํฐ๋ root ์์ ๋ก ๋๊ณ Agent์ ์คํ ๊ณ์ ์ ์์
ํ์ผ๋ง ์์ ํ๋ค.
GitHub APIยทcloneยทpush๋ ํ์ฌ Agent์ GitHub MCP ์ธ์ฆ์ ์ฌ์ฉํ๋ฉฐ Plugin ํ ํฐ์ด๋ ๋ค๋ฅธ Agent์
์ฐ๊ฒฐ๋ก ํด๋ฐฑํ์ง ์๋๋ค. OAuth issuerยทresourceยทclient ๊ฒ์ฌ์ ๊ฐฑ์ ์ ๊ธฐ์กด MCP ์ธ์ฆ ์ ๊ณต์๊ฐ ์ํํ๋ค.
OAuth ํ ํฐ์ ๋ฐ๊ธํ GitHub authority์ ์ผ์นํ๋ APIยทGit endpoint์๋ง ์ฌ์ฉํ๋ค.
์๋ฒ์ ์์ bare Git ์ ์ฅ์์์ ์ธ์ฆํ๊ณ Sandbox์๋ ์๊ฒฉ์ฆ๋ช
์๋ bundle๋ง ์ ๋ฌํ๋ค.
์๋ฒ์์๋ ์ ์ฅ์ checkoutยทhookยทbuild script๋ฅผ ์คํํ์ง ์๋๋ค.
๊ณต๊ฐ Git endpoint๋ HTTPS์ DNS pinning์ ์ฌ์ฉํ๊ณ ๋ด๋ถ ํธ์คํธ ์์ธ๋ ๋ฐฐํฌ์ ๋ณ๋ ๋ชฉ๋ก์ ๋ฐ๋ฅธ๋ค.
ํจ๊ณผ๋ ๊ฒํ ํ tree/HEAD์ ๊ถํ ๊ทผ๊ฑฐ๋ฅผ ๊ฐ์ง ๋์ ๋ ์ฝ๋๋ฅผ ๋จผ์ claimํ ๋ค ์คํํ๋ค.
์ฝ๋ฉ ์์ฒญ์ ์์
๋ธ๋์น CommitยทPushยทPR์ ์ถ๊ฐ ํ์ธ ์์ด ์คํํ๋ฉฐ authorization: coding-request๋ก ๊ธฐ๋กํ๋ค.
main ๋ฐ์ยทํ๊ทธยท๋ฆด๋ฆฌ์ฆยท๋ฐฐํฌ๋ ๋ณ๋ ์ฌ์ฉ์ ํ์ธ์ ์ ์งํ๋ค. ์๋ ๊ฒ์๋ ์์ ๊ถยทํ์ฌ ์ ์ฑ
ยทfingerprintยทlease๋ฅผ ๋ค์ ๊ฒ์ฌํ๋ค.
์ข
๋ฃยท์ญ์ ๊ฐ ๋จผ์ ๊ธฐ๋ก๋๋ฉด pending/์คํ claim์ ๊ฑฐ์ ํ๋ค. ์ข
๋ฃ๋ Workspace์ ์ Git ๊ฒํ ๋
์์ ์ยท์ด์ ์๋ ChatยทAgent์ action lease๋ฅผ ์์์ ์ผ๋ก ํ์ธํ ๋ค ๋ณต์ํ๋ฉฐ ์ญ์ ๋ ๋๋๋ฆฌ์ง ์๋๋ค.
main ๋ณํฉ์ PR ์์ ๋ฒ์์ CI๋ฅผ
์ฌํ์ธํ๊ณ GitHub์ ์ ํํ head SHA ์กฐ๊ฑด์ ์ฌ์ฉํ๋ค. ๋ฐฐํฌ๋ ํ์ฉ๋ main workflow์
์น์ธํ inputs๋ก๋ง ์์ฒญํ๋ค. ์ ์ก ์ค๋ฅ ์ดํ์ ๋ถํ์คํ ํจ๊ณผ๋ ์๋ ์ฌ์คํํ์ง ์๋๋ค.
main ์ง์ ํธ์๋ ๊ฒํ ํ main SHA์ ๊ฒ์๋ ์์
HEAD๋ฅผ ๋์กฐํ๊ณ force: false๋ก ์คํํ๋ค.
๊ฒ์ฌ ๋ฏธ๋ณด๊ณ ๋ none์ผ๋ก ์น์ธ ํ๋ฉด์ ํ์ํ๊ณ , ๋๊ธฐ ์คยท์คํจํ ๊ฒ์ฌ์ ๊ตฌ๋ถํ๋ค. ๋ชจ๋ main ๋ฐ์์
GitHub ๋ธ๋์น ๊ท์น์ ๋ฐ๋ฅด๋ฉฐ ๊ถํยท๋ณดํธ ๊ท์น์ ์ฐํํ๋ ์ต์
์ ์ ๊ณตํ์ง ์๋๋ค.
ํ๊ทธ๋ ๊ฒํ ํ ์๊ฒฉ main, ๋ฆด๋ฆฌ์ฆ๋ ๊ฒํ ํ ๊ธฐ์กด ํ๊ทธ์ ์ ํํ commit์ ์ฌ์ฉํ๋ค. ํ๊ทธ๋ฅผ ๋ฎ์ด์ฐ์ง ์์ผ๋ฉฐ
GitHub์ ์ ์ฅ์ ๋ฒ์ contents ์ฐ๊ธฐ ๊ถํ์ผ๋ก ์คํํ๊ณ ์์ฑ ์๋ต๊ณผ ๋ฆด๋ฆฌ์ฆ ํ๊ทธ๋ฅผ ๊ฒ์ฆํ๋ค.
/api/workspaces/github/webhook์ ์๋ช
๊ณผ delivery ID๋ก PR ๋ฉํ๋ฐ์ดํฐ๋ง ๊ฐฑ์ ํ๋ฉฐ ์น์ธ ๊ถํ์ด ์๋ค.
Agent Trigger์ธ /api/webhook/{agent}๋ ๋ณ๋ Agent ์ํฌ๋ฆฟ์ผ๋ก ์คํ์ ์์ํ๋ค.
๊ด๋ฆฌ์๊ฐ githubReview๋ฅผ ํ์ฑํํ๋ฉด ์๋ช
๋ PR ์ด๋ฒคํธ์ ๋ํด ํด๋น Agent์ GitHub MCP ์ฐ๊ฒฐ๋ก ๋ฆฌ๋ทฐ ๋๊ธ์
๊ฒ์ํ ์ ์๋ค. ์๋ ๋ฆฌ๋ทฐ ๊ฒ์ ์ค์ ์ ๊ด๋ฆฌ์๋ง ๋ณ๊ฒฝํ๋ฉฐ, ์ ๊ทผ ๊ฐ๋ฅํ ์ ์ฅ์ ์ ์ฒด ๋๋
๋ช
์์ ์ ์ฅ์ ๋ชฉ๋ก์ผ๋ก ํ์ ํ๋ค. PR์ ๋ณธ๋ฌธยทURL์ด ๊ฒ์ ๋ชฉ์ ์ง๋ฅผ ๊ฒฐ์ ํ์ง ์๋๋ค. ๊ณต๊ธ์ API๊ฐ
ํ์ธํ base repositoryยทPR ๋ฒํธยทcommit_id์ COMMENT๋ง ๊ฒ์ํ๋ค. ๋ชจ๋ธ์๋ Skill๊ณผ ๊ฒ์ฆ๋ PRยทHEADยทbase์
๊ณ ์ ๋ ReviewSource๋ฅผ ์ ๊ณตํ๋ค. ํ์ผ ๊ฒฝ๋ก๋ ์๋ ๊ฒฝ๋ก๋ก ๊ฒ์ฆํ๊ณ ๊ณต๊ธ์ API๋ง ํธ์ถํ๋ฉฐ,
๋ฐํ๋ download URLยทsubmodule URL์ ๋ฐ๋ผ๊ฐ์ง ์๋๋ค. ์ฝ๊ธฐ ์์ฒญ ์ ํ์ ์ปค๋ฐ๊ณผ ํ์ฌ ์ฐ๋ ์์์ ํ์ธํ๋ค.
์์ ํ ๋ณ๊ฒฝ ์๋ฃ๊ฐ ํ๋ณด๋์ง ์์ ์คํ์ ์ ์ฒด ๋ฆฌ๋ทฐ๋ก ๊ฒ์ํ์ง ์๋๋ค.
PR ๋ฆฌ๋ทฐ Workspace๋ ๊ฐ์ธ Webhook ํ ํฐ ๋ฐ๊ธ์์ ํ์ฌ ๊ถํ๊ณผ Agent ์ ์ฅ์ ์ ์ฑ
์ผ๋ก ์์ฑํ๋ค.
๊ฒ์ฆ๋ ์ปค๋ฐ์ bare bundle๋ง Sandbox์ ์ ๋ฌํ๊ณ ์๋ฒ Git ์๊ฒฉ ์ฆ๋ช
์ ๋ฃ์ง ์๋๋ค.
command ๋ฐํ์๊ณผ ์ด ๋ฆฌ๋ทฐ์ Workspace๋ง ์ ๊ณตํ๋ฉฐ ์ ์ฅ์ ์์ฑยท์ฐ๊ฒฐ, ๋ค๋ฅธ Workspace ์ ํ,
Git publicationยท๋ฐฐํฌ๋ฅผ ๊ฑฐ์ ํ๋ค. ๋๋์ง ์์๊ฑฐ๋ ๊ฒฐ๊ณผ๋ฅผ ์ฝ์ง ์์ ๊ฒ์ฌ๋ ๊ฒ์๋ฅผ ๋ง๋๋ค.
์ฑ๊ณตยท์คํจ ๋ชจ๋ Workspace ์ ๋ฆฌ๋ฅผ ์์ฒญํ๊ณ ์ค์ ์ข
๋ฃ๋ฅผ ํ์ธํ๋ฉฐ ๊ฒ์ ์์์ฆ์ ์ ๋ฆฌ ์คํจ์๋ ๋ณด์กดํ๋ค.
๊ฐ์ธ Webhook ํ ํฐ์ ๋ฐ๊ธ ์ฌ์ฉ์์ ๊ถํ์ผ๋ก ์ ํ ๋ฒ์์ ๋ฆฌ๋ทฐ๋ฅผ ์์ฒญํ๋ค. ํ ํฐยท๊ณ์ ๊ถํ ํ์๋ ์ ์กฐํยท๋๊ตฌ ํธ์ถยท๊ฒ์ยทํ ์คํ์ ์ ์ฉํ๋ค.
Workspace๋ actor ์ข
๋ฅ์ ๋ณ๋๋ก ํ๋ฉด์ด ํ์ธํ ๊ด๋ฆฌ ์ฌ์ฉ์์ ํ์ฌ ๊ณ์ ยทAgent ์ ๊ทผ๊ณผ
์ ์ฅ์ ์ ์ฑ
์ ๊ฒ์ฌํ๋ค. ๋ํํ ์คํ๊ณผ ์๋ํ ๋ชจ๋ member ์ด์์ด์ด์ผ ํ๋ค.
๊ฐ์ธ API token์ ๋ฐ๊ธ ์ฌ์ฉ์๋ฅผ, ๋ฉ์ ์ ๋ ์ฐ๊ฒฐํ Studio ์ฌ์ฉ์๋ฅผ, Schedule์ ๋ฑ๋ก์๋ฅผ ์ฌ์ฉํ๋ค.
Schedule์ ๋ฑ๋ก์ ID๋ ๋ณ๊ฒฝ๋์ง ์์ผ๋ฉฐ ํ์ฌ ๊ณ์ ยทAgent ์ ๊ทผ์ ์คํ ์ ์ ๋ค์ ํ์ธํ๋ค.
Webhook ํธ์ถ์๋ ๊ฐ์ธ ํ ํฐ ๋ฐ๊ธ์์ด๋ฉฐ ๊ณต์ ์ค์ ์์ ๋ค๋ฅธ ์ฌ์ฉ์์ ๊ถํ์ ์์ํ์ง ์๋๋ค.
์ธ๋ถ payload๋ emailยทactor๋ฅผ ์ง์ ํ ์ ์๋ค. ํ๋ซํผ actor๋ ์๋ ์ฐ๋ ํธ์ถ์๋ก ์ ์งํ๋ค.
ํ ์์
์คํ ์ง์ ์๋ ์ฌ์ฉ์ ๊ถํ์ ๋ค์ ํ์ธํ๋ฉฐ ์ธ๋ถ ํธ์ถ์ Git ์น์ธ์ ์ง์ ์๋นํ ์ ์๋ค.
์น์ธยทCI ๊ฒฐ๊ณผ์ Chat ์ฌ๊ฐ๋ ์๋ ์์ ์ยทAgent ์ ๊ทผยทWorkspace ์ ํ๊ณผ SDK Session์ ๋ค์ ํ์ธํ๋ค.
๊ทธ ๊ฒฐ๊ณผ ์ด๋ฒคํธ๋ ์ ์ฌ์ฉ์ ์์ฒญ์ด๋ ๋ค์ Git ๋์์ ๋ํ ์น์ธ์ผ๋ก ์ทจ๊ธํ์ง ์๋๋ค.
Native CLI์๋ ๊ณต๊ธ์ API ํค ๋์ ํ๋์ Workspace Run์ ํ์ ๋ ์๋ช
ํ ํฐ์ ์ ๋ฌํ๋ค.
AES_ENCRYPTION_KEY์์ ๋ณ๋ HKDF ๋ชฉ์ ํค๋ฅผ ํ์ํ๋ฉฐ ์ค๋ธ์ ํธ URL ์๋ช
๊ณผ ๊ตํํ ์ ์๋ค.
Run ๋ง๋ฃยท์ทจ์ยท์ข
๋ฃยท์๋ ์ธ์ฆ ์๋จ ์ฒ ํ๋ ๋ค์ ๋ชจ๋ธ ์์ฒญ์ ๊ฑฐ์ ํ๋ค. ์์ฒญ์์ Authorization,
์ฟ ํค, ์์ ํค๋๋ฅผ ๊ณต๊ธ์์๊ฒ ์ ๋ฌํ์ง ์๋๋ค. ๊ณต์ Provider์ ์ ์ฅ๋ ๋ํยทpromptยทํ์ผยท๋๊ตฌ ๋ฆฌ์์ค๋
์ฐธ์กฐํ ์ ์์ผ๋ฉฐ Responses๋ ์ ์ฅ์ ๋๋ค. Gateway ์ฃผ์๋ ๋ฐฐํฌ์๊ฐ ์ง์ ํ๊ณ Sandbox ๋คํธ์ํฌ์์
Studio์ ํ์ํ ํต์ ๋ง ํ์ฉํ๋ค. Workspace ๊ณ์ฝ์ ๋ฐ๋ฅธ๋ค.
SDK Session ์ด๋ ฅ๊ณผ ์น์ธ ๋๊ธฐ RunState๋ runtime_sessions์ ๋ณ๋๋ก ์ ์ฅํ๋ค. ๊ฐ์ ๋ฐฐํฌ์
AES_ENCRYPTION_KEY๋ฅผ ์ฌ์ฉํ๋ฉฐ ๋ํ ID์ ์์ ์๋ฅผ ์ธ์ฆ ๋ฐ์ดํฐ์ ๋ฌถ์ ์ํธ๋ฌธ๋ง ์ฝ๋๋ค.
์๋ฌธ ์ํ์๋ ๋ชจ๋ธ/๋๊ตฌ ์ด๋ ฅ๊ณผ ๊ฐ Agent์ PII ๋ณต์ ๋งคํ์ด ํฌํจ๋ ์ ์๋ค. DB ์ ๊ทผ ๊ถํ๊ณผ
์ํธํ ํค๋ฅผ ๋ถ๋ฆฌํด ๊ด๋ฆฌํ๊ณ ๋ฐฑ์
ยท๋ณต๊ตฌ ์ ๊ฐ์ ํค๋ฅผ ์ ์งํ๋ผ.
์ํธํ๋ Session์๋ ์ต์ด ์คํ์ Studio ์ฌ์ฉ์ ID๋ฅผ ์ ์ฅํ๋ค. ์ ํด๊ณผ ์น์ธ ์ฌ๊ฐ๋ ๋ก๊ทธ์ธ ์ธ์ ์ ID์ ์ผ์นํด์ผ ํ๋ฉฐ ์ด๋ฉ์ผ๋ง์ผ๋ก ๋ค๋ฅธ ๊ณ์ ์ ์ด๋ ฅ์ ์ธ๊ณํ์ง ์๋๋ค. ์ฌ์ฉ์ ID๊ฐ ์๊ฑฐ๋ ๋ค๋ฅธ Session์ ์คํํ์ง ์์ผ๋ฉฐ ์ Chat์ ์์ํด์ผ ํ๋ค. Workspace Git ์น์ธ์ ์์ฒญ์์ Studio ์ฌ์ฉ์ ID๋ฅผ ๋ณด๊ดํ๊ณ ๊ฐ์ ๊ณ์ ์ ๊ฒฐ์ ๋ง ํ์ฉํ๋ค. ํ์ ์คํ ํ๋ ์ด ID๋ฅผ ๋ณ๊ฒฝํ ์ ์์ผ๋ฉฐ ํ์ฌ ๊ณ์ ยทAgent ์ ๊ทผ๊ณผ SDK Session์ ์ฌ์ฉ์ ID๋ฅผ ๋ค์ ๊ฒ์ฌํ๋ค.
์น์ธ์ Chat ์์ ์๊ฐ ์ ํํ revision๊ณผ ํญ๋ชฉ ID๋ฅผ ์ง์ ํ๋ค. ๋์ผ ์ถ์ฒ session ๋ณ๊ฒฝ ๊ฒ์ฌ, Agent ์ ๊ทผ ์ฌํ์ธ, ์คํ lease์ Session CAS๋ฅผ ํจ๊ป ์ ์ฉํ๋ค. ์น์ธ ์ํ๋ ๋๊ตฌ ์คํ ์ ์ pending์์ running์ผ๋ก ์ ์ ํ๋ค. ์ค๋ณตยท๋ก์ ๊ฒฐ์ , ๋ณ๊ฒฝ๋ ์ค์ ๊ณผ ์ฐ๊ฒฐ์ ๊ฑฐ๋ถํ๋ฉฐ ์น์ธ ํ ์ค๋จ๋ ์คํ์ ์๋์ผ๋ก ๋ฐ๋ณตํ์ง ์๋๋ค. ์ญ์ tombstone์ ๋ฆ๊ฒ ๋๋ ์คํ์ ์ฌ์์ฑ์ ๋ง๋๋ค.
SDK tracing์ ๋ก์ปฌ processor๊ฐ ์ด๋ฆยท์๊ฐยท์ํยท์ฌ์ฉ๋๋ง ์์งํ๋ค. SDK์ ๊ณต๊ฐ exporter๋ฅผ ์ค์นํ์ง ์์ผ๋ฉฐ ์๋ฌธ ๋ชจ๋ธ/๋๊ตฌ ์ ๋ ฅยท์ถ๋ ฅ๊ณผ credential์ native span์ผ๋ก ๋ด๋ณด๋ด์ง ์๋๋ค. ๋ฐฐํฌ๊ฐ ์ ํํ OTLP exporter์ ์คํ ์ค๋ฅ/๊ฒฝ๊ณ ๊ธฐ๋ก์ ์ ๊ทผ ๋ฒ์๋ ๊ธฐ์กด ์ด์ ์ ์ฑ ์ ๋ฐ๋ฅธ๋ค.
parameters.piiFiltering์ Agent๋ณ ์ ํ ๊ธฐ๋ฅ์ด๋ค. SDK ๋ชจ๋ธ ์์ฒญ์ ํ
์คํธ์ system prompt์์
ํ์งํ ๊ฐ์ [[PII:โฆ]]๋ก ์นํํ๊ณ ํ์ํ ์๋ต์์ ๋ณต์ํ๋ค. ์คํธ๋ฆฌ๋ฐ์ ํ ํฐ ๊ฒฝ๊ณ์
ํ์ Agent์ ์นํ ๋งคํ๋ ์ ์งํ๋ค. ์์ ์ฝ๋๋ application/llm/pii.ts,
runtime/model.ts, runtime/tools.ts๋ค.
| ๊ฒฝ๊ณ | ์ ๋ฌยท๋ณด๊ดํ๋ ๋ด์ฉ |
|---|---|
| ํ ์คํธ ๋ชจ๋ธ ์์ฒญยท๋ชจ๋ธ์ ๋์๊ฐ๋ ๋๊ตฌ ๊ฒฐ๊ณผ | ํ์งํ PII๋ฅผ ์นํํ๋ค |
| ์ ChatยทWorkspace์ Agent ์ถ์ฒ | Agent ์ ํ ์ ์๋ ์์ฒญ ํ ์คํธ์ ํ๋ณด ์ค๋ช ์ ํ์งํ PII๋ฅผ ์นํํด ๊ฒฐ์ ๋ชจ๋ธ์ ๋ณด๋ธ๋ค. ํธ์ถ์ ์ฌ์ฉ์๋ณ ๋ถยท์ผ ์ํ์ ๋ฐ๋๋ค |
| MCPยทFetchUrlยทํ์ผ ์์ฑ/ํธ์งยทWorkspace ๋ฑ ์ค์ ๋๊ตฌ dispatch | ๋ณต์ํ ์ธ์๋ฅผ ์ฌ์ฉํ๋ค. ์์ ์์คํ ์ ๊ทธ ๊ฐ์ ๋ณธ๋ค |
| Agent์ GenerateImageยทEditImage prompt | ์นํ๋ ์ธ์๋ฅผ ์ด๋ฏธ์ง ๋ชจ๋ธ์ ์ ๋ฌํ๋ค. ์ฌ์ฉ์์๊ฒ ๋ณด์ด๋ prompt๋ ๋ณต์ํ๋ค |
| ํ์ Agent ์์ฒญ | ์นํ๋ ๋ฉ์์ง์ ํ์ํ ๋งคํ์ ์ ๋ฌํ๋ค |
| ์ฌ์ฉ์ ์๋ตยทChat ํ๋ฉด ๊ธฐ๋กยท์์ฑ ํ์ผ | ๋ณต์ํ ๋ด์ฉ์ด๋ค. ์ ์ฅ ์ต๋ช ํ ๊ธฐ๋ฅ์ด ์๋๋ค |
| capability embeddingยทrerank | ์ต๊ทผ ์์ฒญ๊ณผ ์ ํ๋ recall ๋ฌธ๋งฅ์ ์ค๋น ๋จ๊ณ์์ ์๋ฌธ์ผ๋ก ๋ณด๋ธ๋ค |
| ์๋ Memory recall | ์ต์ ์์ฒญ์ ์ฐ๊ฒฐ๋ MCP์ ์๋ฌธ์ผ๋ก ๋ณด๋ธ๋ค. ํ์ ๊ฒฐ๊ณผ๊ฐ ๋ชจ๋ธ prompt์ ๋ค์ด๊ฐ ๋๋ ํํฐ๋ฅผ ์ง๋๋ค |
| MCP ์ ์ ํค๋ | ํ์ธํ ์ด๋ฉ์ผ ๋ฑ ํ๋ซํผ ๋ฉํ๋ฐ์ดํฐ๋ฅผ ํ๋ฌธ์ผ๋ก ์ ๋ฌํ๋ค. ํํฐ ๋์์ด ์๋๋ค |
์ด๋ฏธ์ง bytes์ ๊ฐ์ธ์ ๋ณด ์ ๊ฑฐ๋ ๋ณด์ฅํ์ง ์๋๋ค. ์ผ๋ฐ์ ์ธ ์ด๋ฆยท์ด๋ฏธ์ง ์ ๊ฐ์ธ์ ๋ณดยทํจํด์ ๋ง์ง ์๋ ๊ฐ๋ ํ์ง ๋์์ด ์๋๋ค. ํ์ง ๋ฒ์๋ email, ์ ํ๋ฒํธ, ํ๊ตญ ์ฃผ๋ฏผ/์ธ๊ตญ์ธ๋ฑ๋ก๋ฒํธ์ ์ง์ ํ์, Luhn ๊ฒ์ฌ๋ฅผ ํต๊ณผํ 13โ19์๋ฆฌ ๊ฒฐ์ ์นด๋ ๋ฒํธ๋ค. ๋ฒ์ฉ DLP๋ก ์ฌ์ฉํ์ง ์๋๋ค.
preview๋ ๋ชจ๋ธ์ ํธ์ถํ์ง ์์๋ recallยทdiscovery๋ฅผ ์ํํ ์ ์์ผ๋ฉฐ ์กฐ๋ฆฝํ ์๋ฌธ์ ๋ณด์ฌ์ค๋ค. ์ค๋น ๋จ๊ณ์ ์๋ฌธ ์ ์ก์ด ํ์ฉ๋์ง ์๋ ํ๊ฒฝ์์๋ ํด๋น capability์ ์ฐ๊ฒฐ์ ์ ํํ์ง ์์์ผ ํ๋ค. ์ธ๋ถ ์ ๊ณต์๊ฐ ๋์ผํ ๊ณ์ ์ธ์ง์ ๋ฌด๊ดํ๊ฒ ๊ฐ ์ฑ๋์ ์ ์กยท๋ณด์กด ์ ์ฑ ์ ํ์ธํ๋ค.
ํ์๋ ๊ธฐ์ต๊ณผ ์ฒจ๋ถยท๋๊ตฌ ๊ฒฐ๊ณผ๋ ์ ๋ขฐํ ์ ์๋ ํ
์คํธ๋ค. rememberedBlock์ ๊ธฐ์ต์
<recalled> ๊ฒฝ๊ณ์ ์ธ์ฉ๋ฌธ์ผ๋ก ๊ฐ์ธ ์ง์์ ๊ตฌ๋ถํ์ง๋ง prompt injection์ ์ ๊ฑฐํ์ง ์๋๋ค.
๋ฌด์์ ๊ธฐ์ตํ๊ณ ๋๊ฐ ๊ฒ์ํ ์ ์๋์ง๋ ์ฐ๊ฒฐ๋ Memory ์๋ฒ์ ์ ์ฅยท๊ถํ ์ ์ฑ
์ด ์์ ํ๋ค.
parameters.callerContext ๋ก Agent๋ณ ์ตํธ์ธ. ์ผ์ ธ ์์ผ๋ฉด Slack ๋ฐ์ ๋๊ฐ ๋ฌป๊ณ ์๋์ง๋ฅผ ๋ชจ๋ธ์๊ฒ
์๋ ค ์ฃผ๊ณ . ํ์ ์ด๋ฆ, ์๊ฐ๋, ์๋ฐํ์ URL. ํ ์ค๋ ๋์ ์ฌ๋์ด ๋ ์ด์์ด๋ฉด ํ์๋ง๋ค ๋ผ๋ฒจ์
๋ถ์ธ๋ค. Telegram ๋ฐ๊ณผ Teams ๋ฐ์ ๊ฐ์์ ์ด๋ฒคํธ๊ฐ ์ค์ด ์ค๋ ๊ฒ์ผ๋ก ๊ฐ์ ์ผ์ ํ๋ค. ๋ณด๋ธ ์ฌ๋์
์ด๋ฆ, ๊ทธ๋ฆฌ๊ณ ๊ทธ ๋ฐ์๋ ์๋ฌด๊ฒ๋ ์๋ค. ๋ ๋ค ์๊ฐ๋๋ email ๋ ๋๊ฒจ์ฃผ์ง ์๋๋ค.
์ด๋ฆ์ piiFiltering ์ด ๋ง์คํนํ์ง ์๋ PII ๋ค. ๊ทธ ํจํด๋ค์ email, ์ ํ๋ฒํธ,
๋ฑ๋ก๋ฒํธ/์นด๋ ๋ฒํธ์ ๋ง๊ณ ์ฌ๋์ ์ด๋ฆ์ ๊ทธ ์ด๋ ๊ฒ์๋ ๋ง์ง ์์ผ๋ฏ๋ก, ํธ์ถ์ ๋ธ๋ก์ด ์ฃ๋ ๊ฒ์
ํํฐ๋ง์ด ์ผ์ ธ ์์ด๋ ์ฐ์ธ ๊ทธ๋๋ก ๋ชจ๋ธ์ ๋๋ฌํ๋ค. ๊ทธ๋์ ๊ทธ ๋ธ๋ก์ email ์ ์ฃ์ง ์์ผ๋ฉฐ,
๊ทธ๋์ ์ด๊ฒ์ด ๊ธฐ๋ณธ ๋์์ด ์๋๋ผ Agent๋ณ ์ตํธ์ธ์ด๋ค. ์ผ๋ ๊ฒ์ ์ค์ ์ฌ๋์ ์ด๋ฆ์ ํ๋กฌํํธ์,
๊ทธ๋ฆฌ๊ณ ์ ๊ณต์๊ฐ ๋ก๊น
ํ๋ ๋ฌด์์๋ ์ง์ด๋ฃ๊ฒ ๋ค๋ ๊ฒฐ์ ์ด๋ค.
์ตํธ์ธ์ ๋ชจ๋ธ์ ๋ฃ์ ์ด๋ฆยท์๊ฐ๋ยท์๋ฐํ๋ฅผ ์ํ ํ๋กํ ์กฐํ๋ฅผ ๊ฒ์ดํธํ๋ค. Slack ์ private
agent ์ ๊ทผ ๊ฒ์ฌ์ artifact ์์ ์ ์๋ณ์ ํ์ํ email ์กฐํ๋ ์ตํธ์ธ๊ณผ ๋
๋ฆฝ์ ์ผ๋ก
users.info ๋ฅผ ํธ์ถํ ์ ์๋ค. ๊ทธ email ์ ๋ชจ๋ธ์ caller ๋ธ๋ก์ ๋ค์ด๊ฐ์ง ์๋๋ค.
์ด๋ฆ์ด ๋ฉ์์ง์ ํจ๊ป ๋์ฐฉํ๋ Telegram ์์๋ ์ตํธ์ธํ์ง ์์ ์ด๋ฆ์ด ๋ํ ํธ๋์คํฌ๋ฆฝํธ์ ์ฐ์ด์ง๋
์๋๋ค(๋ฐ์ดํฐ ๋
ธ์ถ๊ณผ ๋ณด์กด ์ฐธ๊ณ ). transfer ๋ ํธ์ถ์๋ฅผ
์์์๊ฒ ์ค์ด ๋๋ฅด๊ณ (RunOrigin), ๊ฑฐ๊ธฐ์ ์์ Agent ์์ ์ ์ตํธ์ธ์ด ๋ค์ ๊ฒฐ์ ํ๋ค. ๊ทธ๋์
์ด๋ฆ์ ๋ช ํ ๋จ์ด์ ธ ์๋ ๊ทธ๊ฒ์ ์์ฒญํ Agent์๋ง ๋๋ฌํ๊ณ , ์์ ์๊ฐ ํ ๋ฒ๋ ์ตํธ์ธํ์ง ์์
agent ๋ ๊ทธ๊ฒ์ ๊ฒฐ์ฝ ๋ณด์ง ์๋๋ค. ํด์๋ ํ๋กํ์ ์ํฌ์คํ์ด์ค๋ณ๋ก ๋ฉ๋ชจ๋ฆฌ์
์บ์๋๊ณ (1์๊ฐ, ์คํจ๋ 1๋ถ), ํฌ๊ธฐ๊ฐ ์ ํ๋๋ฉฐ, ๊ฒฐ์ฝ ์์๋์ง ์๋๋ค.
ํ์ ์ด๋ฆ์ ๊ณต๊ฒฉ์๊ฐ ํต์ ํ๋ค. ๋๊ตฌ๋ ์๊ธฐ ๊ฒ์ ๋ฌด์์ผ๋ก๋ ์ค์ ํ ์ ์๊ณ , ๊ทธ๊ฒ์ด ์์คํ
ํ๋กฌํํธ์ ์ค๋ฆฐ๋ค. ๊ณต์ ์ค๋ ๋์ ํ์ ๋ผ๋ฒจ์ ํตํด, ์๊ธฐ ๋ํ๋ง์ด ์๋๋ผ ๋ค๋ฅธ ์ฌ๋์ ๋ํ
์์์. callerFrom(src/domain/execution/actor.ts)์ RunCaller ๊ฐ ๋ง๋ค์ด์ง๋ ์ ์ผํ
์๋ฆฌ์ด๊ณ ๋ฐ๋ผ์ ๊ทธ ์ด๋ฆ์ ์์ ํ๊ฒ ๋ง๋๋ ์ ์ผํ ์๋ฆฌ๋ค. ์ ์ด ๋ฌธ์๋ ์ ๊ฑฐํ๊ณ , ๊ณต๋ฐฑ์ ํ ์ค๋ก
์ ๊ณ , ์ด๋ฆ์ 60์๋ก ์ ํํ๋ฉฐ, ์๋ฐํ๋ https: URL ์ผ ๋๋ง ๋ฐ์๋ค์ธ๋ค. ๊ทธ๊ฒ์ด ํ๋กฌํํธ
์ธ์ ์
์ ๋ถ๊ฐ๋ฅํ๊ฒ ๋ง๋ค์ง๋ ์์ง๋ง. ๋ฉ์์ง ๋ณธ๋ฌธ๋ ์ ๋ขฐ๋์ง ์๋๋ค. ์ ์ ๋ฉํ๋ฐ์ดํฐ๊ฐ ๋
์๊ฐ
๋ณผ ์ ์๋ ์ง์๋ฅผ ์จ๊ธธ ์๋ฆฌ๊ฐ ๋๋ ๊ฒ์ ๋ง๋๋ค.
LLM ๋ต๋ณ๊ณผ tool ๊ฒฐ๊ณผ๋ Slack mrkdwn์ผ๋ก ์ ๋ฌ๋๋ฏ๋ก ํ
์คํธ ์์ mention token์ ๋จ์ํ ํ์๊ฐ
์๋๋ค. <@Uโฆ>๋ ์ฌ์ฉ์๋ฅผ, <!subteam^โฆ>์ ์ฌ์ฉ์ ๊ทธ๋ฃน์, <!channel>ยท<!here>ยท
<!everyone>์ ๋์ ์ฒญ์ค์ ์ค์ ๋ก ์๋ฆด ์ ์๋ค. ๊ทธ ํ
์คํธ๋ ์ง๋ฌธยท์ธ๋ถ ๋ฌธ์ยท๋๊ตฌ ๊ฒฐ๊ณผ์ ์ํด
์ํฅ๋ฐ์ผ๋ฏ๋ก ์๋ฆผ ๊ถํ์ผ๋ก ์ทจ๊ธํ์ง ์๋๋ค.
neutralizeSlackMentions(src/domain/slack/outboundText.ts)๊ฐ ์๋ฆผ ๊ฐ๋ฅํ ์์ ํ token๋ง
escapeํ๋ค. slackClient๋ chat.postMessage, chat.update, ๊ทธ๋ฆฌ๊ณ stream์ text/chunk ์ถ์
Slack์ ์ฐ๊ธฐ ์ง์ ์ ๋ชจ๋ ์ด ํจ์๋ฅผ ํต๊ณผ์ํจ๋ค. ๋ฐ๋ผ์ streaming ์คํจ ๋ค edit๋ก ๋ฌผ๋ฌ๋๊ฑฐ๋
๋ง๊ฐ ์ ๋จ์ ๋ต์ ๋ค์ ๋ณด๋ด๋ ๊ฒฝ๋ก๋ ๊ฐ์ ๊ท์น์ ๋ฐ๋๋ค. ์ผ๋ฐ Markdown, URL link, channel
reference, ์๋ฆผ์ ๋ง๋ค์ง ์๋ date token์ ๋ณด์กดํ๋ค.
parameters.slackWorkspace ๋ก Agent๋ณ ์ตํธ์ธ. ์ผ์ ธ ์์ผ๋ฉด ๋ฐ์ ์๊ธฐ agent ์ ๋ด์ด ์ค์น๋
์ํฌ์คํ์ด์ค์ ์ฑ๋ ํ์คํ ๋ฆฌ, ์ค๋ ๋, ์ฌ์ฉ์ ์ด๋ฆ์ ์ฝ์ ์ ์๋ค.
Agent ๋ ๊ณต์ ์นดํ๋ก๊ทธ๋ค (private agent ๋ผ๋ฉด ๊ทธ ์ ๊ทผ ๋ฒ์ ์์์). ๋ฐ๋ผ์ agent ๋ฅผ
์คํํ ์ ์๋ ์ฌ๋์ ๋๊ตฌ๋ ๊ทธ ๋ด์ด ์ฝ์ ์ ์๋ ๊ฒ์ ์ฝ์ ์ ์๋ค. ๋ด์ด ์ด๋๋ ๋ชจ๋
์ฑ๋์ด๋ฉฐ, groups:history ๊ฐ ์ ์ฉ๋๋ ๋น๊ณต๊ฐ ์ฑ๋๋ ํฌํจ์ด๋ค. ๊ทธ๊ฒ์ด ์ด๊ฒ์ Slack ์ ์ฐ๊ฒฐ๋ ๋ชจ๋ agent ๊ฐ ๊ฐ๋ capability ๊ฐ ์๋๋ผ Agent๋ณ
์ตํธ์ธ์ผ๋ก ๋ง๋ ์ด์ ์ ๋ถ๋ค. ์ผ๋ ๊ฒ์ ์ด๋ค ์ฑ๋์ ๋ด์ฉ์ ๊ทธ ์ฑ๋ ์์ ์ ๋ฉค๋ฒ๋ณด๋ค ๋ ๋์
์ฌ๋๋ค์๊ฒ ๋ฟ๊ฒ ํ๊ฒ ๋ค๋ ๊ฒฐ์ ์ด๋ค.
๋ ๊ฐ์ง๋ ๋น ๋จ๋ ค์๊ฐ ์๋๋ผ ๊ตฌ์กฐ์ ์ผ๋ก ๊ฑฐ๋ถ๋๋ค:
-
์ฐ๊ธฐ ์์.
chat:write๋ ๋ด์๊ฒ ๋ถ์ฌ๋ผ ์๊ณ . ๋ต์ฅ ์ ์ก์ ํ์ํ๋ค. ์๋์ ์ผ๋ก ์ด๋ค ๋๊ตฌ์์๋ ๋ฟ์ ์ ์๋ค. ๋ฐ์ ์๊ธฐ๊ฐ ์ฐ์ง ์์ ํ ์คํธ์ ์กฐ์ข ๋๋ค. ๊ธ๋ ์ฌ๋ฆด ์ ์๋ ๋ฐ์, ์ด๋ค ์ฑ๋์ ์ฌ์ด ๋ ๋ฉ์์ง๊ฐ ๋ด์ผ๋ก ํ์ฌ๊ธ ๋ค๋ฅธ ๊ณณ์์ ๋งํ๊ฒ ๋ง๋ค ์ ์๋ ๋ฐ์ด๋ค. -
email ์ ๋ชจ๋ธ์ ๋๋ฌํ์ง ์๋๋ค.
users:read.email์ด ๋ถ์ฌ๋ผ ์๋๋ฐ๋ ๊ทธ๋ ๋ค.SlackUser์SlackUsers๋ ์ด๋ฆ, ์งํจ, ์๊ฐ๋, ์ํ ๋ฌธ๊ตฌ, ์๋ฐํ๋ก ๋ตํ๋ค. ๋๋ฃ๊ฐ ํ๋กํ์ ํด๋ฆญํด์ ๋ณด๋ ์ ๋ถ๋ค. ์ฃผ์๋ ๊ฒฐ์ฝ ๋ตํ์ง ์๋๋ค. ๊ทธ๊ฒ์ ํธ์ถ์ ์ปจํ ์คํธ๊ฐ ์ด๋ฏธ ์ ์ฉํ๋ ๊ท์น์ด๊ณ , ์ด์ ๋ ๊ฐ๋ค. email ์ Slack ๋ฐ์์ ์ฌ๋์ ์๋ณํ๋ฉฐ, ์ด๋ค ๋ต๋ ์ ์ฐ์ด๊ธฐ ์ํด ๊ทธ๊ฒ์ ํ์๋ก ํ์ง ์๋๋ค.์ด๋ฉ์ผ์ private Agent ์ ๊ทผ ํ์ , MCP ์์ ์ ์๊ณผ Artifact์ ๊ฐ์ธ ๊ท์์ ๋ณ๋๋ก ์ฌ์ฉํ๋ค. Slack actor๋ ๋ฐ์ ์์ Slack ์ฌ์ฉ์ ID๋ก ์ ์งํ๋ค. ๊ฐ์ธ ์์ฐ๊ณผ ๋์์ฑ์ ์ผํ์ฉ ์ฝ๋๋ก ์ฐ๊ฒฐํ Studio ์ฌ์ฉ์ ID์ ํฉ์ฐํ๋ค.
toUserDetail์ ์ด๋ฉ์ผ์ ๋ชจ๋ธ์ฉ ๋๊ตฌ ๊ฒฐ๊ณผ์ ๋ณต์ฌํ์ง ์๋๋ค. ์ด ์กฐํ๋ ๋ชจ๋ธ ํ์ ๋ฌธ๋งฅ์ ์ ์ดํ๋callerContext์ ๋ ๋ฆฝ์ ์ด๋ค.
์์ผ๋ก ์ค๋ ค ์ค๋ ๊ฒ์ ์ฒจ๋ถ๋ ๋ฌธ์์ ๋๊ฐ์ ๋ฐฉ์์ผ๋ก ์ ๋ขฐ๋์ง ์๋๋ค. ์ฑ๋์ ๋ฉ์์ง๋ ๊ทธ ์ฑ๋์
์๋ ๋๊ตฌ๋ ์ด ๊ฒ์ด๊ณ , ๊ทธ๊ฒ์ด ํ
์คํธ๋ก ๋ชจ๋ธ์ ๋๋ฌํ๋ค. PII ํํฐ๋ง์ ๋ค๋ฅธ ๊ฒ๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก ๊ทธ
๋๊ตฌ ๊ฒฐ๊ณผ์๋ ์ ์ฉ๋๋ฉฐ(parameters.piiFiltering), ํด๋ณ ๋๊ตฌ ๊ฒฐ๊ณผ ์์ฐ์ด ๊ทธ ํฌ๊ธฐ๋ฅผ ์ ํํ๋ค.
ํธ๋์คํฌ๋ฆฝํธ์ ๊ธธ์ด๋ Slack ์ด ์ ํ๋ ๊ฒ์ด๋ฏ๋ก, ํต์งธ๋ก ์ฒญ๊ตฌ๋๋ ๋์ fit ์ ๊ฑฐ์น๋ค.
๋ฆฌ๋๋ ๋ด token ์ ์ฅ๊ณ ์๊ณ , ๊ทธ๊ฒ์ ์์ฑ ์์ ์ ๋ฐ์ธ๋ฉ๋๋ค. ์ํฌ์คํ์ด์ค๋ฅผ ์ง๋ชฉํ๋ ๋๊ตฌ ์ธ์๋ ๋ชจ๋ธ์ด ์ํฌ์คํ์ด์ค๋ฅผ ๊ณ ๋ฅด๊ฒ ๋ง๋ค ๊ฒ์ด๊ณ , ๊ทธ๊ฒ์ด ์ฌ๋ฐ๋ฅธ ๋ชจ์์ธ ์์ฒญ์ ์๋ค.
๋ฌธ์์ ํ ์คํธ๋ ํด ์์ผ๋ก ๋ค์ด๊ฐ๋ฏ๋ก, ๋๊ตฌ๋ ์ฒจ๋ถํ ์ ์๋ ๊ฒ์ ๋ฌด์์ด๋ ๋งํ ์ ์๋ค. Slack ์ฑ๋์์ ๊ทธ๊ฒ์ ๋ฌป๋ ์ฌ๋๋ง์ด ์๋๋ค. ๋ด์ด ๋ณผ ์ ์๋ ๊ณณ์ ํ์ผ์ ๋จ์ด๋จ๋ฆด ์ ์๋ ๋๊ตฌ๋ ์ด๋ค.
์ด์ ๋ํด ํ๋ ์ผ: ๋ชจ๋ ๋ฌธ์๋ framedDocument(src/application/llm/documentParts.ts)๊ฐ
๊ฐ์ธ๋ฉฐ, ํ์ผ์ ์ด๋ฆ์ ๋ฐํ๊ณ ์ด๋์ ๋๋๋์ง๋ฅผ ํ์ํ๊ณ ๊ทธ ๊ตฌ๊ฐ์ ๋ฐ์ดํฐ๋ก ๋ค๋ฃจ๊ณ ๊ฒฐ์ฝ ์ง์๋ก
๋ค๋ฃจ์ง ๋ง๋ผ๊ณ ๋ชจ๋ธ์๊ฒ ๋งํ๋ค. ์ด๋ฆ์ JSON ์ด์ค์ผ์ดํ๋๋ฏ๋ก ์กฐ์๋ ํ์ผ๋ช
์ด ๋ ํ์๋ฅผ ์์กฐํ ์
์๋ค.
๊ทธ๊ฒ์ ์ํ์ด์ง ํด๊ฒฐ์ด ์๋๋ค. ์ด๋ค ๋ฌธ๊ตฌ๋ ์ฃผ์ ๋ ํ ์คํธ๋ฅผ ์์ ํ๊ฒ ๋ง๋ค์ง ๋ชปํ๊ณ , ๋ฉ์์ง ๋ณธ๋ฌธ์ ์ด๋ฏธ ์ ๋ขฐ๋์ง ์์๋ค. agent ์ ๊ถํ์ ๊ทธ์ ๋ง์ถฐ ์ก์๋ผ. ์ฒจ๋ถ๋ฅผ ์ฝ๋ agent ๋ ํ์ผ์ ๋ ๋ฏ์ ์ฌ๋์๊ฒ ์ฃผ์ง ์์ ๊ถํ์ ์ฅ๊ณ ์์ด์๋ ์ ๋๋ค.
์์ ๋ ๋งํ ๋ค๋ฅธ ์์ฑ๋ค:
- ๋ฌธ์๋ ์ฝํ ๋ฟ, ์คํ๋๊ฑฐ๋ ๋ ๋๋ง๋์ง ์๋๋ค. ์ถ์ถ์ ํ ์คํธ๋ง ๋ด๋๋๋ค. HTML ์ ๋งํฌ์ ๊ณผ ํ์ฑ ๋ด์ฉ์ ์ ๊ฑฐํ ํ ์คํธ๋ก ์ฝํ๋ฉฐ, ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ๊ฑฐ๋ ์ธ๋ถ ๋ฆฌ์์ค๋ฅผ ๊ฐ์ ธ์ค์ง ์๋๋ค.
- ๋ฌธ์๋ฅผ ๋์ ํด ๋ฌด์ธ๊ฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๊ฒ์ ์๋ค. ์ฒจ๋ถ ์์ URL ์ ๋ค๋ฅธ ๊ฒ๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก ํ ์คํธ์ผ ๋ฟ์ด๋ค. Agent๊ฐ ๋ฐ์ธ๋ฉํ ๋๊ตฌ๋ง์ด ๊ทธ๊ฒ์ ์์ฉํ ์ ์๊ณ , ๊ทธ ๋๊ตฌ ์์ ์ ๊ฐ๋ ์๋์์ ๊ทธ๋ ๋ค.
- ํ ์คํธ๋ PII ํํฐ๋ฅผ ์ง๋๋ค. Agent๊ฐ ์ตํธ์ธํ๋ฉด ํด์ ๋๋จธ์ง์ ๋ง์ฐฌ๊ฐ์ง์ด๊ณ , ํ๊ณ๋ ๊ฐ๋ค (email, ์ ํ๋ฒํธ, ํ๊ตญ ๋ฑ๋ก๋ฒํธ, ์นด๋ ๋ฒํธ, ์ด๋ฆ์ ์๋๋ค).
- Chat์ ์๋ณธ๊ณผ ์ถ์ถ๋ฌธ์ ๋ถ๋ฆฌํด ๋ณด๊ดํ๋ค. ํด๋น ์ต๋ 40,000์์ ์ถ์ถ๋ฌธ๊ณผ ํ์ผ ์ฐธ์กฐ๋
์์ ์ ์ ์ฉ chat ํ์ ๋จ๊ณ , ์๋ณธ์
source: attachment์ธ artifact๋ก ์ ์ฅํ๋ค. ์๋ณธ์ ๊ธฐ์กด artifact์ ๊ฐ์ ์์ฑ์ยทAgent ์์ ์ ์ฝ๊ธฐ ์ ์ฑ , artifact ๋ณด์กด ๊ธฐ๊ฐ๊ณผ ์ค๋ธ์ ํธ ์ ๊ทผ ๋ชจ๋๋ฅผ ๋ฐ๋ฅธ๋ค. ์๋ณธ์ chat ์ญ์ ๋ง์ผ๋ก ์ญ์ ๋์ง ์์ผ๋ฉฐ artifact ์ญ์ ยท๋ณด์กด ์ ์ฑ ์ด ์์ ํ๋ค.
- Trace ๋ ์ ํ๋ ๋ฉํ๋ฐ์ดํฐ๋ง ์ ์ฅํ๋ค. ๋ฌธ์ ์, token, ๋น์ฉ, ์์ ์๊ฐ, subagent ์
trace id. ์๋ณธ ํ๋กฌํํธ์ ๋๊ตฌ ๊ฒฐ๊ณผ๋ ์์๋์ง ์์ง๋ง, trace ์
error์warnings๋ ์คํจ ํ ์คํธ๋ฅผ ๊ทธ๋๋ก ์ต๋ 1,000์๊น์ง ๋ณด๊ดํ๊ณ , ์ ๊ณต์๋ ๋๊ตฌ์ ์๋ฌ ๋ฌธ์์ด์ ๋ด์ฉ์ ํ์ ์ ์๋ค. - ๋ฐ์ ์ถ๋ก ์ ์ผ Agent์์ ๋ณต์๋ ์ฑ๋ก ์ ์ฅ๋๋ค.
parameters.reasoningTrace๋ฅผ ์ผ Agent๋ assistant ๋ฉ์์ง์ ๊ทธ ๋ฐ์ ์ฌ๊ณ ๋ฅผ ๋จ๊ธฐ๋๋ฐ(AssistantChatMessage.reasoning, ๋ฉ์์ง๋น ์ต๋ 40,000๋ฐ์ดํธ), ๊ทธ๊ฒ์content์ ๊ฐ์ ์ถ์ฒ. ์ฆ ๋ง์คํน์ด ํ๋ฆฐ ํ ์คํธ๋ค. PII ํํฐ๋ ๋ชจ๋ธ์ด ๋ณด๋ ๊ฒ์ ์ ํํ์ง ์ฝ์์ ์ ์ฅ๋๋ ๊ฒ์ ์ ํํ์ง ์์ผ๋ฏ๋ก(content๋ ๋ง์ฐฌ๊ฐ์ง๋ค),piiFiltering์ ์ผ Agent์์๋ ์ถ๋ก ์ ๊ฑธ๋ฌ์ง์ง ์์ ์ฑ chat ํ์ ์๋๋ค. ์ถ๋ก ์ ์์ฒญ์ ๋ชจ๋ธ ์์ ์ ๋ง๋ก ๋ํ์ดํ๋ ์๋ฆฌ๋ผ ์ ๋ ฅ์ด ์ค์ด ์จ ๊ฒ์ ๊ทธ๋๋ก ํ๊ธฐ ์ฝ๋ค. ์ตํธ์ธ์ธ ์ด์ ๊ฐ ์ด๊ฒ์ด๊ณ , ๋ณด์กด ๊ธฐ๊ฐ์ chat ํ๊ณผ ๊ฐ๋ค(RETENTION.chatDays). /api/metrics๋ agent, ์ฌ์ฉ์, model ์ ์ง๋ชฉํ์ง ์๋๋ค. ๋ฉํธ๋ฆญ ๋ผ๋ฒจ์ ํ์คํ ๊ทธ๋จ์le์ build ์ ๋ณด์ ์ ํํversionยทstage๋ฟ์ด๋ค.- ๋ก๊ทธ ๋ผ์ธ์ ๋ฐ์ correlation id ๋ฅผ ์ค์ ๋ฟ, ํ๋กฌํํธ ๋ด์ฉ์ ๊ฒฐ์ฝ ์ฃ์ง ์๋๋ค.
- Trace, usage ํ, chat, trigger ๋ฐฐ๋ฌ ํ์ ๋ชจ๋
expiresAt์ ์ง๋๊ณ schedule-scan ํฑ์ sweep ์ด ์ง์ด๋ค. scan ํธ์ถ์ด ์๋ ๋ฐฐํฌ์์๋ ์ด DB sweep์ด ์คํ๋์ง ์๋๋ค. OPERATIONS.md ์ฐธ๊ณ . - ๋ฉ์์ง ํ์ผ ์ฐธ์กฐ ๊ธฐ๋ก์ SlackยทTelegramยทTeams์์ ๋ํยทactor๋ณ๋ก ์์ฑ ํ์ผ ID์
์ด๋ฆ๋ง 7์ผ๊ฐ ๋ณด๊ดํ๋ค. URL์ด๋ ๋ฐ์ดํธ๋ ๊ธฐ๋กํ์ง ์๋๋ค. ์ต๊ทผ 20๊ฐ ๊ธฐ๋ก, ๊ธฐ๋ก๋น 20๊ฐ
ํ์ผ, ๋ฐ๋น 20,000์๋ก ์ ํํ๋ฉฐ ์ฐธ์กฐ๋ฅผ ์ป์ด๋
File๋๊ตฌ์ ๊ถํ ๊ฒ์ฌ๋ฅผ ํต๊ณผํด์ผ ํ๋ค. - TelegramยทTeams ๋ํ ํธ๋์คํฌ๋ฆฝํธ ๋ agent ์ ๋ด๊ณผ ์ฃผ๊ณ ๋ฐ์ ๋ชจ๋ ํด์ ํ
์คํธ ๋ฅผ 7์ผ๊ฐ
๋ณด๊ดํ๋ค. ๋ํ๋ณ๋ก ์ง๋ฌธ๊ณผ ๋ต์. ๋ ํ๋ซํผ ๋ชจ๋ ํ์คํ ๋ฆฌ๋ฅผ ๋๋ ค์ฃผ์ง ์์ ํ์ ์ง๋ฌธ์ด ๊ทธ ์์
์ง๋ฌธ์ ์ค์ด ๋ ๋ผ์ผ ํ๊ธฐ ๋๋ฌธ์ด๋ค. ๊ทธ๊ฒ์ chat ๋ฉ์์ง์ฒ๋ผ ์ ์ฅ๋ ์ฌ์ฉ์ ํ
์คํธ๋ค. chat ๊ณผ ๋ฌ๋ฆฌ
๊ทธ ๋ํ์ ๋ค์ ๋ฐ ์ธ์๋ ์๋ฌด๊ฒ๋ ๊ทธ๊ฒ์ ์ฝ์ง ์๋๋ค. ๋ณด๋ธ ์ฌ๋์ ํ๋ซํผ ์ฌ์ฉ์ id(Telegram
user id, Teams ๋ Entra object id)๋ ํด ์์ ์ ์ฅ๋๊ณ , ๋ณด๋ธ ์ฌ๋์ ์ด๋ฆ ์ Agent๊ฐ
callerContext์ ์ตํธ์ธํ์ ๋๋ง ์ ์ฅ๋๋ฉฐ, ์ตํธ์ธ์ ๋ Agent๋ ์ด์ ์ ์ ์ฅ๋ ์ด๋ฆ๋ ์ฝ์ง ์๋๋ค. ํ์ agent ํํฐ์ ์ ์์ด agent ๋ฅผ ์ง์ฐ๋ฉด ํจ๊ป ์ง์์ง๋ค. - ์์ฑ๋ ์ด๋ฏธ์ง ๋
S3_BUCKET_NAME์ด ์ค์ ๋ผ ์์ผ๋ฉด ์ถ์ธกํ ์ ์๋ UUID ํค ์๋ ์ ์ฅ๋๊ณ , chat ํ์ ์ฃผ์๊ฐ ์๋๋ผ ์ค๋ธ์ ํธ ํค ๋ฅผ ๋ณด๊ดํ๋ค. ์ฝ๊ธฐ ์์ ์ ํค๊ฐ ์ฃผ์๊ฐ ๋๋ฉฐ, ์๋ช ์ ๋ ์์ ๋ง์ถฐ ๊ณ ๋ฅธ๋ค. chat ๋ทฐ์๋ 15๋ถ, ๋ฉ์์ง ๋ต๋ณ์ ํฌํจ๋ ๋งํฌ์๋ 7์ผ(SigV4 pre-sign ์ ์ํ์ด๊ณ , proxied ํ ํฐ๋ ๊ฐ์ ๊ฐ์ ์ด๋ค). ๊ทธ ๋งํฌ๋ ๊ทธ๊ฒ์ด ํจ๊ป ์จ ๋ต์ ์ด๋ฏธ ์ฝ์ ์ ์๋ ์ฒญ์ค์ด ์ฅ๋ค(src/shared/artifactUrlTtl.ts). ์ฃผ์์ ๋ชจ์ ์ARTIFACT_ACCESS_MODE๊ฐ ์ ํ๋ค:-
proxied. ์คํ ์ด๋ ์ฑ์๊ฒ๋ง ๋ฟ๊ณ ๋ ์๋ ์ฑ์ ์ฃผ์PUBLIC_BASE_URL/api/objects/<key>?exp=<unix>&sig=<hmac>[&dl=<filename>]๋ฅผ ๋ฐ๋๋ค (src/infrastructure/storage/objectUrlToken.ts). ๊ทธ ๋ผ์ฐํธ๋ ์ธ์ ์ ์๊ตฌํ์ง ์์ผ๋ฉฐ ๊ทธ๊ฒ์ด ๊ณ์ฝ์ด๋ค: ์ฃผ์๋ฅผ ์ฅ๋ ๊ฒ์<img>ํ๊ทธ์ Slack ๋ฉ์์ง๋ผ ์ฟ ํค๋ฅผ ๋ผ ์ ์๋ค. ํ ํฐ์ด ์๊ฒฉ ์ฆ๋ช ์ด๋ค. ํคยท๋ง๋ฃยทํ์ผ๋ช ์ ํจ๊ป ๋ฎ๋ HMAC-SHA256 ์ด๊ณ , ์๋ช ํค๋AES_ENCRYPTION_KEY์์ HKDF(agent-studio/object-url/v1)๋ก ํ์๋์ด ๊ทธ ๋ฐ์ดํธ๊ฐ ์ ์ฅ๋ ํ ํฐ์ ์ํธํํ๋ ๋ฐ์ดํธ์ ๊ฒฐ์ฝ ๊ฐ์ง ์๋ค. ์ฆ๋ช ํ๋ ๊ฒ์ ์ด ๋ฐฐํฌ๊ฐ ์ด ํค์ ๋ํด ์ด ์๋ช ๊ณผ ์ด ํ์ผ๋ช ์ผ๋ก ๋ฐํํ๋ค ๋ ์ฌ์ค๋ฟ์ด๋ค. ํ์ผ๋ช ์ ์ฅ์์ด ์๋๋ผ ์๋ช ์ ๋ฌถ์ฌ ์์ดdl์ ๋ผ์ด ๋ค์ด๋ก๋๋ฅผ ์ธ๋ผ์ธ ๋ณด๊ธฐ๋ก ๋ฐ๊ฟ ์ ์๊ณ , ๋ง๋ฃ์ ์๋ช ๋ถ์ผ์น๋ ํ๋์ 403 ์ผ๋ก ๋ตํ๋ค(๋์ ๊ตฌ๋ณํด ์ฃผ๋ฉด ์์กฐ์์๊ฒ ์ด๋ ์ชฝ์ ๊ณ ์น ์ง ์๋ ค ์ค๋ค). ์์ด์ง ์ค๋ธ์ ํธ๋ 404, ์ฝ๊ธฐ๋MAX_PROXIED_OBJECT_BYTES์์ ๋๊ธฐ๋ฉฐ,Cache-Control: private์ max-age ๋ ํ ํฐ์ ๋จ์ ์๋ช ์ ๋์ง ์๋๋ค. ๋ฐ์ดํธ๋ ์ฝ์์ origin ์์ ๋๊ฐ๋ฏ๋ก ๋ธ๋ผ์ฐ์ ๊ฐ ๋ฌธ์๋ก ๋ ๋ํ ์ ์๋ ํ์ (HTML, SVG, ํ ์คํธ)์/view์ ๊ฐ์sandbox; default-src 'none'์๋ ๋ถํฌ๋ช origin ์ ๋์ด๊ณ , ๋์คํฐ ์ด๋ฏธ์ง์ PDF ๋งframe-ancestors 'none'์ผ๋ก ๋๋๋ค.next.config.ts๊ฐ ์ด ์ฃผ์๋ฅผ ์ฝ์ ํค๋์์ ์ ์ธํ๋ ์ด์ ๊ฐ ๊ทธ๊ฒ์ด๋ค. -
authenticated. ์คํ ์ด์ pre-signed URL. ์คํ ์ด๊ฐ ๋ธ๋ผ์ฐ์ ์์ ๋ฟ์์ผ ํ๊ณ ๋ฒํท์ ๋น๊ณต๊ฐ๋ก ๋จ๋๋ค. -
public. ์๊ตฌ์ ์ธ ์ง์ URL. ๋ช ์์ ์ธ ๊ณต๊ฐ ์ฝ๊ธฐ ๋ฒํท ์ ์ฑ ์ ์๊ตฌํ๊ณ URL ์ ์ป์ ๋๊ตฌ์๊ฒ๋ ๋ฐ์ดํธ๋ฅผ ๋ ธ์ถํ๋ค. ์ ํ๋ฆฌ์ผ์ด์ ์ธ์ฆ์ ์ฌ์ ํ ๊ฐค๋ฌ๋ฆฌ ๋ฉํ๋ฐ์ดํฐ์ ์ญ์ ๋ฅผ ๋ณดํธํ์ง๋ง ์ค๋ธ์ ํธ๋ ๋ณดํธํ์ง ์๋๋ค. ์ฃผ์๊ฐ ๋ณด๊ธฐ๊ฐ ์๋๋ผ ๋ค์ด๋ก๋์ธ ๊ณณ์์๋ ์ด์จ๋ ๋ฏธ๋ฆฌ ์๋ช ํ๋ค. ๋ธ๋ผ์ฐ์ ๊ฐ ์ ์ฅํ ํ์ผ ์ด๋ฆ์ResponseContentDisposition์ด ์ค์ด ๋๋ฅด๋๋ฐ S3 ๋ ์ต๋ช GET ์์ ๊ทธ๊ฒ์ ๊ฑฐ๋ถํ๋ฏ๋ก, ์๋ช ๋์ง ์์ ๋งํฌ๋ ์ค๋ธ์ ํธ๋ฅผ UUID ํค๋ก๋ง ์ ์ฅํ ์ ์๋ค. -
๋ ๊ฑฐ์ ํ์ ๊ณต๊ฐ
url์ ์ง๋๊ณ ์์ ์ ์๊ณ ๊ทธ๋๋ก ๋์ฝํ๋ค. ๊ทธ๊ฒ์ ๋ค์ ์ด๋ค๊ณ ํด์ ์ด๋ฏธ ๊ณต๊ฐ์ธ ๊ทธ ์ค๋ธ์ ํธ๋ค์ ๋๊ฐ ๋ฟ์ ์ ์๋์ง๋ ์๋ฌด๊ฒ๋ ๋ฐ๋์ง ์๋๋ค. ๊ณต๊ฐ ๋ ธ์ถ ์ฌ๋ถ๋ ํ์ฌ bucket policyยทACL์ด ๊ฒฐ์ ํ๋ค. ์ฑ์ metadata๋ access mode๋ง ๋ฐ๊ฟ์๋ ๊ธฐ์กด ๊ฐ์ฒด๋ฅผ ๋น๊ณต๊ฐ๋ก ์ ํํ์ง ๋ชปํ๋ค. ์ ์ฑ ์ ๋ซ์ผ๋ฉด ์ ๊ณต๊ฐ URL๋ ๋๋ ์ ๊ทผ๋์ง ์์ ์ ์๋ค. -
ํ์ด์ง๋ ์ค๋ธ์ ํธ ์ฃผ์๋ก ๋๊ฐ์ง ์๋๋ค.
SAVABLE_TYPES์ ํฌํจ๋, ์ฌ๋์ด ์ฝ๋๋ก ๋ง๋ artifact ๋ง/view๋ฅผ ํตํด ์ฑ์ด ๋ฐ์ดํธ๋ก ๋ตํ๋ค. ์๋ช ํ ์ค๋ธ์ ํธ URL ์ sandbox ํค๋๋ฅผ ์ค์ ์ ์๊ณ , ํ ๋ฒ ๊ฑด๋ค์ง๋ฉด ๊ทธ๊ฒ์ ์ฐ ์ฌ๋์ ๊ถํ๋ณด๋ค ์ค๋ ์ด๋ฉฐ,public๋ชจ๋์์๋ ์๊ตฌ๋ค. ์์์ ๋งํฌ์ ์ด ์คํ๋๋ ์๊ตฌ ์ฃผ์๋ ์ ์ฅ์๊ฐ ์๋๋ผ ํธ์คํ ์ด๋ค./view๋ ์ญ์ ์ ๊ฐ์ ์กฐ๊ฑด์ผ๋ก ๋งค ์์ฒญ์ ์ธ๊ฐํ๊ณ ,Content-Security-Policy์sandbox๋ก ๋ฌธ์๋ฅผ ๋ถํฌ๋ช ์ค๋ฆฌ์ง์ ๋๋๋ค. HTML ์๋ฌธ์ ๋ณ๋์ iframe์๋ง ๋ค์ด๊ฐ๊ณ ์ฝ์์ ์ฟ ํคยท์คํ ๋ฆฌ์งยทDOM์ ๋ฟ์ง ๋ชปํ๋ค.nosniff์no-referrer๋ ํจ๊ป ์ ์ฉํ๋ค. -
HTML์ ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋ฅผ ์ฌ๋ ์ฆ์ ๊ฒฉ๋ฆฌ๋ iframe์์ ์คํํ๋ค. ์๋ฌธ์ ์ ์ธ๋ charset์ผ๋ก ์๊ฒฉํ๊ฒ ๋์ฝ๋ฉํ๊ณ , ์ ์ฒด ๋ด์ฉ์ ์ด์ค์ผ์ดํํ
srcdoc์์ฑ์ผ๋ก ์ ๋ฌํ๋ค. ๋ฐ๊นฅ ํ๋ฉด์๋ ์ ํ์ ์ ์ด ์ฝ๋๋ง ์คํ๋๋ฉฐ, ์๋ฌธ scriptยท์ด๋ฒคํธยทcanvasยทSVG๋ iframe ์์์ ๋ณด์กดํ๋ค. HTTP CSP์ iframe ๋ชจ๋sandbox allow-scripts๋ฅผ ์ ์ฉํ๊ณallow-same-origin, top-navigation, popup, form, download ๊ถํ์ ์ฃผ์ง ์๋๋ค. iframe์ ์ ๊ฑฐํ๋ฉด ์คํ ์ํ๋ฅผ ๋ฒ๋ฆฌ๊ณ , ๋ค์ ์์ํ๋ฉด ์๋ณธ์ ์ iframe์ ๋ฃ๋๋ค. ์ฝ๋ ์ค๋ฅ๋ ์ํ๋ฅผ ์ ์ฅ ์ฑ๊ณต๊ณผ ํผ๋ํ์ง ์๋๋ค. -
๊ฒฉ๋ฆฌ์ ํต์ ์ ํ์ ๋ฒ์๋ฅผ ๊ตฌ๋ถํ๋ค. HTML์
INTERACTIVE_HTML_VIEW_POLICY๋ fetch/XHR/WebSocket, ์ธ๋ถ scriptยทCSSยทimageยทfont, worker, ์ธ๋ถ ํ๋ ์ ์ด๋๊ณผ ํผ ์ ์ถ์ ์ ํํ๋ค.frame-src 'none'์ inline srcdoc์ ํ์ฉํ๋ฉด์ ๋คํธ์ํฌ frame ํ์์ ๋ง๋๋ค. ๋ด๋ถ ๋ชฉ์ฐจ ๋งํฌ๋ ๊ธฐ์ค URL์about:srcdoc์ผ๋ก ์ง์ ํด ์ฒ๋ฆฌํ๋ฉฐ,base-uri about:์ผ๋ก ์ธ๋ถ ๊ธฐ์ค URL์ ๊ฑฐ์ ํ๋ค. ์นด๋ฉ๋ผยท๋ง์ดํฌยท์์น ๋ฑ์ Permissions Policy๋ก ์ ํํ๋ค. ์ด ์ ์ฑ ์ WebRTC ๋ฑ ๋ชจ๋ ๋ธ๋ผ์ฐ์ ํต์ ์ด๋ CPUยท๋ฉ๋ชจ๋ฆฌ๋ฅผ ๊ฐ์ ๊ฒฉ๋ฆฌํ์ง ์๋๋ค. ๋ฏธ๋ฆฌ๋ณด๊ธฐ ์ด๊ธฐ๋ HTML ์ฝ๋ ์คํ์ ํฌํจํ๋ฏ๋ก ์ ๋ขฐํ๋ ํ์ผ์ ๋ค๋ฃฌ๋ค๋ ์ ์ ๋ก ์ฌ์ฉํ๋ค. ์์ ํ ๋ฌดํต์ ยท์์ ๊ฒฉ๋ฆฌ๊ฐ ํ์ํ๋ฉด ๋ณ๋์ ์คํ ํ๊ฒฝ์ด ํ์ํ๋ค. iframe์์ ๋ณด๊ณ ํ ์ค๋ฅ๋ ํ์ฌ iframe์ Window๋ฅผ ํ์ธํ ๋ค ๊ณ ์ ์๋ด๋ก๋ง ํ์ํ๋ค. ์ฐจ๋จ๋ ๋ฆฌ์์ค์ ์ธ๋ถ ์ด๋๋ ๊ณ ์ ์๋ด๋ก ํ์ํ๊ณ , ์คํฌ๋ฆฝํธ ์ค๋ฅ๋ฅผ ์ฐ์ ํ๋ค. ์ค๋ฅ ์๋ฌธยท์ฃผ์๋ฅผ ๋ถ๋ชจ ํ๋ฉด์ ๋ ๋ํ๊ฑฐ๋ ์๋ฒ๋ก ๋ณด๋ด์ง ์์ผ๋ฉฐ ํน๊ถ APIยท์ธ์ฆ ์ ๋ณด๋ ์ ๋ฌํ์ง ์๋๋ค. -
์ ์ view๋ ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ์ง ์๋๋ค.
ARTIFACT_VIEW_POLICY์๋ ์ด๋คallow-*๋ ๋ถ์ด์ง ์๋๋ค. Markdown์ raw HTML์ ํ ์คํธ๋ก ๋ด๋ณด๋ด๊ณ , CSV๋ ์ด์ค์ผ์ดํ๋ ํ, SVG๋<img>๋ก ํ์ํ๋ค. HTML ์คํ ์ ์ฑ ์ ์ด ๊ฒฝ๋ก์ ์ ์ฉํ์ง ์๋๋ค. -
์ ์ญ ํค๋์์ ์ถฉ๋์ ๊ฒ์ฌํ๋ค.
next.config.ts๋ ์์ฒด CSP๋ฅผ ์ฌ์ฉํ๋ ๋ ๊ฒฝ๋ก๋ฅผ ์ ์ธํ๋ค. ์ ํ์ผ ์๋ต์ด๋ ์ ์ฑ ๋ณ๊ฒฝ๋ ์๋ต ํค๋์ ๊ฒฝ๊ณ๋ฅผ ์ ์งํด์ผ ํ๋ค. -
์ผ๋ฐ ๋ฐ Artifact์ object ๋ง๋ฃ๋ ์ ์ฅ์ ์ ์ฑ ์ด ๋ด๋นํ๋ค. ํฑ์ ๋ฉํ๋ฐ์ดํฐ ํ์ ์ง์ฐ๋ฉฐ
artifacts/์ bytes์๋ ๋ณ๋ lifecycle์ ์ ์ฉํ๋ค. ๋น๊ณต๊ฐsource-files/๋ worker๊ฐ ํ์ผ๋ณ ๋ณด์กด ๊ธฐํ์ ๊ฒ์ฌํ๊ณ ๋ณธ๋ฌธ์ ์ญ์ ํ์์ผ๋ก ๊ต์ฒดํ๋ฏ๋ก ๊ฐ์ ์ผ๊ด ๋ง๋ฃ ๊ท์น์ ์ ์ฉํ์ง ์๋๋ค. INSTALL.md์ ์ ์ฅ์ ์ ์ฑ ์ ๋ฐ๋ฅธ๋ค.
-
- ๋น๊ณต๊ฐ ํ์ผ Artifacts๋ ๊ฐ์
S3_BUCKET_NAME์ ์ฌ์ฉํ์ง๋ง ์ผ๋ฐ object ์ ๊ทผ ๊ฒฝ๋ก๋ก ์ฝ๊ฑฐ๋ URL์ ๋ฐ๊ธํ ์ ์๋ค.source-files/ํค๋ ์ผ๋ฐ ์ด๋ํฐ์ bearer URL ๊ฒ์ฆ์์ ๊ฑฐ์ ํ๋ฉฐ, ์์ ์ยทAgentยทํ์ผ ์ํยท๋ง๋ฃ๋ฅผ ํ์ธํ๋ ๋ค์ด๋ก๋ยท๋ฏธ๋ฆฌ๋ณด๊ธฐ ๊ฒฝ๋ก๋ง ์ฌ์ฉํ๋ค.public๋ชจ๋์์๋ ๊ฐ์ ธ์ค๊ธฐ ์ ์ ๋น๊ณต๊ฐ ํ์ผ ์ฐ๊ธฐ๋ฅผ ๊ฑฐ์ ํ๋ค. ์ค์ bucket policy์ ACL์ ์ต๋ช ์ฝ๊ธฐ ์ฐจ๋จ์ ๋ฐฐํฌ ํ๊ฒฝ์ด ์์ ํ๋ค. - Artifact ํ ์ ๋ฐ์ด ๋ง๋ค์ด ๋ธ ๋ชจ๋ ์ค๋ธ์ ํธ๋ฅผ ์ง๋ชฉํ๊ณ , ๊ทธ๊ฒ์ด ์ ์ฅ๋ ์ด๋ฏธ์ง๋ ๋ฌธ์๋ฅผ
๋์ดํ๊ณ ์ง์ธ ์ ์๊ฒ ๋ง๋๋ ์ ๋ถ๋ค. ์ธ๊ธํ ๋งํ ๊ท๊ฒฐ์ด ์
์๋ค:
- ํ์ ๊ฐค๋ฌ๋ฆฌ๋ฅผ ์ฝ์ ์ ์๊ฒ ํ๋ ค๊ณ ํ๋กฌํํธ์ 500์ ๋ฐ์ท ๋ฅผ ๋ณด๊ดํ๋ค. ๊ทธ๊ฒ์
ARTIFACT_RETENTION_DAYS๋์ ์ฌ๋ ์ฌ์ฉ์ ํ ์คํธ์ด๋ฉฐ, ๊ทธ๊ฒ์ ์ค์ด ์จ chat ๋ฉ์์ง๋ณด๋ค ์ค๋ ๋จ๋๋ค. PII ํํฐ๋ง์ ๋ชจ๋ธ ์ด ๋ณด๋ ๊ฒ์ ํ์ ํ ๋ฟ, ์ ์ฅ๋๋ ๊ฒ์ ํ์ ํ์ง ์๋๋ค. - agent ์ artifact ํญ์ ๊ทธ Agent์ ์์ ์๊ฐ ์ฝ์ ์ ์๋ค. trace ๊ฐ ์ฐ๋ ๊ฒ๊ณผ ๊ฐ์ ๊ท์น์ด๊ณ , ์ด์ ๋ ๊ฐ๋ค(๋ค๋ฅธ ์ฌ๋์ ๋ฐํ์ ์ถ๋ ฅ์ ๋ด๊ณ ์๋ค). ์ค์ ๋ก๋ trace ๋ณด๋ค ๋ ๋์ ๋ ธ์ถ์ด๋ค. Agent trace๋ ํญ์ ๊ธฐ๋กํ๊ณ ๊ธฐ๋ณธ 30์ผ์ ๋ณด๊ดํ์ง๋ง, artifact ๋ ๋ชจ๋ ์ค๋ธ์ ํธ์ด๊ณ 180์ผ์ ๋ณด๊ดํ๋ค.
- artifact ๋ฅผ ์ง์ฐ๋ฉด ์ค๋ธ์ ํธ๋ฅผ ๋จผ์ , ํ์ ๋์ค์ ์ง์ฐ๋ฏ๋ก ์ค๋จ๋ ์ญ์ ๋ ์ฌ์๋๋ก ์๋ ดํ๋ค. chat ๋ฉ์์ง๋ ๊ทธ ํค์ ์ฌ๋ณธ์ ์๊ธฐ ์์ ๊ฐ๊ณ ์์ผ๋ฏ๋ก ํธ๋์คํฌ๋ฆฝํธ๋ ๊ทธ ๋ค๋ก ์ด๋ฏธ์ง๋ฅผ ์ฌ์ฉํ ์ ์์์ผ๋ก ๋ ๋๋งํ๋ค. ํ์ธ ๋ฌธ๊ตฌ๊ฐ ๊ทธ ์ฌ์ค์ ๋ฏธ๋ฆฌ ๋งํด ์ค๋ค.
- ํ์ ๊ฐค๋ฌ๋ฆฌ๋ฅผ ์ฝ์ ์ ์๊ฒ ํ๋ ค๊ณ ํ๋กฌํํธ์ 500์ ๋ฐ์ท ๋ฅผ ๋ณด๊ดํ๋ค. ๊ทธ๊ฒ์
- ์ ์ถ๋ ๊ฐ์ธ ํ ํฐ์ ํ๊ธฐยท์ฌ๋ฐ๊ธํ๋ค. ๋ณธ์ธ APIยทWebhook ํ ํฐ์ Integrations ๋๋
DELETEยทPOST /api/agents/{name}/token๋ฐโฆ/webhook-token์ผ๋ก ๊ด๋ฆฌํ๋ค. ์คํ์ ํ์ฌ ๊ณ์ ยทcredential์ ๋ค์ ๊ฒ์ฌํ๋ค. - ์ค์ ์ ํ๋ ์ฆ์๊ฐ ์๋๋ค. ๊ฐ๋ฑ๋ admin์ ๊ถํ ๋ณ๊ฒฝ๋ ๊ทธ ์ฐ๊ธฐ๋ฅผ ์ฒ๋ฆฌํ์ง ์์
์ธ์คํด์ค์์ ์ค์ ์บ์๊ฐ ๋ง๋ฃ๋ ๋๊น์ง ๊ณ์ ๋์ํ๋ค(
SETTINGS_CACHE_TTL_MS, ๊ธฐ๋ณธ 5์ด). ์ธ์คํด์ค ๊ฐ ์ฆ์ ์ทจ์์๋ ๊ณต์ ๋ฌดํจํ ์ ํธ๊ฐ ํ์ํ๋ฐ, ์์ง ์๋ค. ์ฐ๊ธฐ๋ฅผ ์ฒ๋ฆฌํ ์ธ์คํด์ค๋ ์บ์ ์ธ๋๋ฅผ ์ฐ๋ฏ๋ก, ์ด๋ฏธ ์งํ ์ค์ด๋ ์ฝ๊ธฐ๊ฐ ๋ฌดํจํ๋ ํญ๋ชฉ์ ๋ค์ ์ฑ์ธ ์ ์๋ค. - ์ธ์ฆ rate limit ์ ํด๋ผ์ด์ธํธ IP ๋ก ํค์ํ๊ณ , ํ๋ก์ ๋ค์์ ๊ทธ๊ฒ์
TRUSTED_PROXY_CIDRS๋ก ํด์๋๋ค. CONFIGURATION.md ์ฐธ๊ณ . ํ๋ก์ ๋ ๋ค์์ ๊ทธ๊ฒ์ ๋น์ ๋๋ฉด ๋ชจ๋ ์์ฒญ์ด ๊ฐ์ ํ์ผ๋ก ํด์๋ผ ํ๋์ ๊ณต์ ๋ฒํท์ ๋จ์ด์ง๋ฏ๋ก, ๋ฆฌ๋ฏธํฐ๋ ๋จ์ฉ์๊ฐ ์๋๋ผ ํจ๋ ์ ์ฒด๋ฅผ ์กฐ์ธ๋ค. - AWS ์๊ฒฉ ์ฆ๋ช
์ AWS ๋ฅผ ์ฐ๋ ๊ธฐ๋ฅ์๋ง ํ์ํ๊ณ (Bedrock, AWS S3 ์์ฒด), ์ญํ ์ด๋ ํ์ค
AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY์์ผ๋ก ์จ๋ค. MinIO ๊ฐ์ S3 ํธํ ์คํ ์ด์ ์๊ฒฉ ์ฆ๋ช ์ ๊ทธ๊ฒ๊ณผ ๋ค๋ฅธS3_ACCESS_KEY_ID/S3_SECRET_ACCESS_KEY์์ด๋ค. ํ ํ๋ก์ธ์ค๊ฐ ๋ ๋ค ์ธ ์ ์๋ค. ํค๋ฅผ ์ด๋ฏธ์ง์ ๊ตฝ์ง ๋ง๋ผ. AES_ENCRYPTION_KEY๋ฅผ ํ์ ํ๋ฉด ์ ์ฅ๋ ์ํฌ๋ฆฟ๋ง์ด ์๋๋ผ proxied ์ค๋ธ์ ํธ ์ฃผ์๋ ์ ๋ถ ๋ฌดํจ๊ฐ ๋๋ค. ์๋ช ํค๊ฐ ๊ฑฐ๊ธฐ์ ํ์๋๋ค. ๋ฐ๊ธ๋ ๋งํฌ๊ฐ ๋ฌดํจํ๋๊ณ ๊ธฐ์กด credentialยทSDK SessionยทWorkspace checkpoint๋ ์ ํค๋ก๋ ๋ณตํธํํ ์ ์๋ค. ํค ๊ต์ฒด๋ง์ผ๋ก ๊ธฐ์กด ์ํธ๋ฌธ์ ๋ค์ ์ํธํํ๋ ์๋ ์ด๊ด์ ์ ๊ณตํ์ง ์๋๋ค.