セキュリティ
認可はキーのみで行う
Section titled “認可はキーのみで行う”コントラクトはセキュリティスキームを2つだけ定義しており、どちらも同じシークレットを運びます:
| スキーム | ヘッダー | 備考 |
|---|---|---|
ApiKeyHeader | X-API-Key | 推奨。 |
BearerAuth | Authorization: Bearer | 同等です。クライアントライブラリがベアラートークンを要求する場合に使用します。 |
どちらの形式も同じ資格情報に解決されます。GET /v1/products は、未認証の呼び出しを受け付ける唯一のエンドポイントです。
IP 許可リストはありません。IP 単位のレート制限は、同じアドレスの背後にあるすべてで共有される上限です — 悪用を抑止するものであり、アクセスを許可したり拒否したりするものではありません。キーを、アカウントの権限境界のすべてとして扱ってください。
Zelnum の API キーは ck_ に続く 48 文字、合計 51 文字です。それより短いものはキーではないので、シークレットマネージャーが値を壊したときの確認に役立ちます。
| すべきこと | すべきでないこと |
|---|---|
| シークレットマネージャーまたは環境変数に保管する | リポジトリ、ユーザーが読める設定ファイル、CI ログに置く |
| サーバーから送信する | ブラウザの JavaScript、モバイルアプリのバンドル、その他いかなる公開クライアントにも置く |
キーを特定する必要があるときは api_key_id を読む | サポート依頼にキー本体を貼り付ける |
| ログでは伏せ字にする | リクエストヘッダーをそのままログに記録する |
フロントエンドのバンドルに入ったキーはシークレットではありません。統合がブラウザから API を呼び出す必要がある場合、ブラウザは自社のサーバーを呼び、サーバーがキーを保持してください — 未認証に見えるトラフィックに対する IP 単位の上限は、あなたを救いません。
データベースには SHA-256 ハッシュと 9 文字の表示用プレフィックスが保存され、値そのものは保存されません。そのため、ダンプが漏れても使用可能なトークンが誰かに渡ることはありません。裏を返せば、どのエンドポイントもキーを返すことはできません。紛失した場合はローテーションします。
どのキーが有効かを確認する
Section titled “どのキーが有効かを確認する”curl -X GET "https://api.zelnum.com/api/v1/api-key" \ -H "X-API-Key: YOUR_KEY_HERE"レスポンスには api_key_id、masked_key、last_used、created_at が含まれます — 対象はアカウントで最後に発行された有効なキーです。このエンドポイントが報告するのは1つのキーなので、一覧ではなく「いま自分が使っているはずのキー」として読んでください。すべてのキーを確認するには、コンソールを使用します。
last_used はローテーションが反映されたかを確認する最速の方法ですが、1つ注意点があります。キーごとに最大でも5分に一度しか書き込まれないため、頻繁に使われているキーでも、切り替えてから最大5分間は未使用のように見えることがあります。古い last_used だけで、デプロイが壊れていると判断しないでください。
キーのローテーション
Section titled “キーのローテーション”アカウントは複数の有効なキーを同時に保持でき、コンソールはそれらを個別に管理します:
| コンソールでの操作 | 効果 |
|---|---|
| 作成 | キーを追加します。既存のキーはすべて動作し続けます。 |
| 再生成 | そのキーを無効化し、同じ名前の代替キーを発行します。元のキーは即座に動作しなくなります。 |
| 削除 | キーを完全に削除します。 |
これにより2通りのローテーションの形が得られ、選択の基準は、重複期間を許容できるかどうかです。
2つ目のキーを作成する — 段階的ローテーションであり、推奨される方法:
- コンソールで新しいキーを作成します。他は何も変わりません。古いキーも引き続き認証できます。
- 必要なすべての場所(アプリケーションサーバー、ワーカー、cron ジョブ、定期実行スクリプト)に、新しい値を配置しますが、まだ有効化はしません。
- デプロイを切り替えます。
GET /v1/api-keyが新しいapi_key_idを報告するまで確認しますが、last_usedの5分という粒度を考慮してください。 - 誰もそれを使わなくなったら、古いキーを削除します。認証情報を実際に取り除くのはこの手順です — これを行わない限り、ローテーションは完了しません。
その場で再生成する — 古い値を今すぐ無効にしなければならない場合:
キーが露出し、有効なままでいること自体がリスクである場合に使用します。
- 空白期間を受け入れます。 再生成した瞬間に古いキーは動作しなくなるため、それを保持しているすべてのコンポーネントは、再デプロイされるまで
401 unauthorizedを返します。設計上、重複はありません。 - コンソールで再生成し、バナーから平文の値をすぐにコピーしてください — そこ以外には、二度と表示されません。
- 新しい値をデプロイし、まだ
401を記録しているものがないか確認します。
トランスポート
Section titled “トランスポート”すべてのエンドポイントは HTTPS です。平文のリスナーはなく、ダウングレードを受け付けるエンドポイントもないため、キーが暗号化されずに移動する構成は存在しません。
API の前にプロキシやゲートウェイを構築する場合は、エッジで TLS を終端し、X-API-Key ヘッダーを転送してください — 書き換えたり、受信リクエストログに追加したりしないでください。
送信するものと、その保持期間
Section titled “送信するものと、その保持期間”API への入力は電話番号とメールアドレスであり、ほとんどの法域で個人データです。2つの帰結があります:
- 必要なものだけを送信します。 チェックに必要なのは識別子だけで、それ以外は不要です。リクエストボディにユーザー ID、内部参照、自由記述のメタデータを追加しないでください。それはフィールドとして保存されず、自分のログの露出を広げるだけです。
- 保持期間を把握します。 リアルタイムログと冪等性のリプレイ結果は既定で 30 日間、バルク結果ファイルは7 日間保持されます(
result_retention_days)。期間を過ぎると記録は消えるため、保持が義務付けられているものはエクスポートしてください。
自分のシステム内でも、番号を機微情報として扱ってください。検出結果は、特定の人物が特定のプラットフォームに登録されているかどうかを観測者に伝えます。識別子と判定の組み合わせは、どちらか片方よりも多くを明かします。
二重課金からの保護
Section titled “二重課金からの保護”これは課金上の性質であると同時に、セキュリティ上の性質でもあります。Idempotency-Key が再試行を安全にするため、ネットワーク障害やせっかちな運用担当者が、1回の課金を2回に変えることはできません。結果を確認できなかったリクエストを再試行するために、新しいキーを生成しないでください — 冪等性とリトライ を参照してください。
- ステータスとサポート — キーを漏らさずにエスカレーションする際に含めるもの
- エラーコード — 文脈における
unauthorizedとaccount_banned