MINARA
Minara 사용하기클라이언트 및 인터페이스메시징 플랫폼

Microsoft Teams

JWT + JWKS 검증 기반 Bot Framework 메시징. 멀티 테넌트 및 싱글 테넌트 지원.

🟡 아웃바운드 준비 완료, 인바운드 JWT 검증 적용. Bot Connector REST API를 통해 Teams와 통신합니다. 인바운드 활동은 Microsoft가 서명하며 동적으로 탐색된 JWKS로 검증되므로, 위조된 POST 요청은 401을 반환합니다.

제공 기능

  • 아웃바운드 텍스트 전송. Bot Framework Conversation API를 사용합니다. POST {serviceUrl}/v3/conversations/{conversationId}/activities 형식으로 {type:"message", text}를 전송합니다. 스레드(replyToActivityId)도 지원합니다.
  • 인바운드 webhook 엔드포인트: /webhooks/teams. Microsoft는 모든 활동에 JWT로 서명하며, Minara는 OpenID 메타데이터 엔드포인트(https://login.botframework.com/v1/.well-known/openidconfiguration)를 통해 JWKS를 탐색하고 두 항목 모두 24시간 동안 캐싱합니다.
  • 아웃바운드용 OAuth 클라이언트 자격증명 token 캐시. TTL 1시간, 5분 사전 갱신.
  • 현재 텍스트만 지원합니다. Adaptive Cards, Office 365 커넥터, 파일 업로드는 향후 추가될 예정입니다.
  • 텍스트 한도: 28,000자.

설정

1. 봇 등록 (Azure)

  1. Azure 포털에서 Azure Bot 리소스를 생성합니다. 단일 리전 기준이며 개발 환경에는 "F0 무료" 요금제로 충분합니다.
  2. 프로비저닝 완료 후 "Configuration" 블레이드에서 Microsoft App ID (GUID)를 확인하고 Client Secret (App Password)을 생성합니다. 두 값 모두 저장해 둡니다.
  3. 테넌트 범위를 결정합니다. "Multi Tenant"는 tenant id에 common을 사용하고, "Single Tenant"는 Azure AD 테넌트 GUID를 사용합니다.

2. 봇을 Teams에 연결

  1. 동일한 Azure Bot 블레이드에서 "Channels" → "Microsoft Teams"로 이동합니다. 서비스 약관에 동의하고 활성화합니다.
  2. Teams 앱 매니페스트를 생성하거나 Developer Portal for Teams를 사용하여 봇의 Microsoft App ID를 지정합니다. 테스트용으로 테넌트에 사이드로드합니다.
  3. 봇을 팀에 추가하거나 테스트 사용자가 DM을 보냅니다. 첫 번째 인바운드 활동에 Minara가 필요로 하는 conversation.idserviceUrl이 포함됩니다.

3. 봇 메시징 엔드포인트 설정

Azure Bot 블레이드에서 "Configuration" → "Messaging endpoint"로 이동하여 URL을 https://<your-host>/webhooks/teams로 설정합니다.

4. Minara 설정

minara auth messaging add
# 목록에서 `teams`를 선택하고 App ID, App Password, tenant id
# (또는 "common"), 기본 conversation id와 service URL을 입력합니다.

또는 환경 변수로 설정합니다.

TEAMS_BOT_APP_ID=<봇 Microsoft App ID GUID>
TEAMS_BOT_APP_PASSWORD=<봇 Microsoft App Password>
TEAMS_BOT_TENANT_ID=common
TEAMS_DEFAULT_CONVERSATION_ID=<수신된 인바운드 활동에서 가져온 conversation id>
TEAMS_DEFAULT_SERVICE_URL=https://smba.trafficmanager.net/teams/

위의 TEAMS_DEFAULT_SERVICE_URL 값은 멀티 테넌트 프로덕션 라우트입니다. 싱글 테넌트 또는 소버린 클라우드 배포의 경우, 테넌트에서 수신된 첫 번째 인바운드 활동에 포함된 serviceUrl로 재정의합니다.

5. 테스트

minara auth messaging test teams

인바운드 webhook

Bot Framework는 Authorization: Bearer ... 헤더의 JWT로 인바운드 활동에 서명합니다. Minara는 다음 항목을 검증합니다.

클레임예상 값
iss (발급자)https://api.botframework.com
aud (대상)멀티 테넌트: TEAMS_BOT_APP_ID / 싱글 테넌트: TEAMS_BOT_TENANT_ID GUID
서명RS256, https://login.botframework.com/v1/.well-known/openidconfiguration에서 탐색된 키
클럭 스큐±5분

JWKS와 OpenID 메타데이터는 24시간 동안 캐싱됩니다. Microsoft는 주기적으로 키를 교체합니다. kid 불일치가 발생하면 캐시를 무효화하고 한 번 재조회합니다.

수신 가능한 활동 타입: message. 그 외 타입(conversationUpdate, typing, installationUpdate)은 무시합니다.

제한 사항 및 주의점

  • serviceUrl은 대화별로 다릅니다. Bot Framework 문서에 따르면 각 인바운드 활동에서 serviceUrl을 캡처하여 대화별로 저장해야 합니다. Minara는 인바운드 serviceUrl이 있으면 이를 우선 사용하며, 환경 변수 기본값은 콜드 푸시 시 부트스트랩 폴백으로만 사용됩니다.
  • 멀티 테넌트 대상. TEAMS_BOT_TENANT_ID=common으로 설정하면 봇은 모든 테넌트의 활동을 수락합니다. 이 경우 JWT audience는 TEAMS_BOT_APP_ID와 같습니다. 싱글 테넌트로 설정할 경우 테넌트 GUID를 입력하면 audience도 해당 GUID가 됩니다.
  • Adaptive Cards는 아직 지원하지 않습니다. 봇은 일반 텍스트만 사용합니다.
  • JWKS 탐색은 첫 인바운드 POST 시 네트워크 접근이 필요합니다. login.botframework.com이 방화벽으로 차단된 경우 검증은 실패하며 401을 반환합니다.

문제 해결

"인바운드 요청마다 401 반환"

  • 호스트와 Microsoft 간 클럭 스큐가 5분을 초과합니다.
  • TEAMS_BOT_APP_ID 값이 Azure의 봇 Microsoft App ID와 일치하지 않습니다. Azure Bot에는 Application ID와 리소스 ID 두 가지가 있으며, Application ID를 사용해야 합니다. 붙여넣기 실수가 자주 발생하는 항목입니다.
  • 싱글 테넌트의 경우: TEAMS_BOT_TENANT_ID가 인바운드 JWT의 audience와 일치하지 않습니다.

"아웃바운드 401 (token 엔드포인트)"

  • TEAMS_BOT_APP_PASSWORD가 교체되었거나 취소되었습니다. Azure Bot 설정 블레이드에서 새 Client Secret을 생성합니다.

"대화를 찾을 수 없음 (아웃바운드 404)"

  • 기본 TEAMS_DEFAULT_CONVERSATION_ID가 오래된 값입니다. 사용자가 봇을 제거했거나 채널이 삭제된 경우 발생합니다. 최근 인바운드 활동에서 새 conversation id를 캡처합니다.

참조

목차