# 認証情報はサーバーに置く：業務システムをプラットフォームに接続するランタイムモデル

モジュール認証情報、Launch Grant、短期のインスタンストークン、メンバー失効の収束、Scope の失敗時クローズ、冪等性の所在。リモートの業務システムを接続するとき、サーバー側が守る境界をまとめます。

> Runlume はプラットフォーム機能、独立業務アプリ、専門サービスを必要に応じて組み合わせて提供します。機能、上限、納品範囲は選択したプランや合意条件に従います。業務アプリは個別に選べ、横断連携は接続設定と許可境界を守ります。

元のページ: https://runlume.app/ja/blog/platform-integration-runtime-model

開発者ガイド · アプリ接続 / 認証情報とセッション / API 契約

公開：2026-09-19 · 著者：Runlume チーム

遠隔の業務システムをプラットフォームに接続するとき、つまずきやすいのは 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 だけで、プラットフォームの Token、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 側は public 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 名、利用できる機能は、契約時に合意した契約書とプラットフォームのドキュメントに従います。本記事はサーバー側が守る境界だけを扱います。機能の範囲は[プラットフォーム機能](/ja/platform#capability-identity)から確認できます。

## 関連ページ

- [プラットフォーム](https://runlume.app/ja/platform)
- [業務アプリ](https://runlume.app/ja/apps)
- [開発者](https://runlume.app/ja/developers)
- [Runlume について](https://runlume.app/ja/about)
