BazaarLinkBazaarLink
ログイン
ドキュメントAPIリファレンスSDKリファレンスエージェント利用AIスキル
目次

OAuth PKCE

OAuth PKCE

OAuth 2.0 PKCE(Proof Key for Code Exchange)により、パブリッククライアントアプリ(ブラウザSPA、モバイルアプリ)がクライアントサイドに長期的なサーバーシークレットを保存せずに、個々のユーザーの代わりにAPI呼び出しを行えます。

OAuth PKCEを使用する場面

  • ユーザーごとの課金が必要なブラウザSPAまたはモバイルアプリを構築する場合
  • マルチテナントSaaS — 各エンドユーザーが自分のAPI使用料を支払う
  • クライアントサイドに共有シークレットを保存できない場合(パブリッククライアント)
  • 単一の共有APIキーではなく、ユーザーごとに独立した取り消し可能なキー(自動では失効しません)が必要な場合

ユーザーに表示される内容

自社のサインイン画面で、次の手順を説明してください:

  1. アプリ内で「BazaarLink でサインイン」(またはお好みのボタン名)を選びます。
  2. ブラウザで BazaarLink の認可ページが開きます。まだサインインしていない場合は、先にサインインすると自動的にこのページへ戻ります。
  3. ページにはアプリのアドレスと、許可した場合に起こることが表示されます:アプリ用の新しい API キーが作成され、利用料金は BazaarLink の残高に請求され、いつでもキーを取り消せます。キー名と月間利用上限も設定できます(どちらも任意)。
  4. 「許可」をクリックするとアプリに戻ります。「拒否」をクリックした場合、キーは作成されず、アプリにも通知されず、「アクセスを拒否しました」ページが表示されます。
  5. 後でアクセスを取り消すには、「API キー」ページ(https://bazaarlink.ai/keys)を開き、アプリ名が付いたキーを無効化または削除します。

仕組み

ステップ1 — 認証の開始 — ランダムなcode_verifier(長いランダム文字列)とそのSHA-256ハッシュをcode_challengeとして生成し、ユーザーをBazaarLink認証ページにリダイレクト。

https://bazaarlink.ai/auth?callback_url=https://yourapp.com/callback&code_challenge=CODE_CHALLENGE&code_challenge_method=S256

認可 URL のパラメータ

  • callback_url(必須)— ユーザーが許可した後に戻る URL。ルールは下記を参照。
  • code_challenge(必須)— code_verifier の SHA-256 を base64url エンコードした値(43 文字、パディングなし)。
  • code_challenge_method(必須)— S256 である必要があります。
  • state(任意)— 独自の不透明な CSRF 値。印字可能な ASCII 文字で 1〜256 文字。BazaarLink は code の直後に &state=… としてそのまま返します。形式が不正な state の場合、承認ページには「無効な承認リクエスト」と表示されます。
  • key_label(任意)— 最大 100 文字。同意ページのキー名にあらかじめ入力されます(ユーザーは変更できます)。長すぎる、または空白のラベルは無視されます。
  • Headless tools (CLI / desktop, no callback_url) — omit callback_url. After the user allows, the page shows a one-time code (valid 5 minutes, single use) for them to enter into your tool; exchange it exactly like a redirected code. The page cannot show which app is asking, so tell users to enter the code only in a tool they started themselves.

非対応

  • workspace_id と required_workspace_id — 非対応。キーは常にユーザー自身のアカウントに属します。
  • code_challenge_method=plain — 非対応(S256 のみ)。

callback_url のルール

  • https:// である必要があります。http:// は localhost、127.0.0.1、[::1](任意のポート)のみ許可され、その場合は同意ページにローカル開発の警告が表示されます。
  • フラグメント(#)、URL 内のユーザー名・パスワードは使用不可。最大 2048 文字。
  • 同意ページにはあなたの callback ホスト名が表示され、ユーザーはどのアプリが要求しているか確認できます。
  • ユーザーが許可すると、ブラウザは code=… を付けた callback_url に移動します(state を送った場合は state=… も付き、既存のクエリ文字列は保持されます)。code の有効期間は 10 分で、1 回だけ使えます。

ステップ2 — コードをAPIキーと交換 — ユーザーがリクエストを承認すると、BazaarLinkはワンタイムの code を付けて callback_url にリダイレクトします。code の有効期間は10分で、1回だけ使用できます。code_verifier が誤っていると code は無効になります。code、code_verifier、code_challenge_method(3つとも必須)を POST して、そのユーザーのAPIキーを受け取ります。

curl https://bazaarlink.ai/api/v1/auth/keys \
-H "Content-Type: application/json" \
-d '{
  "code": "<CODE_FROM_CALLBACK_URL>",
  "code_verifier": "<CODE_VERIFIER>",
  "code_challenge_method": "S256"
}'

# Response
# { "key": "sk-bl-...", "user_id": "..." }

ステップ3 — ユーザースコープキーの使用 — 返されるキーは、承認したユーザーに属する通常のBazaarLink APIキーです。利用料金はあなたではなく、そのユーザーの残高に請求されます。

curl https://bazaarlink.ai/api/v1/chat/completions \
-H "Authorization: Bearer sk-bl-..." \
-H "Content-Type: application/json" \
-d '{"model": "google/gemini-3.5-flash", "messages": [{"role": "user", "content": "Hello"}]}'

JavaScript の例(ブラウザ)

// 1) Create a verifier + S256 challenge, then send the user to BazaarLink
const b64url = (buf) => btoa(String.fromCharCode(...new Uint8Array(buf)))
.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
const verifier = b64url(crypto.getRandomValues(new Uint8Array(32)));
const challenge = b64url(await crypto.subtle.digest("SHA-256", new TextEncoder().encode(verifier)));
sessionStorage.setItem("bl_verifier", verifier);
// "state" is optional: BazaarLink hands it back unchanged next to the code.
const state = b64url(crypto.getRandomValues(new Uint8Array(16)));
sessionStorage.setItem("bl_state", state);
location.href =
"https://bazaarlink.ai/auth?callback_url=" + encodeURIComponent(location.origin + "/callback") +
"&code_challenge=" + challenge + "&code_challenge_method=S256&state=" + state;

// 2) On /callback: check your own state, then exchange the one-time code for a user key
const params = new URLSearchParams(location.search);
if (params.get("state") !== sessionStorage.getItem("bl_state")) throw new Error("state mismatch");
const res = await fetch("https://bazaarlink.ai/api/v1/auth/keys", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
  code: params.get("code"),
  code_verifier: sessionStorage.getItem("bl_verifier"),
  code_challenge_method: "S256",
}),
});
if (!res.ok) throw new Error((await res.json()).error?.message ?? "exchange failed"); // 403 invalid_code: ask the user to authorize again
const { key } = await res.json(); // use as: Authorization: Bearer <key>
セキュリティ:S256のみ
code_challenge_methodをS256(SHA-256ハッシュ)に設定してください。サポートされるのはS256のみです。plainまたはcode_challenge_method未指定のリクエストはHTTP 400で拒否されます。
注意
ユーザーが拒否した場合、BazaarLink は callback_url へリダイレクトせず、アプリにも通知しません。「アクセスを拒否しました」ページを表示するだけなので、/auth がオープンリダイレクトになることはありません。未承認の状態はアプリ側で処理してください(例:タイムアウトや再試行ボタン)。

/auth ページと POST /api/v1/auth/keys は https://bazaarlink.ai から提供されます(api.bazaarlink.ai ではありません)。取得したキーは、ベース URL が https://bazaarlink.ai/api/v1 でも https://api.bazaarlink.ai/v1 でも使えます。

ユーザーが承認時に利用上限を設定した場合、それは月間上限で、アカウントの月次サイクルに合わせてリセットされます。

エラー

エラーは OpenAI 形式 {"error":{"message","type","code"}} で返されます。POST /api/v1/auth/keys は次を返すことがあります:

  • 400 invalid_code_challenge_method — code_challenge_method が未指定、plain、または S256 以外です。
  • 400 — JSON 本文が無効、または code / code_verifier がありません。
  • 403 invalid_code — code が不明・期限切れ・使用済み、code_verifier が誤り、またはアカウントがすでに許可されていません。呼び出し側が区別できないよう、これらはすべて意図的に同じメッセージを返します。code_verifier が誤っていると code も無効になるため、ユーザーに再度承認してもらってください。
  • 429 rate_limited — 同一 IP から 10 分間に 30 回を超える交換試行がありました(Retry-After ヘッダーを参照)。
  • 429 key_total_cap — アカウントがすでに上限の 200 個の API キーを保有しています。
  • 405 — POST のみ受け付けます。

サーバーから認可コードを作成する(管理キー)

個人の管理キー(Management Key)の所有者は、ブラウザの認可ページを経由せず、POST /api/v1/auth/keys/code で直接認可コードを作成できます(OpenRouter 互換)。コードは管理キーの所有者に紐づくため、交換して得られるのはその所有者のアカウント上の標準キーで、上限額・期間・有効期限・名前はここで指定した内容になります。自社ツールがすでに管理キーを持っていて、アプリに制限付きキーを渡したい場合に使います。交換手順(POST /api/v1/auth/keys)は上記と同じです。

  • callback_url(必須)と code_challenge + code_challenge_method=S256(必須)— 認可 URL と同じルールです。
  • key_label(任意)— 最大100文字、キーの名前。デフォルトは「App: <コールバックのホスト名>」。
  • limit(任意)— USD の利用上限、0 以上。0 または未指定は上限なしです。
  • usage_limit_type(任意)— daily、weekly、monthly:上限がリセットされる頻度。limit と併用した場合のみ有効で、デフォルトは monthly です。
  • expires_at(任意)— キーの有効期限:未来の ISO 8601 UTC 時刻(秒まで必須)、例:2026-12-31T23:59:59Z。分単位までの値は拒否されます。未指定の場合、キーは失効させるまで有効なままです。
  • workspace_id — 未対応(400)。spawn_agent と spawn_cloud は受け付けられますが無視されます。
curl https://bazaarlink.ai/api/v1/auth/keys/code \
-H "Authorization: Bearer sk-bl-YOUR_MGMT_KEY" \
-H "Content-Type: application/json" \
-d '{
  "callback_url": "https://yourapp.com/callback",
  "code_challenge": "<CODE_CHALLENGE>",
  "code_challenge_method": "S256",
  "key_label": "My app",
  "limit": 10,
  "usage_limit_type": "monthly",
  "expires_at": "2026-12-31T23:59:59Z"
}'

# Response
# { "data": { "id": "<ONE_TIME_CODE>", "app_id": 123456789, "created_at": "2026-10-22T12:00:00.000Z" } }
# Then POST { "code": "<ONE_TIME_CODE>", "code_verifier": "<CODE_VERIFIER>", "code_challenge_method": "S256" } to /api/v1/auth/keys

レスポンス:{ "data": { "id", "app_id", "created_at" } }。id が交換に使う使い捨ての認可コードです(10分間有効、1回のみ)。BazaarLink にはアプリ登録の仕組みがないため、app_id はコールバックアドレスから導出される固定の整数で、同じアドレスなら常に同じ app_id になります。

  • 401 unauthorized — Bearer キーがない、またはキーが存在しません。
  • 403 management_key_required — キーが個人の管理キーではありません(標準キーと組織の管理キーは拒否されます)。
  • 403 account_not_allowed — キーの所有者が停止または削除されています。
  • 400 — invalid_callback_url、invalid_code_challenge_method、invalid_code_challenge、invalid_expires_at、workspace_not_supported、またはボディの形式不正。
  • 429 rate_limited — 同一所有者で1時間に30件超、または同一 IP で1時間に120件超のコード作成(Retry-After を参照)。

受け取るキー

  • 標準的な BazaarLink API キー(sk-bl-…)。「API キー」ページで作成したキーと同じ種類で、自動では失効しません。
  • 利用料金はユーザーの BazaarLink 残高に請求されます。ユーザーが同意ページで利用上限を設定した場合、それは月間上限です。
  • どちらのベース URL でも使えます:https://bazaarlink.ai/api/v1 と https://api.bazaarlink.ai/v1。
  • アカウントのキー数上限(200 個)に含まれ、ユーザーの「API キー」一覧に表示されます。ユーザーはいつでも無効化または削除できます。
  • 停止中または削除済みのアカウントはアプリを承認できません。停止前に発行された code も、交換時に拒否されます(403 invalid_code)。

得られるもの

  • パブリッククライアントアプリケーション向けのAuthorization Code + PKCEフロー
  • ユーザーごとの課金:各ユーザーが自分の残高から自分の利用料金を支払う
  • ユーザーごとに別々のキーを発行。ユーザーの「API キー」ページに表示され、ユーザー自身で取り消せる
サポート
こんにちは。どのようなご用件でしょうか?
メッセージをお送りください。担当者より返信します。
OAuth PKCE | BazaarLink