> ## Documentation Index
> Fetch the complete documentation index at: https://arkor-92aeef0e-eng-353.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# arkor login / logout / whoami

> Arkor のマネージドバックエンドにサインインまたはサインアウトし、現在の identity を確認する。

# `arkor login`、`arkor logout`、`arkor whoami`

`~/.arkor/credentials.json` を読み書きするだけの 3 つの短いコマンドです。いずれも `.arkor/state.json` には触りません。匿名ワークスペースでは、初回 `trainer.start()`（または初回推論呼び出し）でランタイムがプロジェクトルーティングを自動作成します。OAuth ワークスペースでは学習の前に `.arkor/state.json` が存在している必要があります。今のところ `arkor login` も `arkor init` もこれを作らないので、現実的なパスは `{ orgSlug, projectSlug, projectId }` を手で書くことです。状態ファイルが無くてランタイムがエラーを返すと、このフォールバックを案内します。

## `arkor login`

```bash theme={null}
pnpm exec arkor login
```

マネージドバックエンドにサインインします。フラグなしの場合、CLI は Arkor Cloud の OAuth と匿名セッションのどちらを使うかを対話的に尋ねます。対話セレクタの初期選択は **Anonymous** なので、デフォルトを受け入れる（あるいは非 TTY にパイプする）と匿名パスに進みます。OAuth が走るのは明示的に選択するか `--oauth` を渡したときだけです。

### 概要

```
arkor login [options]
```

### オプション

| フラグ            | 説明                                                                                                                                                                                                                                                                                                                                            |
| -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--oauth`      | ピッカーをスキップして Arkor Cloud の OAuth（Authorization Code + PKCE）フローを直接走らせる。`--anonymous` と排他。`process.env.CI` が立っていると `--oauth needs a browser callback that CI runners can't complete. Use --anonymous in CI.`（CI ランナーが完了できないブラウザーコールバックを `--oauth` は必要とする。CI では `--anonymous` を使ってください）で失敗します。PKCE はブラウザーコールバックを必要とするため、CI ではループバックが永遠にハングするからです。 |
| `--anonymous`  | ピッカーをスキップして使い捨ての匿名トークンを要求。`--oauth` と排他。これは `arkor dev` の起動時に認証情報がディスクに無いときに走るのと同じパスです。`arkor dev` は必ずまず匿名でブートストラップします。                                                                                                                                                                                                                       |
| `--no-browser` | 自動の `open(url)` 呼び出しを無効化。authorization URL はいずれにせよ表示されます（`Browser: <url>`（ブラウザー: `<url>`）行）。このフラグは CLI がブラウザーを起動するのを止めるだけです。ヘッドレス環境（SSH、Docker）で便利。OAuth パスにのみ影響します。                                                                                                                                                                          |

### 何が起きるか

1. CLI はクラウド API の `/v1/auth/cli/config` を呼んでデプロイの OAuth 設定を読みます。
2. `--anonymous` が渡されたら、`/v1/auth/anonymous` から匿名トークンを要求し、`mode: "anon"` で `~/.arkor/credentials.json` に書きます。
3. `--oauth` が渡された場合、ピッカーをスキップして直接 OAuth フローへ。
4. フラグが渡されない場合、対話ピッカー（`OAuth (browser)` / `Anonymous`）を表示し **Anonymous** が事前選択されます。デフォルトを受け入れる（プロンプトがブロッキングしない非対話的な場面でも同様）と匿名パスが走り、OAuth を選ぶと OAuth フローが走ります。
5. OAuth フローは PKCE ペアを生成し、クラウド API から提供されたコールバックポートのいずれかでループバック HTTP サーバーを起動し、authorize URL を開く（または表示する）、コールバックを待ちます。コードをトークンに交換する前に state を検証し、不一致は CSRF 防止のため Abort されます。得られた OAuth トークンは `mode: "auth0"` で `~/.arkor/credentials.json` に書かれます。

ループバックサーバーは `finally` ブロックで閉じられるので、login が失敗してもサーバーは残りません。

### 匿名モードを 1 段落で

匿名認証は、アカウントなしで Arkor を試すためのものです。学習、ジョブ、その他の作業は匿名トークンを介してローカルマシーンに紐づきます。あとで OAuth に切り替える（`arkor login --oauth`、またはピッカーから `OAuth (browser)` を選ぶ）と認証情報ファイルは差し替えられますが、作業は移行されません。匿名で学習したものを残したいなら、学習を始める前に `arkor login --oauth` を走らせてください。

匿名アカウントは設計上 **単一端末専用** です。クラウド API は匿名ユーザーごとに `latest_jti` を保持しており、`userAuth` は受信した JWT の jti が一致しないリクエストをすべて拒否します。jti はトークンのローテーションでしか変わらないので、実際の発火タイミングは大きく 2 つに分かれます。**今のところ** CLI は匿名トークンの自動 refresh を実装していません（`@arkor/cloud-api-client` の `getToken()` 側で配線予定で、[SDK ロードマップ](/ja/roadmap) に乗っています）。そのためクライアント側からのローテーションは起こらず、別マシーンにコピーした `~/.arkor/credentials.json` も大抵しばらく動いてしまいます。失効するのは、発行ユーザーが明示的に新 identity を発行したとき（`arkor login --anonymous` が新しい jti でファイルを上書き）か、管理者がサーバー側でローテーションしたとき。そのタイミングで他のコピーは次の呼び出しから失敗します。**自動 refresh が入ると**、refresh のたびに `latest_jti` が即座に進むので、別端末（または同じマシーン上の古いバックアップ）に残った旧 jti のコピーは予告なく次の呼び出しで失敗するようになります。いずれにせよ、負けた側のクライアントは HTTP 401 / 409 を `code: "anonymous_token_single_device"` で受け取り、`cli/main.ts` がそれを実行可能なガイダンスとして整形します。匿名行そのものが削除された場合は `code: "anonymous_account_not_found"` も同じ仕組みで surface されます。リカバリー提案は **デプロイ形態に応じて分岐** します。OAuth がサポートされているデプロイでは `arkor login --oauth` を案内して複数端末対応のアカウントへサインアップする経路を示し、匿名専用デプロイ（OAuth 未設定）では代わりに `arkor login --anonymous` を案内します。後者で `--oauth` を出すとそのコマンドはそのまま失敗するので、新規匿名 identity の発行が唯一のリカバリ手段になるためです。**いずれのパスも、過去の匿名作業は移行されません**。前のワークスペースには発行元の credentials ファイルからしか到達できません。

### 匿名発行時の出力

どちらの匿名パスでも、新しい `anonymousId` と「同じ id がセッションをまたいで Arkor Cloud がこのクライアントを認識するための識別子である」旨の説明を必ず surface します。ただし出力の形は入口によって異なります。`arkor login`（`--anonymous` フラグまたはピッカー → **Anonymous**）はスピナーの停止行として `Anonymous id: <id>` を出し、続けて「認証情報ファイル（`credentialsPath()`、Linux と macOS では通常 `~/.arkor/credentials.json`）を保持していれば同じ identity を維持できる」旨の info 行を別行で出します。`arkor dev` の自動ブートストラップはスピナーを使わず、id と同じ説明を 1 本の info 行にまとめて出します。ピッカー → **Anonymous** のパスでは、さらに成功メッセージと並んで 1 行の warn（``Anonymous sessions aren't guaranteed to persist — sign in with `arkor login --oauth` to tie future work to your Arkor Cloud account.``、和訳: 匿名セッションは永続性が保証されないので、今後の作業を Arkor Cloud アカウントに紐付けたいなら `arkor login --oauth` でサインインしてください）が出るので、発行時点でアップグレードのヒントが見えます。明示的な `--anonymous` ショートカットでは `/v1/auth/cli/config` の取得をスキップしているため `arkor login --oauth` がそのデプロイで成功するかわからず、稀に存在する匿名専用デプロイで失敗するコマンドへユーザーを誘導しないよう、warn は意図的に抑制されます。

匿名発行のあらゆる入口で、単一端末の制約も別行の info として surface します。実際の文言は永続性ナッジと同じ `oauthAvailable` のゲーティング契約に従って分岐します。OAuth サポートのデプロイでは ``Note: anonymous accounts work on this machine only. Run `arkor login --oauth` to sign up for multi-device access.``（和訳: 注意: 匿名アカウントはこのマシーンでのみ動作します。複数端末で使うには `arkor login --oauth` でサインアップしてください）が出ますが、匿名専用デプロイ、および `/v1/auth/cli/config` の取得を意図的にスキップする `arkor login --anonymous` の経路では、bare な `Note: anonymous accounts work on this machine only.` だけが出ます。失敗確実なコマンドへユーザーを誘導しないためです。`arkor whoami` も匿名 identity に対しては bare 版のみを stderr に出します。さらに stdout / stderr の両方が TTY のときに限るので、出力をリダイレクトしたとき（stdout が TTY でなくなる）や、stderr 出力をすべて警告扱いする CI ランナー（stderr が TTY でなくなる）では追加のテキストは出ません。あくまで UX のヒントであり、どの挙動もゲートしません。stdout 側の形（`JSON.stringify(user, null, 2)` で出される user オブジェクトの JSON と、org に所属していれば続けて 1 行の人間向け `Orgs: <slug>, …` 行）は note 追加前と変わりません。ただし `Orgs:` 行は JSON 本体の一部ではなく後ろに付くサマリ行なので、出力全体をそのまま `jq` のような厳密な JSON パーサーに通すのは避けてください。

## `arkor logout`

```bash theme={null}
pnpm exec arkor logout
```

`~/.arkor/credentials.json` を削除します。デフォルトでは確認プロンプトが出ます。

### 概要

```
arkor logout [options]
```

### オプション

| フラグ         | 説明            |
| ----------- | ------------- |
| `-y, --yes` | 確認プロンプトをスキップ。 |

### 振る舞い

* 認証情報ファイルが存在しなければ、CLI は `No credentials on file.`（認証情報ファイルがありません）と出して終了。
* ユーザーがプロンプトを断ると `Aborted.`（中止しました）と出して削除せずに終了。
* `arkor logout` は `.arkor/state.json` や `.arkor/build/` 成果物には触りません。完全に最初からやり直すには `.arkor/` も手動で削除してください。

## `arkor whoami`

```bash theme={null}
pnpm exec arkor whoami
```

クラウド API の `/v1/me` から現在の identity を表示し、到達できる org slug も並べます。

### 概要

```
arkor whoami
```

フラグはありません。

### 出力

サインイン中なら `user` オブジェクトを JSON として整形表示し、レスポンスに org が含まれていれば `Orgs: <slug>, <slug>, …`（org 一覧）を 1 行で出します。`~/.arkor/credentials.json` が無いときは `Not signed in. Run \`arkor login\` or \`arkor login --anonymous\`.`（サインインしていません。`arkor login`または`arkor login --anonymous\` を実行してください）と出して終了します。

### 終了コード

* `0`: サインイン中、identity を表示。
* `0`: 未サインイン、メッセージは情報用のみ。
* `1`: クラウド API が `426 Upgrade Required` を返した。CLI はアップグレードのヒント（と検出したパッケージマネージャ用のアップグレードコマンド）を表示し、`process.exitCode = 1` を立てて、`arkor` のシャットダウンフックの非推奨警告フラッシュが終了前に走るようにします。
* `1`: クラウド API が認証状態系の構造化 `code`（`anonymous_token_single_device` または `anonymous_account_not_found`）を返した。`cli/main.ts` のトップレベルハンドラがそれを stderr 上の実行可能なメッセージへ整形します。具体的な文言は [トークンの有効期限](#トークンの有効期限) を参照。
* `1`: それ以外の非 2xx（一過性の 5xx、未マップの 4xx など）。以前は「`Failed to fetch /v1/me (<status>). Token may be expired.` を stdout に出して終了コード `0`」でしたが、本リリースで撤廃しました。`arkor whoami` は `CloudApiError` を投げ、`bin.ts` が `err.message`（例: `cloud-api 503`）だけを stderr に出してから非ゼロで終了します。スタックトレースは未知の `Error` 形（実質 SDK のバグ）に限り出すので、通常の HTTP 失敗はラッパーのログを汚しません。

## 認証情報の保存場所

両モードとも同じファイル `~/.arkor/credentials.json` に書き、`mode` フィールドが `"auth0"` か `"anon"` でタグ付けされます。これにより CLI（と Studio サーバー）はどのパスを使うかわかります。レイアウト全体は [プロジェクト構成](/ja/concepts/project-structure) を参照。

## トークンの有効期限

OAuth セッションでは、認証情報ファイルにアクセストークンと発行されたリフレッシュトークン、トークン交換が返した `expiresAt` タイムスタンプを記録します。リフレッシュトークンは保存していますが、CLI は **まだ** 期限切れアクセストークンの自動リフレッシュをしません。これは[ロードマップ上](/ja/roadmap#auth0-token-auto-refresh)です。

実用上の意味は次のとおりです。

* 期限切れまたは無効化されたトークンはクラウド API からの非 2xx として現れます。`arkor whoami` は汎用的な「Token may be expired」を出さなくなり、代わりに上流の `code`（あれば）を持った `CloudApiError` を投げ、`cli/main.ts` のトップレベルハンドラが既知 2 種の認証状態 `code` を実行可能なガイダンスへ整形します。整形前に `main()` は `/v1/auth/cli/config` を best-effort で取得し、リカバリーヒントをデプロイ形態に揃えます。

  * `code: "anonymous_token_single_device"`:
    * OAuth サポートのデプロイ: `Anonymous credentials were rejected as single-device. Anonymous accounts only work on one machine. Sign up for an account that supports multiple devices: arkor login --oauth`（終了コード `1`）。
    * 匿名専用デプロイ: `Anonymous credentials were rejected as single-device. Anonymous accounts only work on one machine. This deployment does not advertise OAuth, so the only recovery is to mint a new anonymous identity (your previous workspace data cannot be recovered): arkor login --anonymous`（終了コード `1`）。
  * `code: "anonymous_account_not_found"` も同様に分岐し、末尾は `arkor login --oauth` または `arkor login --anonymous` のいずれか。

  既知の `code` を持たないエラー（および `CloudApiError` 以外の例外）は `main()` から再 throw されます。`bin.ts` のトップレベル `await main(...)` は try/catch で囲まれており、エラーの形で挙動を分けます。`CloudApiError` は `err.message`（上流の `error` 本文、または本文が空のときの `cloud-api <status>` フォールバック）だけを出すので、通常の HTTP 失敗は 1 行で終わり、原因を切り分けやすくなります。それ以外の `Error` は `err.stack ?? err.message` で出すので、本物の SDK バグはフレームが見えます。いずれの場合も `process.exit(1)` ではなく `process.exitCode = 1` を立てるので、`main()` の `finally` ブロックの非推奨警告フラッシュ + テレメトリーシャットダウンは終了前にちゃんと走ります。明示的に catch しているのは、Node のデフォルトの unhandled rejection ハンドラがバンドル後の minified なコードフレームを出すのを避け、サポート対象の Node バージョン全体で stderr の flush を確定させるためでもあります。
* OAuth セッションの直し方は `arkor login --oauth` をもう一度走らせることです。フル PKCE フローを通って `~/.arkor/credentials.json` を新トークンで上書きします。

匿名トークンはサーバー側に 90 日の TTL がありますが、CLI はまだ自動リフレッシュをしません。その配線は `@arkor/cloud-api-client` の `getToken()` 側にあり、SDK ロードマップに残っています。今日時点で匿名セッションが失敗し始めたら `arkor login --anonymous` で新しいものを発行してください（新しい `anonymousId` が発行されるので、実質的には別ワークスペースになります）。

## よくあるエラー

| メッセージ                                                                                                                                                                           | 場所                                            | 意味                                                                                                                                                                                                                                                                                                            | 対処                                                                                                                                                                 |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `Pick one of --oauth / --anonymous, not both.`（`--oauth` と `--anonymous` のどちらか一方だけ指定してください）                                                                                     | `arkor login`                                 | モードフラグを両方渡した。                                                                                                                                                                                                                                                                                                 | どちらか一方にする。                                                                                                                                                         |
| `--oauth needs a browser callback that CI runners can't complete. Use --anonymous in CI.`（CI ランナーが完了できないブラウザーコールバックを `--oauth` は必要とする。CI では `--anonymous` を使ってください）             | `arkor login --oauth`（`process.env.CI` が立つ環境） | PKCE はブラウザーからのループバックリダイレクトに依存し、CI ではこれを満たせない。                                                                                                                                                                                                                                                                 | CI では `--anonymous` を使う。ブラウザーに到達できるローカルのヘッドレスフロー（例: `... --no-browser \| tee logs`）では、その実行の間 `CI` を unset にする。                                                     |
| `State mismatch — aborting to prevent CSRF`（state の不一致のため CSRF 防止で中止しました）                                                                                                       | `arkor login --oauth`                         | ループバックコールバックに返ってきた `state` が CLI の生成したものと一致しない。たいていは前回 login の古いタブをブラウザーが開いたケース。                                                                                                                                                                                                                              | `arkor login --oauth` を再実行し、新規に開いたタブでフローを完了。                                                                                                                       |
| `Auth0 did not return a refresh token. Make sure the Application has 'offline_access' scope enabled.`（Auth0 がリフレッシュトークンを返しませんでした。Application で `offline_access` スコープを有効にしてください） | `arkor login --oauth`                         | OAuth のトークン交換は成功したがレスポンスに `refresh_token` が無く、CLI がアクセストークンの寿命を超えてセッションを保てない。たいていデプロイ側の設定ミス。                                                                                                                                                                                                                  | OAuth（Auth0）アプリケーションで `offline_access` スコープを有効化してから `arkor login --oauth` を再実行。                                                                                    |
| `No credentials on file.`（認証情報ファイルがありません）                                                                                                                                       | `arkor logout`                                | `~/.arkor/credentials.json` が存在しない。削除対象なし。                                                                                                                                                                                                                                                                    | サインインしたいなら先に `arkor login`。                                                                                                                                        |
| `Not signed in. Run \`arkor login\` or \`arkor login --anonymous\`.`（サインインしていません。`arkor login`または`arkor login --anonymous\` を実行してください）                                          | `arkor whoami`                                | 上と同じ条件を別コマンドから出している。                                                                                                                                                                                                                                                                                          | 同じ対処。                                                                                                                                                              |
| `Anonymous credentials were rejected as single-device. …`（末尾は `arkor login --oauth` または `arkor login --anonymous`、デプロイ形態次第）                                                     | `arkor whoami` および認証付きの全コマンド                  | クラウド API が `code: "anonymous_token_single_device"` で拒否した（userAuth の jti チェックからの HTTP 401、または rotate-jti の CAS からの HTTP 409）。認証情報ファイルが別端末にコピーされたか、別のローカルプロセスがこのトークンを recovery window 内でローテートし越えた、のいずれか。                                                                                                        | メッセージ末尾のコマンドに従う: OAuth サポートのデプロイなら `arkor login --oauth`、匿名専用デプロイなら `arkor login --anonymous`。どちらも *新規* identity で、過去の匿名作業は移行できない。CLI は `1` で終了。                   |
| `Your anonymous credentials are no longer valid. …`（末尾は `arkor login --oauth` または `arkor login --anonymous`）                                                                    | `arkor whoami` および認証付きの全コマンド                  | クラウド API が `code: "anonymous_account_not_found"` で拒否した（HTTP 401）。背後の `anonymous_users` 行が削除された（admin / cascade / 明示的な revoke）。                                                                                                                                                                                | 上と同じく、メッセージ末尾のデプロイ依存コマンドに従う。前の匿名ワークスペースは取り戻せない。CLI は `1` で終了。                                                                                                      |
| `cloud-api <status>`（1 行、スタックなし）                                                                                                                                                | `arkor whoami` および認証付きの全コマンド                  | 構造化された認証状態 `code` を持たない非 200 / 非 426 のクラウド API レスポンス（一過性の 5xx、未マップの 4xx など）。`cli/main.ts` が `CloudApiError` をそのまま再 throw し、`bin.ts` がスタックの最上位で catch して `err.message`（上流の `error` 本文、または本文が空のときの `cloud-api <status>` フォールバック）だけを表示した後、`process.exitCode = 1` をセットする。スタックトレースは未知の `Error` 形（実質 SDK のバグ）に限り出す。 | メッセージをそのまま確認し、トランスポート / サーバー障害なら再試行。OAuth アクセストークンの期限切れなら `arkor login --oauth` を再実行。匿名トークンの期限切れなら `arkor login --anonymous` を再実行（新しい `anonymousId` で別ワークスペースになる）。 |
| `426 Upgrade Required`（アップグレードヒント付き）                                                                                                                                            | `arkor whoami`（および他のクラウド API 呼び出し）            | デプロイがより新しい SDK バージョンを要求している。CLI は検出したパッケージマネージャ用のアップグレードコマンドを表示し、`process.exitCode = 1` を立てる。                                                                                                                                                                                                                 | `arkor` パッケージをアップグレードして再実行。                                                                                                                                        |
