password.es の API が動きはじめた:使い方

公開日 著者 David Carrero

このブログは何か月も同じことを繰り返してきた。パスワードはブラウザから出すべきでは ない生成ツールcrypto.getRandomValues() から乱数を取り、それはあなたの端末の中で起きる。 チェッカーも、入力された文字をどこにも送らずに解析する。

そして今日、サーバー側でパスワードを生成する API を公開する。

矛盾は明らかで、ごまかすつもりはない。API のすべての応答が、まさにそのことを 告げる注意書きを載せている。しかしブラウザが存在しない場所がある——100 個の アカウントを作るスクリプト、一時的な認証情報を発行するサーバー、パスワードを 求められて創作してしまうアシスタント——そこでの選択肢は「ブラウザ」ではない。 選び方を誤った random() か、手で打った文字列だ。この API はそのためにある。

呼び出しの全部

キーなし、登録なし、ヘッダーなし。これで全部だ。

curl -X POST https://api.password.es/v1/generate

16 文字のパスワードとその解析が返る。この段落を書きながら実行した結果は x*7$9,BUy9PPvOI?、89 文字のアルファベットから引かれ、エントロピー 103.6 ビット、解読時間は 2.5 × 10¹¹ 年。レベルは 4 段階中の 4。

これらの数値はどれも新しくない。トップページのメーターを描くのと同じエンジンから 出ている。ビットの式も、攻撃モデル——毎秒 10¹² 回の試行、オフライン、高速ハッシュ——も、レベルの尺度もチェッカーと同じだ。 同じパスワードでサイトと API が違う数値を出すなら、どちらかが嘘をついていること になる。

返ってくる中身、フィールドごとに

応答には passwords——1 個だけ頼んでも必ず配列——と、lengthpoolbitslog10_guessescrack_time_log10_secondscrack_timelevellevel_scaleceiling を含む analysis ブロックが入る。

そのうち二つは説明に値する。level_scale はレベルの出どころを示す(今日は 常に "time")。将来サイトと API が食い違ったとき、数値を突き合わせて推測する のではなく、フィールドを見れば分かるようにするためだ。そして ceiling は その数値が厳密なのか上限なのかを示すgenerate では常に false になる。 サーバーがパスワードを作り、どのアルファベットを使ったか知っているからだ。 サイトのチェッカーではそうとは限らない。あちらではパスワードを持ち込むのは あなただからだ。

続いて注意書きの notice、そしてプラン、適用された言語、制限、ドキュメントへの リンクを含む _meta ブロックが入る。

オプション

すべて任意で、名前は英語のまま。API を組み込む人はフィールド名をそのまま打つ からだ。length(4–64、既定 16)、count(1–20)、lowerupperdigitssymbolsexclude_ambiguousno_repeatslang

curl -X POST https://api.password.es/v1/generate -H 'content-type: application/json' -d '{"length":20,"exclude_ambiguous":true}'

ドキュメントに書かれていて、組み込む前に知っておくとよい細部が二つ。 exclude_ambiguous が外すのは 7 文字ではなく 6 文字だ。0 O 1 I l | o を 落とすが、縦棒はそもそも記号セットに入っていない。だからアルファベットは 89 から 83 に下がり、82 にはならない。応答の pool が 83 なのはそのためだ。そして no_repeats は絶対の保証ではない。サイトの生成ツールとまったく同じく 10 回 やり直すだけで、64 文字では隣り合う繰り返しが約 0.1 % の確率ですり抜ける。 逆を約束するより、こう言うほうが役に立つ。

応答の言語

既定では英語で返る。何も指定せずに組み込む人が期待するのがそれだからだ。変更は URL の ?lang=、本文の "lang"、ヘッダーの Accept-Language の三通りで、 食い違ったときは先のものが勝つ。存在しない言語はエラーではなく、英語に落ちる。

ここには推測できない非対称がある。だから API 自身が申告する。メッセージは 英語とスペイン語にしか存在せず、リンクはサイトの 18 言語すべてにある。ドイツ語を 指定すればリンクはドイツ語、メッセージは英語のままだ。推測は要らない。 _meta.lang{ "messages", "links" } として、どちらに何が適用されたかを 返してくる。

MCP サーバー

MCP は、アシスタント——Claude や ChatGPT——が外部ツールを使うためのプロトコル だ。https://api.password.es/mcp は登録もキーも不要な MCP サーバーで、公開して いるツールは一つだけ。上と同じパラメータを取る generate_password である。

ここが我々にとって一番重要な部分で、技術的な理由からではない。パスワードを 取ってくる先がないアシスタントは、それを創作する。そこから出てくるものは ランダムではなく、モデルが「パスワードらしい」と考えた何かだ。このサーバーを つないでおけば、アシスタントは即興をやめ、crypto.getRandomValues() で作られた ものを、解析と、ツールの説明および各結果に含まれる注意書きとともに返す。その 注意書きこそ、アシスタントがパスワードを求めた人に読み上げることになる文言だ。 だからそこに置いてある。

他の MCP サーバーから来たなら、一つだけ。これはステートレスだ。 POST には JSON で応答し、ストリームは開かない。Mcp-Session-Id は発行も期待もしない。 通知には本文なしの 202 を返し、GET は 405 を返す。2025-06-18 の仕様はこれを 明示的に許しているが、セッションと SSE を前提にしている人は、誰も教えてくれ なければ手探りでデバッグすることになる。

できないこと

/v1/check は 501 を返す。 手抜きでも作りかけでもなく、意図的にそうして あり、応答自身が理由を説明する。チェッカーと同じ数値を返すには、サイトで動いて いるのと同じパターン解析エンジンが要る。そしてそれは、送られてくる内容次第で 1 リクエストあたり 11 ms から 3.6 秒の CPU を食う。登録もキーもないサービスで、 この幅は製品上の判断——長さの上限をどこに置くか——であり、まだ決まっていない。 それまでの間、501 は要求された言語でサイトのチェッカーを指す checker_url を 返す。あちらは同じことを、何も送らずにやってくれる。

アカウントもキーもプランも存在しない。存在しないので、API のどこにも登録への リンクは一つもない。誰もが必ず置く「制限超過エラー」の中にすらない。

制限

一つだけ、そして実際に適用されているのはそれだ。IP ごとに毎分 60 リクエスト。 このページを信じる必要はない。数値はすべての応答の _meta.limits.burst に入って 運ばれてくる。超えると Retry-AfterRateLimit-* ヘッダー付きの 429 が返る。

_meta にはもう一つ、値が nullquota ブロックが見える。アカウントが できたときのために予約された枠で、意図的に空にしてある。宣言されていながら 強制されていない制限は、何も宣言しないより悪い。組み込む側はそれを守り、誰も 数えていない数値に向けてコードを書くことになるからだ。

それでも、二度考えてほしい

パスワードを生成する API は、根本的にはアンチパターンだ。パスワードがネットワークを 通り、あなたのものではない機械を通過する。我々が何も保存しないことは、問題の形を 変えず、我々の担当分を変えるだけだ。そして 検証できない約束にどれだけの価値があるかは もう知っているはずだ。

だから注意書きはこのページだけに置いていない。要求された言語で、すべての応答に 乗って運ばれる。そしてだからこの段落は、ドキュメントの末尾に隠さずここにある。 自分で使うパスワードなら、このサイトの生成ツールはすべてブラウザの中で 動き、何も送らない。 API はもう一方のためのものだ。画面の前に誰もいないところで 起きることのために。

詳細は 2 ページに分かれている。API とは何かは、誰のためのもので、 今日何が応答し何がしないかを説明する。リファレンスには 9 つの パラメータ、すべてのフィールドの逐一の説明、エラーコード、制限がある。 エディタの横に開いておくのはこちらだ。機械に読ませたいなら openapi.json が ある。


出典:API 本体、2026 年 8 月 31 日に本番環境に対して検証——POST /v1/generatePOST /v1/check(501)、POST /mcpGET /openapi.json · 解析の数値は password.es の生成ツールおよびチェッカーと同じエンジンから出ている · 攻撃モデルは 毎秒 10¹² 回の試行、オフライン、高速ハッシュで、サイトの他の部分と同じ · MCP サーバーは 2025-06-18 の仕様を、ステートレスな Streamable HTTP トランスポート で実装している。

写真: Stanislav Kondratiev · Pexels

← ブログに戻る