원격 비즈니스 시스템을 플랫폼에 연결할 때 문제가 되는 것은 대개 API 호출 자체가 아니라 "누가 어떤 자격 증명을 들고 있고, 언제 만료되며, 멤버가 해지된 뒤 언제 반영되는가"입니다. 이 세 가지가 오래 안정적으로 동작할지를 결정합니다. 아래는 이 경로에서 우리가 지키는 방식과 경계입니다.
자격 증명은 두 단계, 장기 자격 증명은 서버를 벗어나지 않습니다
플랫폼에는 두 종류의 identity가 있습니다. 모듈 서비스 identity는 장기 자격 증명으로 비즈니스 시스템의 서버에만 보관하며, Launch Grant 교환(POST /integration/v1/sso/launch-grants/exchange)과 인스턴스 서비스 토큰 발급 요청(POST /integration/v1/service-tokens)에 사용합니다. 인스턴스 서비스 토큰은 최대 5분, Audience 고정, 이번 요청에 맞게 Scope가 좁혀진 단기 자격 증명이며 no-store로 반환됩니다.
따라서 브라우저는 모듈 자격 증명을 받지 않습니다. 프런트엔드는 전달받은 Launch Code를 자기 백엔드에 넘길 뿐이고, 교환은 모두 서버에서 이뤄집니다. 단기 토큰에 대해 SDK는 "인스턴스 + 이번 요청의 Scope 집합" 단위로 최대 300초 캐시하고 Refresh가 없습니다. 남은 수명이 안전 구간 아래로 내려가면 다시 발급받고, 동시 호출은 한 번만 교환하며, 인스턴스를 넘어 재사용하지 않습니다.
Launch는 일회성 교환이고, 남는 것은 자체 세션입니다
사용자가 플랫폼에서 비즈니스 시스템으로 들어올 때 들고 오는 것은 Launch Code이며 장기 자격 증명이 아닙니다. 백엔드는 모듈 서비스 identity로 Grant를 교환하고 소비한 뒤, 비즈니스 시스템 자체의 로컬 세션을 만듭니다. 세션에는 파생된 identity만 담고 플랫폼 토큰, Launch Code, Client Secret, 전체 Claims는 담지 않습니다.
교환과 세션 검증 모두 서명 검증을 거칩니다. 플랫폼 런타임 JWKS로 서명 알고리즘, Issuer, Audience, 유효 기간, token_use, Account와 AppInstance, Scope를 확인하고, 공개키 출처는 리디렉션을 금지하고 응답 크기를 제한합니다. 헷갈리기 쉬운 지점은 로그인 안내 페이지의 "연결 정상"이 백엔드가 공개키를 해석할 수 있다는 것만 뜻한다는 사실입니다. 사용자가 로그인했다는 것도, Launch 경로가 동작한다는 것도 아닙니다. 세 가지는 따로 다뤄야 합니다.
멤버가 해지되면 로컬 세션을 수렴시켜야 합니다
플랫폼 세션이 유효하다고 해서 로컬 세션을 무기한 쓸 수 있는 것은 아닙니다. 장기 세션 동안 멤버 제거, 역할 변경, 인스턴스 정지가 제한된 시간 안에 비즈니스 시스템에 도달해야 합니다. 방식은 인스턴스 서비스 identity로 일괄 검증하는 것(POST /integration/v1/session-checks)입니다. active가 참이려면 인스턴스, 인스턴스 멤버십, Account, Account 멤버십이 모두 유효해야 합니다. 비멤버와 존재하지 않는 사용자는 모두 active=false를 반환하므로 멤버 존재 여부가 새지 않습니다. 비즈니스 시스템은 스스로 선언한 검증 창으로 수렴시키며, 실무에서는 쓰기 창을 읽기보다 짧게 잡을 수 있습니다.
Scope가 부족하면 로컬에서 실패시킵니다
런타임 요청은 모두 Scope를 가집니다. SDK가 쓸 수 있는 자격 증명을 돌려주는 경우는 플랫폼이 실제로 부여한 Scope가 이번 요청을 덮을 때뿐이며, 그렇지 않으면 로컬에서 실패하고 비즈니스 요청을 보내지 않습니다. 이 규칙의 의미는 "플랫폼이 허용하지 않았다"와 "플랫폼 호출이 실패했다"를 분리하는 데 있습니다. 전자는 설정 문제이므로 즉시 보여야 하며, 알아보기 어려운 업스트림 오류로 바뀌어서는 안 됩니다.
멱등성과 재시도는 호출자의 몫입니다
SDK는 어떤 요청도 자동으로 재시도하지 않습니다. 쓰기 작업은 호출자가 안정적인 멱등 키를 제공해야 하며, 실패한 요청을 다시 보내지 않습니다. "결과 미상"과 "실패"는 다른 상태이고, 다시 보낼지, 조회할지, 사용자에게 알릴지는 비즈니스 시스템만 알 수 있습니다. 오류는 플랫폼의 Problem Details가 안정적인 분류(미인증, 권한 없음, 충돌, 요청 제한, 서버 오류 등)와 재시도 가능 표시로 매핑되며, 자격 증명과 응답 본문은 로그나 오류 직렬화에 들어가지 않습니다.
두 개의 산출물, 두 개의 획득 경로
두 SDK는 획득 방식이 다르므로 어느 쪽인지 먼저 확인하십시오. TypeScript / Node 쪽은 공개 npm의 @td-runlume/platform-integration-sdk이며 Apache-2.0이고 서버 측에서 사용합니다. Java 쪽 좌표는 app.runlume.platform:platform-integration-sdk-java로, 플랫폼의 Nexus 저장소에서 제공되며 Maven Central에는 없습니다. 플랫폼이 부여한 자격 증명과 라이선스 범위에서만 사용할 수 있고 산출물을 재배포해서는 안 됩니다. Java 쪽은 보통 Spring Boot Starter와 함께 쓰며, SDK 컴포넌트와 로컬 세션 유효성 파이프라인은 Starter가 조립하고 비즈니스 시스템은 세션 경계와 워크스페이스 조회 두 가지 확장점만 제공합니다.
엔드포인트 경로, Scope 이름, 사용 가능한 기능은 계약 시점에 합의한 계약과 플랫폼 문서를 따릅니다. 이 글은 서버가 지켜야 할 경계만 다룹니다. 기능 범위는 플랫폼 기능에서 확인할 수 있습니다.