> ## Documentation Index
> Fetch the complete documentation index at: https://docs.timothe.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# 署名付きログイン連携

> 署名付きトークンを使ってダッシュボードへのシームレスなログイン連携を実装する方法

Turnint AI のダッシュボードをマルチテナントシステムにホワイトラベルとして組み込むための仕組みです。エンドユーザーは Turnint AI のログイン画面を経由せず、シームレスにダッシュボードへアクセスできます。

## フロー概要

```mermaid theme={null}
sequenceDiagram
    participant Partner as あなたのシステム
    participant API as Turnint API
    participant Browser as ユーザーのブラウザ
    participant Dashboard as Turnint ダッシュボード

    Partner->>API: POST /partner/v1/auth/sessions<br/>(API キー認証)
    API-->>Partner: loginUrl + workspaceId

    Partner->>Browser: loginUrl へリダイレクト
    Browser->>Dashboard: /partner-login?code=ptn_ac_xxx

    Dashboard->>API: POST /partner-auth/v1/exchange<br/>{ code }
    API-->>Dashboard: Set-Cookie: ptn_session=xxx

    Dashboard->>Browser: ワークスペースへリダイレクト
    Note over Browser,Dashboard: ログイン完了
```

1. あなたのサーバーから Partner API キーを使ってセッション作成エンドポイントを呼び出します。
2. Turnint AI はワンタイム認証コード付きのログイン URL を返します。
3. ユーザーのブラウザをそのログイン URL にリダイレクトします。
4. ダッシュボードが認証コードを自動的に検証し、セッションを発行します。
5. ユーザーはログイン画面を経由せず、ダッシュボードにアクセスできます。

## 前提条件

* Partner API キー（`ptn_sk_xxxx`）が発行済みであること

## API リファレンス

### セッション作成

```
POST /partner/v1/auth/sessions
Authorization: Bearer ptn_sk_xxxxxxxx
Content-Type: application/json
```

#### リクエストボディ

| フィールド        | 型        | 必須  | 説明                                      |
| ------------ | -------- | --- | --------------------------------------- |
| `namespace`  | `string` | はい  | テナントを識別する一意の文字列（1〜100文字）                |
| `role`       | `string` | はい  | ユーザーのロール（`admin` または `member`）          |
| `ttlSeconds` | `number` | いいえ | セッションの有効期間（秒）。60〜86400。省略時はパートナーのデフォルト値 |

#### リクエスト例

```json theme={null}
{
  "namespace": "tenant-abc",
  "role": "admin",
  "ttlSeconds": 3600
}
```

#### レスポンス

```json theme={null}
{
  "loginUrl": "https://dashboard.turnint.ai/partner-login?code=ptn_ac_xxxxxxxx",
  "workspaceId": "ws_xxxxxxxx",
  "expiresAt": "2026-03-10T13:00:00.000Z"
}
```

| フィールド         | 型        | 説明                     |
| ------------- | -------- | ---------------------- |
| `loginUrl`    | `string` | ユーザーをリダイレクトさせるログイン URL |
| `workspaceId` | `string` | 作成または紐付けられたワークスペースの ID |
| `expiresAt`   | `string` | セッションの有効期限（ISO 8601）   |

### セッション無効化

指定した namespace のすべてのセッションを無効化します。

```
DELETE /partner/v1/auth/sessions
Authorization: Bearer ptn_sk_xxxxxxxx
Content-Type: application/json
```

#### リクエストボディ

| フィールド       | 型        | 必須 | 説明               |
| ----------- | -------- | -- | ---------------- |
| `namespace` | `string` | はい | 無効化対象の namespace |

#### レスポンス

```json theme={null}
{
  "revokedCount": 3
}
```

## 実装例

### Node.js / TypeScript

```typescript theme={null}
const response = await fetch("https://api.turnint.ai/partner/v1/auth/sessions", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${PARTNER_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    namespace: "tenant-abc",
    role: "admin",
  }),
});

const { loginUrl } = await response.json();

// ユーザーのブラウザをリダイレクト
res.redirect(loginUrl);
```

### cURL

```bash theme={null}
curl -X POST https://api.turnint.ai/partner/v1/auth/sessions \
  -H "Authorization: Bearer ptn_sk_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"namespace": "tenant-abc", "role": "member"}'
```

## namespace とワークスペース

`namespace` はパートナーのテナントと Turnint AI のワークスペースを紐付けるキーです。

* 同じ `namespace` で複数回セッションを作成しても、同一のワークスペースが使用されます。
* 新しい `namespace` を指定すると、自動的に新しいワークスペースが作成されます。

## セキュリティ

* **認証コードはワンタイム** — 1 回使用されると即座に無効化されます。
* **認証コードの有効期限は 5 分** — 発行後 5 分以内にリダイレクトを完了してください。
* **ロール制限** — パートナーに許可されたロールのみ指定可能です。許可されていないロールを指定すると `400 Bad Request` が返されます。

## エラーレスポンス

| ステータスコード | 説明                               |
| -------- | -------------------------------- |
| `400`    | リクエストが不正（バリデーションエラー、許可されていないロール） |
| `401`    | API キーが無効、またはパートナーが無効            |
| `500`    | サーバー内部エラー                        |
