Skip to main content

トークンセキュリティモデル

L402トークンは、:で結合された2つの部分で構成されています:
  • Macaroon{hash, exp}を含むbase64エンコードされたJSON。SHA-256で署名されています。preimageを知らずに偽造することはできません。
  • Preimage — SHA-256でハッシュ化したときに、macaroonに埋め込まれたハッシュと一致しなければならない32バイトのシークレット。
検証は完全にローカルで行われます — データベースの参照もネットワーク呼び出しも必要ありません。SDKはマイクロ秒単位で暗号学的にハッシュ関係を検証します。

リプレイ保護

l402-kitには組み込みのリプレイ保護が含まれています。各preimageは一度しか使用できません:
トークンの初回使用時に、preimageは使用済みとしてマークされます。同じpreimageを使用した後続のリクエストは401 Token already usedを返します。 デフォルトストア:インメモリのSet。これは以下を意味します:
  • 再起動するとリプレイストアがクリアされる(再起動をまたいでトークンが再利用可能になる)
  • 複数のインスタンス間で状態が共有されない
複数インスタンスを使用する本番環境では、永続的なリプレイストアを実装してください:

トークンの有効期限

トークンにはexpフィールド(ミリ秒単位のUnixタイムスタンプ)が含まれています。SDKは期限切れのトークンを自動的に拒否します。 デフォルトのTTL:1時間(インボイス作成時にLightningプロバイダーによって設定されます)。

HTTPSは必須

本番環境でL402を平文のHTTPで使用しないでください。 macaroonとpreimageはAuthorizationヘッダーで送信されます。HTTPでは、ネットワーク攻撃者にさらされてしまいます。

レート制限

L402はデータベースを参照するのではなく、暗号学的にトークンを検証するため、コストが低くなっています。しかし、Lightningインボイスの作成(402レスポンス)はLightningプロバイダーのAPIを呼び出します。 DoSを防ぐために、インボイス作成をレートリミッターで保護してください:

シークレット管理

APIキーをハードコードしないでください。環境変数を使用してください:
本番環境ではシークレットマネージャーを使用してください:AWS Secrets Manager、Doppler、Vault、または.env + dotenv(絶対にgitにコミットしないでください)。

管理エンドポイントの認証

管理エンドポイントや統計エンドポイントを公開する場合、URLクエリパラメーターでシークレットを受け取ることは絶対に避けてください。URLはリバースプロキシ、CDN、クラウドプロバイダーによってクエリ文字列を含む完全な形でログに記録されます。

Supabaseキーの管理

SUPABASE_SERVICE_KEY(サーバーサイド専用)とSUPABASE_ANON_KEY(クライアントへの公開が安全)を正しく使い分けてください: 機密テーブル(例:pro_access)を読み取るサーバーサイドのCloudflare Workersはサービスキーを使用しなければなりません — anonキーは絶対に使用しないでください。機密テーブルのRLSポリシーはanonアクセスを許可すべきではありません。

コンテンツセキュリティポリシー

APIとともにフロントエンドを提供する場合、CSPがL402フローをブロックしないようにしてください:

データ管理 — ユーザーデータの削除

ユーザーはVS Code拡張機能内からいつでもすべての支払い履歴とProサブスクリプションを削除できます(設定 → 危険ゾーン)。拡張機能は以下を呼び出します:
レスポンス:
このエンドポイントはSupabaseのservice role keyをサーバーサイドで使用してRLSをバイパスし、以下を永続的に削除します:
  • paymentsテーブル内のowner_address = ?に一致するすべての行
  • pro_accessテーブル内のaddress = ?に一致するすべての行
拡張機能では、削除ボタンが有効になる前にユーザーがLightningアドレスを正確に入力する必要があります — 破壊的な操作に対するGitHubスタイルの確認です。
l402-kitの上に独自のダッシュボードを構築する場合は、ユーザー向けに同様のエンドポイントを公開してください。anonキーによる削除は絶対に許可しないでください — サービスキーを使用するサーバーサイド関数を通じて常にプロキシしてください。

プライバシーとデータ最小化

l402-kitは動作に必要な最小限のデータを収集するよう設計されています。以下に、保存される内容、その理由、および各フィールドを強化する方法を示します。

保存される内容

preimageをそのまま保存せずハッシュ化する

preimageはLightning支払いが行われたことを証明する32バイトのシークレットです。そのまま保存すると、データベース侵害によってすべての証明が公開されてしまいます。代わりにSHA-256ハッシュを保存してください — これはすでに公開されており(BOLT11インボイスに埋め込まれています)、リプレイ保護には十分です:

ウェイトリストのメールアドレスを保護する

メールアドレスはシステム内で唯一の真のPIIです。保護レベルの順に以下のオプションがあります:

データ削除前にウォレット所有権を証明する(LNURL-auth)

/api/delete-dataエンドポイントは、Lightningアドレスの実際の所有者からのリクエストのみを受け付けるべきです。LNURL-authを使用して所有権を暗号学的に証明してください — ユーザーはパスワードやアカウントなしで、LightningウォレットのPrivateKeyでサーバーチャレンジに署名します: Supabaseの状態を含む完全なシーケンスについては、完全なフロー図を参照してください。 これにより、Lightningアドレスを知っている場合でも、他のユーザーのレコードを削除することができなくなります。

チェックリスト

  • すべてのエンドポイントでHTTPSが強制されている
  • APIキーがソースコードではなく環境変数に保存されている
  • 管理/統計エンドポイントがヘッダー認証を使用している(?secret= URLパラメーターではなく)
  • Supabaseのservice_roleキーがサーバーサイドで使用されている;anonキーはクライアントのみ
  • 機密SupabaseテーブルにanonのSELECTポリシーがない
  • データ削除エンドポイント(/api/delete-data)がサービスキーを使用し、anonキーを使用していない
  • インボイス作成にレートリミッターが設定されている
  • リプレイ保護がテストされている(preimageを再利用して401を確認)
  • トークンの有効期限がテストされている(開発環境で短いTTLを設定し、有効期限後の401を確認)
  • preimageがSHA-256ハッシュとして保存されており、生のシークレットではない
  • ウェイトリストのメールアドレスが保存時に暗号化されているか、送信後に破棄されている
  • /api/delete-dataがウォレット所有権のLNURL-auth証明を要求している
  • Redisを使用したリプレイストア(インスタンス間で共有)
  • 402レスポンスレートの監視(スパイク = DoSの可能性)
  • Lightningプロバイダーのフェイルオーバー(BlinkProvider → LNbitsProviderへのフォールバック)
  • Lightningプロバイダーのステータスページ監視(例:status.blink.sv)