ナレッジベース

/

セキュリティ

更新情報

Bot トークンはどう守られているか

BotShade に預けていただく Bot トークンを、私たちがどう保管し、どう守っているかを率直に説明します。

B
BotShade チーム

|

8 分で読めます

|

最終更新: 2026年6月15日

BotShade をお使いいただくとき、たぶん一番気になるのは Bot トークン だと思います。これが流出すれば、Bot は乗っ取られ、サーバーは荒らされかねません。だからこそ、私たちがどこに、どう保管し、どこまで守っているか、そして 何をしないと決めているか を率直に書いておきます。

セキュリティの話は、結論だけ並べると無味乾燥になりがちです。この記事ではなるべく「なぜそうしているか」も含めて、設計の意図ごと共有します。

この記事で扱うこと:

そもそも Bot トークンとは何か

Bot トークンは、Discord の開発者ポータルで Bot を作ったときに発行される、長い文字列です。Discord に対して「自分はこの Bot だ」と名乗るための、いわば Bot 専用のパスワード にあたります。

トークンを持っている誰かは、Bot として何でもできます。メッセージの送信、ロールの付与、メンバーの BAN、サーバーの設定変更 — Bot に与えた権限の範囲ですべて可能です。これが、トークンが「最も慎重に扱うべき情報」と言われる理由です。

BotShade のような Bot プラットフォームを使うということは、この Bot トークンをサービス側に預ける、ということです。何が起きていて、どう守られているかを知っておきたい、と思うのは当然のことだと思います。

預けるときの流れ

ユーザーがダッシュボードに Bot トークンを貼り付けて「保存」を押した瞬間、内部では次の順番で処理が走ります。

  1. TLS で暗号化された経路 で、トークンがブラウザから BotShade のサーバーに送られる
  2. サーバー側で受け取ったトークンは Discord の API に1度だけ照会 し、有効なトークンか、どの Bot に紐づくかを確認する
  3. 確認が取れたら、トークンは その場で AES-256-GCM で暗号化 され、データベースに保存される
  4. 復号に必要な鍵は 別の場所(クラウドのシークレットマネージャ) にあり、データベースとは隔離されている
  5. メモリ上に残った平文のトークンは、処理が終わった直後に破棄される

ブラウザの入力欄に並ぶ「●●●●●●」は、保存後はもう復元できません。ダッシュボードに表示されるのは「最後の4文字」など、本人が「自分の Bot だ」と認識するための最小限の情報だけです。

保管時はどう守るか

データベースに保存されている Bot トークンは、すべて AES-256-GCM で暗号化されています。AES-256-GCM は、暗号化と同時に 改ざん検知 も組み込まれている認証付き暗号で、「読めなくする」と「いじられていないかを確かめる」の両方を1つの仕組みで担います。

復号に必要な鍵は、データベースとは別の場所にある クラウドのシークレットマネージャ で管理しています。鍵自体も、特定の権限を持つ運用基盤からしか取り出せないように設定しています。

つまり、もしデータベースのダンプが手元にあっても、それだけではトークンを復号できません。鍵側のアクセス権限と、暗号化された値の両方が同時に手に入って、初めて平文のトークンが復元できる構造になっています。「片方が破られても、もう片方で食い止める」 という、典型的な多層防御の形です。

技術詳細:AES-256-GCM の認証タグと nonce

AES-256-GCM の “GCM” は Galois/Counter Mode の略で、暗号化と同時に 認証タグ (authentication tag) と呼ばれる短い MAC を生成します。復号時にはこのタグが照合され、暗号文または関連データに 1 ビットでも改ざんがあれば復号自体が失敗します。「読めなくする」と「いじられていないかを確かめる」を、1 つの仕組みで同時にこなしているのはこのためです。

GCM では、各レコードごとに重複しない nonce(一度きりの値) を使う必要があります。同じ鍵で同じ nonce を再利用すると、暗号としての安全性が大きく崩れる性質があるため、各レコードに固有の nonce を組み込み、衝突しないよう運用しています。

加えて、関連付けたい情報を AAD(Additional Authenticated Data) として認証対象に含めることで、「この暗号文は、本当にこの bot のものか」のような文脈の取り違えも、復号段階で検出できる構造にしています。

Bot 同士が混ざらない仕組み

BotShade では、たくさんのユーザーの Bot を同じデータベースで扱います。ここで肝心なのは、A さんの Bot が、B さんの Bot のトークンに到達できないこと です。

これを、PostgreSQL の Row Level Security (RLS) によってデータベース層で保証しています。RLS は「どの行を見せるか」をデータベースのポリシーとして書き込み、クエリのたびに自動で適用するしくみです。アプリケーション側のコードが何か間違えたとしても、データベース自身が「あなたの Bot のデータしか返しません」と判定して弾く設計です。

なぜアプリ層ではなく、わざわざデータベース層で分離しているかというと、コードのバグやリリースの事故で「うっかり別の Bot のデータが見えてしまう」 という事故の余地を構造的に潰したいからです。アプリのコードは日々更新されますが、データベース側のポリシーは滅多に変わりません。守りの土台を、変わりにくい場所に置く方が安全です。

さらに複合プライマリーキーを併用し、「Bot をまたいだ参照」というクエリの形そのものを成立させないようにしています。

技術詳細:Row Level Security という仕組み

PostgreSQL の Row Level Security は、テーブルごとに「どの行をどの主体に見せるか」を、データベース側のポリシーとして宣言する機能です。リクエストごとにアプリケーションは「現在の bot は誰か」を安全な経路でデータベースへ伝え、ポリシーがクエリに自動で組み込まれます。

仮にアプリ側のコードが全件取得のようなクエリを投げたつもりでも、データベース自身が裏で「現在の bot のものだけを返す」フィルタを足します。これがアプリ層ではなく データベース層で分離する ことの効果です。

加えて、アプリケーションが DB に接続するときに使うロール(DB ユーザー)には、ポリシーをすり抜ける権限を持たせていません。「うっかり無効化できない」状態を、システムのデフォルトとして固定しています。

通信経路で守ること

トークンが流れる経路は、ざっくり3つです。

  • ブラウザ ↔ BotShade のダッシュボード
  • BotShade ↔ Discord
  • 内部のサービス間通信

これらはすべて TLS で暗号化しています。受け口は Cloudflare が前段に立ち、SSL モードは Full (Strict) で運用しています。「Full (Strict)」というのは、ユーザー側から見えない裏側でもオリジンサーバとの通信を有効な証明書で守る、という意味の設定です。HTTP に降格して情報が流出する余地を、設計の段階で潰しています。

エッジでは WAF と DDoS Protection を有効化し、明らかに不審なリクエストはアプリケーションに届く前に弾いています。さらに重要な API リクエストには HMAC 署名 をかけ、送信元が正規のクライアントか、途中で改ざんされていないかを、サーバー側で毎回検証してから処理しています。

通信途中での盗聴・なりすまし・改ざん — これらに対しては、別々の層で別々の対策が同時にかかっています。

技術詳細:HMAC 署名とリプレイ攻撃の防ぎ方

重要な API リクエストには、共有鍵を使った HMAC-SHA256 の署名を付与しています。クライアントは、そのリクエストの主要な要素(メソッド・パス・本文・タイムスタンプなど)から署名を生成し、サーバー側は同じ手順で再計算します。一致しなければ、そのリクエストは即時に拒否されます。

署名鍵は ローテーション可能 にしており、新旧の鍵を一定期間並走させて検証できる構成です。鍵の漏洩が疑われたときに、サービスを止めずに切り替えられるようにするためです。

リプレイ攻撃 — 過去の正規リクエストをそのまま再送する攻撃 — に対しては、署名対象に タイムスタンプ を含め、サーバー側で「一定の時間より古いリクエストは受け付けない」という閾値で対処しています。さらに必要に応じて、短時間内の一意な nonce を組み合わせ、同じリクエストの 2 度目を弾けるようにしています。

誰がトークンに触れられるか

率直に書くと、私たちは 復号後のトークンには基本的にアクセスしません。そもそも復号する手段を日常の運用ラインに持たせていないので、ダッシュボードの開発でもサポート対応でも、平文のトークンを見る場面はありません。見たくもないし、見るつもりもありません。

ただし、暗号化された状態の文字列(ciphertext)そのもの は、ストレージの整合性確認や改ざん検知のために運用側で扱う可能性があります。これは「同じ値か」「壊れていないか」を、復号せずに確かめるためのものです。中身を覗くものではありません。

運用上行われた管理操作は、監査ログ に残しています。誰が、いつ、何をしたかが記録され、現在は 7 日間 保持しています。

万一に備えて

完璧な防御はありません。だから、起きてしまったときにどうするかも同じくらい大事だと考えています。

  • 不審なアクセスや、通常と異なるパターンのログイン試行は検知の対象です
  • トークンが漏れた可能性が出た場合は、対象のユーザーに通知します
  • ダッシュボードからトークンは いつでも再生成 できます。古いトークンは即時に失効します
  • セキュリティに関する報告は help@botshade.com で受け付けています。発見した方には誠実に対応します(詳しくは 責任ある開示 のセクション)

トークンの再生成は、利用中のユーザーには「いざというときの非常口」として案内しています。何かおかしいと感じたら、まず再生成して古いトークンを失効させる — それだけでも被害の広がりを大幅に止められます。

私たちが意図的にやらないこと

設計の意図は、やっていることだけでなく やらないと決めていること にも表れます。私たちが BotShade で「やらない」と決めているのは、たとえば次のようなことです。

  • トークンをログに出力しない:エラーログやデバッグログ、メトリクス、トレースを含め、トークン自体やその一部を残さない設計にしています
  • サポートチケットやチャットでトークンを尋ねない:問い合わせ対応のために運営側からトークンの提示をお願いすることはありません。もし「トークンを送ってください」というメッセージが届いたら、それは私たちではない誰かです
  • ダッシュボード以外でトークンを表示しない:メール、Discord メッセージ、外部サービス連携のいずれでも、平文のトークンを露出させません
  • 復号鍵を運用基盤に常駐させない:必要なときにだけ、限定された場所から鍵にアクセスできる設計にし、「常時手元にある」状態を避けています

こうした「やらない」リストは、書類上のポリシーではなく、コードと運用の両方に落とし込まれています。

できないこと、お願いしたいこと

私たちが守れる範囲には正直に線があります。次のことは、こちらでは守りきれません。

  • ユーザー自身がトークンを誤って公開リポジトリにコミットしてしまったとき
  • ダッシュボードのログインアカウントが第三者に乗っ取られたとき
  • ユーザーのデバイス自体がマルウェアに感染しているとき

後ろの2つを薄めるための一番効くお願いは、ダッシュボードの入り口を強くしていただくこと です。BotShade のダッシュボードはパスワードを持たない設計で、Discord などの外部アカウントでサインインしていただくか、パスキー (Passkey) でサインインしていただく形になっています。

そのため、お願いしたいのは次のことです。

  • サインインに使われている 連携先のアカウント(Discord・Google など)に二要素認証 (2FA) を有効化 しておくこと。BotShade 自身にはパスワードがないため、入り口の強さは、連携先のアカウントの強さがそのまま反映されます
  • 可能であれば パスキーを登録 していただくこと。パスキーは端末に紐づき、フィッシングに強い認証方式です

そして、最初のリスク(トークンをうっかり公開リポジトリにコミットしてしまった、など)に気づいたときは、Discord の開発者ポータルの「Reset Token」からトークンをすぐに作り直して ください。古いトークンはその場で失効します。新しいトークンを BotShade のダッシュボードに登録し直せば、Bot の動作はそのまま継続します。

セキュリティはこちらだけでも、お使いの方だけでも完成しません。両方そろって、ようやく「最小限の被害」に収まる設計になっています。私たちは私たちの分を、誠実に守り続けます。

← ナレッジベースに戻る