認証とエラー
概要
NanoTerm は 2 層の認証を持ちます。
| レイヤー | 用途 | 方法 |
|---|---|---|
| マネージド ID | ユーザーのサインアップ / サインイン | ダッシュボード経由のブラウザ OAuth |
| API キー | CLI・SDK・API からのプログラマティックアクセス | Authorization: Bearer nt_xxx |
API キー
すべての API リクエストで Authorization ヘッダにキーを付けます。
curl https://api.nanoterm.dev/api/workspaces \
-H 'Authorization: Bearer nt_live_a1b2c3d4...'
キーの発行・取消はダッシュボードの API Keys ページ、または CLI の nanoterm auth login から可能です。
フルキーは作成時に一度だけ表示されます。後から取得する手段はないので、保管してください。
権限レベル
| 権限 | ワークスペース | 実行 | ファイル | 管理(キー、組織) |
|---|---|---|---|---|
full | 読み書き | 可 | 読み書き | 可 |
execute | 読み書き | 可 | 読み書き | 不可 |
read | 読み取り | 不可 | 読み取り | 不可 |
read キーはすべてのルートで強制されます — terminal / proxy
WebSocket、diff エンドポイントを含み、これらはコンテナ内でシェルを
起動するため exec 扱いです。read キーで
/api/workspaces/:id/terminal を開いたり /files/* に PUT すると
403 FORBIDDEN が返り、サイレントエスカレートはしません(こ
の契約は回帰テスト済み。今後追加された route が gate を忘れた場合
CI が落ちます)。
WebSocket 接続でのキーの渡し方
ブラウザは WebSocket ハンドシェイクにカスタムヘッダを付けられない
ため、terminal (/api/workspaces/:id/terminal) と proxy
(/api/workspaces/:id/proxy/:port) は WebSocket アップグレード
ハンドシェイク時のみ(リクエストに Upgrade: websocket がある場
合のみ)?token= クエリパラメータを許可します。通常の HTTP リク
エストは Authorization ヘッダを使ってください — 普通の GET で
?token= を渡しても無視されます。これは API キーがアクセスログ・
CDN ログ・Referer ヘッダ・ブラウザ履歴に乗らないようにするためで
す。
キーフォーマットについて
キーは nt_<random> 形式です。CLI や SDK 側で構造を意識する必要はありません — そのまま貼れば動きます。プランのアップグレードは既存キーに即時反映されるので、鍵の再発行は不要です。
レート制限
API キー経由のトラフィック (CLI、SDK、Agent コード) にプランごとの上限があります。
| プラン | リクエスト / 分 |
|---|---|
| Free | 60 |
| Developer | 600 |
| Team | 3,000 |
| Enterprise | カスタム |
上限超過時は 429 Too Many Requests が返り、Retry-After ヘッダに待機秒数が入ります。公式 CLI と SDK は 5 秒以下なら自動で 1 回リトライ、それ以上は明示的なエラーを返します。プランをアップグレードすると上限は即時引き上げ — キー再発行は不要です。
ダッシュボードからの操作 (ユーザーセッション) はプラン上限の対象外です。全リクエストに対しては IP ベースの汎用的な濫用防止制限 (1,000 rpm) が別途かかります。
エラー
すべての API エラーは共通の形式です。
{
"error": {
"code": "WORKSPACE_NOT_FOUND",
"message": "Workspace 'ws_abc' not found.",
"action": "Check the ID or list workspaces with GET /api/workspaces.",
"retryable": false,
"docs": "https://docs.nanoterm.dev/api-workspaces#get-workspace"
}
}
各フィールドの意味:
| Field | 用途 |
|---|---|
code | コードから match する用の安定識別子 |
message | 人間向けの説明 |
action | 次に何をすべきかを 1 文で |
retryable | 同じリクエストが後で成功しうるか(ネットワーク、レート制限なら true)。入力不正・リソース不在なら false |
docs | 該当ドキュメントへのディープリンク |
共通ステータスコード
どのエンドポイントからも返りうるコードです。エンドポイント固有の追加コードは各ページ参照。
| Status | Code | 意味 |
|---|---|---|
400 | VALIDATION_FAILED | リクエスト body のバリデーション失敗 |
401 | UNAUTHORIZED | Authorization ヘッダが無い/無効 |
403 | FORBIDDEN | 認証済だがキー / ロールの権限不足。action フィールドに必要なロールが書かれている |
404 | NOT_FOUND | リソース不在、または他組織所有 |
409 | CONFLICT | ユニーク制約違反(slug 重複等) |
426 | CLI_VERSION_TOO_OLD | 公式 CLI のバージョンが最低必要バージョンを下回っている |
429 | RATE_LIMITED | プランのレート制限超過 |
429 | QUOTA_EXCEEDED | ワークスペース数クォータ |
429 | COMPUTE_QUOTA_EXCEEDED | 月間コンピュート時間クォータ |
429 | MEMBER_QUOTA_EXCEEDED | プランのメンバー数上限(Free 1 / Dev 5 / Team 10 / Ent ∞) |
429 | STORAGE_QUOTA_EXCEEDED | スナップショット/ストレージクォータ |
500 | INTERNAL_ERROR | サーバ側の想定外エラー。短い backoff でリトライ可 |
501 | NOT_SUPPORTED | ランタイムが機能をサポートしていない |
503 | RUNTIME_UNAVAILABLE | コンテナランタイムに一時的に到達不可 |
426 の例
サーバーは公式 CLI/SDK が送る X-Client-Name と X-Client-Version を
読みます。X-Client-Name === "nanoterm-cli" でバージョンが最低必要
バージョンを下回ると、すべてのリクエストが 426 を返します。
他のクライアント(curl、ダッシュボード、独自 SDK)はこのチェックの
対象外です。
HTTP/1.1 426 Upgrade Required
Content-Type: application/json
{
"error": {
"code": "CLI_VERSION_TOO_OLD",
"message": "CLI 0.1.2 is below the minimum required version (0.1.3).",
"action": "Run: npm install -g @nanoterm/cli@latest",
"retryable": false
}
}
429 の例
HTTP/1.1 429 Too Many Requests
Retry-After: 17
Content-Type: application/json
{
"error": {
"code": "RATE_LIMITED",
"message": "Rate limit exceeded. Slow down requests or upgrade your plan.",
"action": "Retry after 17s, or upgrade at https://nanoterm.dev/pricing",
"retryable": true
}
}