OneDrive と Google Drive の認可
CLI はブラウザーでのログイン、暗号化されたローカルアカウントの保存、ステータス、ローカルログアウト、および OneDrive または Google Drive のアプリケーションフォルダーを介した不変の暗号文オブジェクトの cloud sync をサポートします。トークンの更新結果は、その後のアップロードより前に永続化されます。実際のアカウントでの検証はまだ完了していません。各デバイスではプロバイダーごとに 1 つのアカウントを接続できます。再ログイン時は、新しい認可が成功してから、そのプロバイダーのアカウントだけを置き換えます。
ログイン前の準備
新しい CLI をビルドまたはインストールし、同じ新しいバージョンでデーモンを再起動します。
cargo install --path crates/cli --locked
memories daemon
デーモンは別のターミナルで実行してください。ログインを実行するターミナルでは、必要に応じて既存のライブラリのロックを解除し、memories sudo を実行します。すべてのコマンドで同じ --home/MEMORIES_HOME を使用してください。新しいライブラリには、まず memories init が必要です。そのデータベースをクラウド同期ディレクトリに移動しないでください。
OAuth アプリケーション登録は同梱されていません。独自の登録を使用してください。CLI が Microsoft または Google アカウントのパスワードを要求することはありません。認証と同意は、ブラウザーでプロバイダーの Web サイト上で行います。
OneDrive の登録
- Microsoft Entra ID でアプリ登録を作成します。ビジネス用と個人用の OneDrive の両方が必要な場合は、任意の組織ディレクトリのアカウントおよび個人用 Microsoft アカウントのサポートを選択します。このクライアントは
commonテナントを使用します。 - 認証で モバイルとデスクトップ アプリケーションのプラットフォームを追加し、リダイレクト URI を
http://localhost/oauth/callbackに設定します。これはパブリックデスクトップクライアントであり、Web または SPA アプリケーションではありません。このフロー用のクライアントシークレットを作成しないでください。 - 委任された Microsoft Graph のアクセス許可
User.ReadとFiles.ReadWrite.AppFolderを構成します。ログインではoffline_accessも要求します。組織の同意ポリシーによっては管理者の承認が必要です。 - アプリケーション(クライアント)ID をコピーし、次を実行します。
memories sudo
memories cloud login onedrive --client-id YOUR_MICROSOFT_CLIENT_ID
コールバックは http://localhost:PORT/oauth/callback を使用します。Microsoft は localhost リダイレクト URI の照合でポートを無視します。パスは登録と一致する必要があります。リスナーは IPv4 ループバックだけにバインドします。オプションの --port PORT で固定ポートを選択できます。指定しない場合は OS が空いているポートを選びます。
代わりに、--client-config PATH は client_id を含む JSON オブジェクトを受け付けます。カスタムの認可 URL、トークン URL、および機密クライアントのシークレットは受け付けません。
Google Drive の登録
- Google Cloud プロジェクトを作成または選択し、Google Drive API を有効にします。
- OAuth 同意画面を構成します。アプリがテストモードの場合は、Google アカウントをテストユーザーとして追加します。
drive.appdataに加え、アカウント識別用のopenid、email、profileを要求します。 - 種類が デスクトップ アプリの OAuth クライアントを作成し、その JSON ファイルをダウンロードします。CLI が想定するのはダウンロードした
installedセクションであり、Web クライアントの構成ではありません。 - JSON をこのリポジトリの外に保管し、次を実行します。
memories sudo
memories cloud login google-drive --client-config /path/to/google-desktop-client.json
Windows CMD の例:
memories cloud login google-drive --client-config "%USERPROFILE%\Downloads\google-desktop-client.json"
コールバックは http://127.0.0.1:PORT/oauth/callback を使用します。デスクトップアプリケーションのフローはループバックコールバックをサポートするため、ホストされたコールバックサーバーは不要です。ダウンロードしたエンドポイントのフィールドは無視され、クライアントは固定の Google 公式エンドポイントを使用します。installed-app のクライアントシークレットが指定されている場合は JSON から読み取り、コマンド引数からは読み取りません。デスクトップアプリのシークレットは PKCE の代わりにはなりません。
Google はテストモードのアプリケーションのリフレッシュトークンを失効させることがあります(基本以外のスコープを要求する場合、通常は 7 日後です)。必要になったら再認可してください。公開およびプロバイダーによる検証の要件はアプリケーションによって異なります。
ステータス、キャンセル、ログアウト
memories cloud status
memories cloud sync onedrive
memories cloud sync google-drive
memories sudo
memories cloud logout onedrive
memories cloud logout google-drive
ステータスは、プロバイダー、アカウントの識別情報、表示名またはメールアドレス、アクセストークンの有効期限、リフレッシュトークンが保存されているかどうかを返します。アクセストークン、リフレッシュトークン、クライアントシークレットは返しません。sync_enabled は、少なくとも 1 つのクラウドアカウントが接続されていることを示します。object_sync は outbox/inbox の件数だけを報告します。cloud sync は必要に応じてプロバイダーとの転送前にトークンを更新します。アクセストークンが期限切れであることだけでは、プロバイダーへの同意が取り消されたとは限りません。
有効期限は、トークン交換の開始時点から保守的に測定します。ネットワーク応答やアカウントプロフィールの問い合わせが遅くても、トークンの有効期間は延長されません。
ログアウトはローカルアカウントを削除し、そのプロバイダーの保留中のログインをキャンセルします。Microsoft または Google のサーバー上の同意は取り消しません。リモートでの取り消しには、プロバイダーの接続済みアプリの設定を使用してください。ローカルレコードを削除しても、ストレージのスナップショットや古いローカルコピーからのフォレンジック上の消去は保証されません。
ログインには 5 分の制限があります。--no-browser はブラウザーを開かずに認可 URL を表示しますが、このコンピューターでのコールバックを引き続き待ちます。これは帯域外または手動コードのフローではなく、リモートまたはヘッドレスのログイン機構でもありません。
タイムアウトまたは通常のエラー時には、CLI は保留中のチケットをキャンセルします。CLI を強制終了した場合は、有効期限まで待つか、再試行前に cloud logout PROVIDER を使用してください。
セキュリティとライフサイクル
- OAuth は S256 PKCE と予測不能な state 値を伴う認可コードを使用します。コールバックのメソッド、Host、オリジン、パス、重複フィールド、state、有効期限、リプレイを確認します。プロバイダーのエラーとコールバックページはコードやトークンをそのまま表示しません。
- ブラウザーの待機、トークン交換、識別情報の問い合わせは、デーモンの mutex とデータベーストランザクションの外で CLI プロセス内で実行します。HTTPS リクエストはタイムアウトと応答サイズに上限を設け、自動リダイレクトを無効にし、環境のプロキシを継承しません。この初期トランスポート構成では、プロキシを必要とするネットワーク環境はサポートされません。
- デーモンは、プロバイダー、クライアント ID、ローカル呼び出し元に結び付けた短命のチケットを発行します。保存には再度 sudo が必要です。ロック、再起動、ログアウトは保留中のチケットを無効にします。遅れて届いた HTTP 結果で、キャンセル済みのログインを復元することはできません。
- ローカル CLI はプロバイダーとの交換を実行する信頼済みの主体です。サービスのトークン書き込み操作には有効なチケットと権限昇格が必要です。これはリモートエンドポイントではなく、MCP から使用できません。トークン読み取りコマンドはありません。
- アカウントとトークンは暗号化されたローカル状態の中にあります。エクスポートされたバックアップ、デバイス承認、vault 同期、監査出力、MCP から除外されます。各デバイスで個別にログインする必要があります。クラウドログインで vault のメンバー資格は付与されません。
- 所有するシークレットバッファーはゼロ化します。HTTP/URL/JSON ライブラリや OS メモリに一時的なコピーが残る可能性があります。詳細は
SECURITY.mdを参照してください。
この状態フィールドは、存在しない場合の後方互換性があります。認可済みのストアを古いデーモンで再度開いて書き直さないでください。古いデーモンはクラウドアカウントを理解せず、新しいフィールドを破棄して、再度のクラウドログインが必要になる可能性があります。
検証の範囲
テストでは、ローカル HTTP フィクスチャに対する両プロバイダーの交換、実際のループバックコールバック、暗号化された永続化、呼び出し元への結び付け、リプレイ、ロック後のキャンセル、スコープまたはリフレッシュトークンの不足、エラーの秘匿、バックアップからの除外、MCP の拒否を確認します。テスト用トランスポートはモジュール内で非公開です。本番エンドポイントは固定の HTTPS です。
実際のアカウントの認可には、登録済みのクライアント ID または構成と、ユーザーの同意が必要です。このテストなしに実際のプロバイダーアカウントを検証済みと主張することはありません。モバイルは後述のネイティブ認可フローを使用します。実際の同意はまだ検証されていません。
2026-09-09 に確認した参考資料:
モバイルクライアント
クラウドボタンは、接続ステータス、接続または再接続、今すぐ同期、切断を開きます。同期はフォアグラウンドでのみ行います。AppAuth はシステムブラウザーを開き、state を検証し、PKCE を生成します。ブラウザーによってアプリがバックグラウンドになると、ライブラリがロックされます。戻ったら、Rust がコードを交換する前にロックを解除し、再度ローカルで認可してください。アクセストークンとリフレッシュトークンは Rust が検証および保存し、Dart には返しません。
プラットフォーム固有のパブリッククライアント登録を使用してビルドします。
--dart-define=MEMORIES_ONEDRIVE_CLIENT_ID=...--dart-define=MEMORIES_ONEDRIVE_REDIRECT_URI=app.memories.memories:/oauth/callback--dart-define=MEMORIES_GOOGLE_CLIENT_ID=...--dart-define=MEMORIES_GOOGLE_REDIRECT_URI=...
クライアント ID が未設定の場合は、説明メッセージを表示してログインを無効にします。Web クライアントシークレットを埋め込んだり、デスクトップのループバック構成を再利用したりしないでください。プラットフォーム、バンドルまたはパッケージ、署名 ID に対してプロバイダーがサポートする正確なネイティブリダイレクトを使用してください。Google の iOS 登録では一般にクライアント ID を逆順にしたスキームを使用します。Google の Android 登録とリダイレクトの制限は異なるため、Android ビルドを配布する前に、プロバイダーがサポートするネイティブフローで検証する必要があります。URI が設定されていることだけでは、プロバイダーの同意がサポートされる証拠にはなりません。
既定の登録済みアプリスキームは app.memories.memories です。別のカスタムスキームを使う場合、Android は Gradle プロパティ memoriesOAuthScheme(例えば ORG_GRADLE_PROJECT_memoriesOAuthScheme を通じて)を受け付けます。iOS は MEMORIES_OAUTH_SCHEME を mobile/ios/Flutter/Memories.xcconfig 内で使用します。スキームはネイティブコールバック登録と Dart のリダイレクト URI に一致する必要があります。両プロバイダーを有効にする場合は、互換性のあるコールバックを登録するか、2 番目のスキームをネイティブのマニフェストまたは URL types に追加してください。HTTPS のアプリリンクまたはユニバーサルリンクには、プラットフォームの関連付けファイルとネイティブ構成が必要です。既定のカスタムスキームビルドでは有効になりません。
ブラウザーログインが完了しても、古い権限昇格セッションは復元できません。ローカルのパスワードプロンプトをキャンセルしても、クラウド認可は変わりません。ロックまたはバックグラウンド移行は、遅れて届いた同期結果の適用をキャンセルします。ネットワーク障害時は、後の「今すぐ同期」に備えてキューのデータを保持します。UI は完了した操作と、保留作業が残る制限付きの実行を区別します。サインアウトはローカルトークンを削除しますが、プロバイダーの同意やクラウドファイルは削除しません。実際のプロバイダーの検証については、リリース条件を参照してください。