# 画面設計書 118-アクセストークン一覧

## 概要

本ドキュメントは、GitLabのプロジェクト設定におけるアクセストークン一覧画面の設計仕様を記載したものである。

### 本画面の処理概要

アクセストークン一覧画面は、プロジェクトアクセストークンの作成・管理を行うための画面である。プロジェクトアクセストークンは、特定のプロジェクトに対してAPIやGitへのアクセスを提供する認証トークンである。

**業務上の目的・背景**：CI/CDパイプラインやスクリプトからプロジェクトにアクセスする際、個人のアクセストークンではなくプロジェクト専用のトークンを使用することで、セキュリティとアクセス管理を向上させることが目的である。トークンにはスコープと有効期限を設定でき、最小権限の原則に基づいたアクセス制御が可能である。

**画面へのアクセス方法**：プロジェクトのサイドバーから「設定」→「アクセストークン」を選択してアクセスする。または、URL `/:namespace/:project/-/settings/access_tokens` に直接アクセスする。

**主要な操作・処理内容**：
1. プロジェクトアクセストークンの新規作成
2. アクティブなトークンの一覧表示
3. 非アクティブ（失効・取り消し済み）トークンの一覧表示
4. トークンの取り消し（Revoke）
5. トークンのローテーション

**画面遷移**：
- 遷移元：プロジェクト設定ページ、プロジェクトサイドバー
- 遷移先：なし（同一画面で操作完結）

**権限による表示制御**：
- `read_resource_access_tokens` 権限：アクセストークン一覧の表示
- `create_resource_access_tokens` 権限：新規トークン作成フォームの表示
- グループ設定でトークン作成が無効化されている場合、作成フォームは非表示

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 81 | 個人アクセストークン | 主機能 | プロジェクトアクセストークンの管理 |

## 画面種別

一覧（作成フォーム付き）

## URL/ルーティング

- **URL**: `/:namespace/:project/-/settings/access_tokens`
- **HTTPメソッド**: GET（表示）、POST（作成）
- **コントローラー**: `Projects::Settings::AccessTokensController`
- **アクション**: `index`、`create`、`revoke`、`rotate`、`inactive`

## 入出力項目

### トークン作成フォーム

| 項目名 | 項目ID | 型 | 必須 | 説明 |
|--------|--------|-----|------|------|
| トークン名 | name | string | はい | トークンの識別名 |
| 有効期限 | expires_at | date | いいえ | トークンの有効期限 |
| ロール | access_level | select | はい | トークンに付与するロール |
| スコープ | scopes | checkbox | はい | トークンの権限スコープ |

### 利用可能なスコープ

| スコープ | 説明 |
|---------|------|
| api | API完全アクセス |
| read_api | APIの読み取りアクセス |
| read_registry | コンテナレジストリの読み取り |
| write_registry | コンテナレジストリの書き込み |
| read_repository | リポジトリの読み取り |
| write_repository | リポジトリの書き込み |
| create_runner | Runnerの作成 |
| k8s_proxy | Kubernetesプロキシ |
| ai_features | AI機能 |

## 表示項目

### アクティブトークン一覧

| 項目名 | 説明 |
|--------|------|
| トークン名 | トークンの識別名 |
| 作成日 | トークンが作成された日時 |
| 有効期限 | トークンの有効期限 |
| 最終使用日 | トークンが最後に使用された日時 |
| ロール | トークンに付与されているロール |
| スコープ | トークンの権限スコープ |

### 非アクティブトークン一覧

| 項目名 | 説明 |
|--------|------|
| トークン名 | トークンの識別名 |
| 作成日 | トークンが作成された日時 |
| 状態 | 失効/取り消し済み |
| 失効日 | トークンが無効になった日時 |

## イベント仕様

### 1-トークン作成

トークン作成フォームで「トークンを作成」ボタンを押下すると、新しいプロジェクトアクセストークンが作成される。

- `ResourceAccessTokens::CreateService`が実行される
- トークン値は作成直後の1回のみ表示される（セキュリティ上の理由）
- 成功時：トークン値が表示され、アクティブトークン一覧に追加される
- 失敗時：エラーメッセージが表示される

### 2-トークン取り消し

トークン一覧の「取り消し」ボタンを押下すると、選択したトークンが取り消される。

- `ResourceAccessTokens::RevokeService`が実行される
- トークンは論理削除され、非アクティブ一覧に移動する
- 成功時：成功メッセージが表示される
- 失敗時：エラーメッセージが表示される

### 3-トークンローテーション

トークン一覧の「ローテーション」ボタンを押下すると、トークンがローテーションされる。

- `ProjectAccessTokens::RotateService`が実行される
- 既存のトークンは取り消され、新しいトークンが作成される
- 成功時：新しいトークン値が表示される

## データベース更新仕様

### 操作別データベース影響一覧

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| トークン作成 | personal_access_tokens | INSERT | トークンレコード作成 |
| トークン作成 | users | INSERT | ボットユーザー作成 |
| トークン作成 | project_members | INSERT | プロジェクトメンバー追加 |
| トークン取り消し | personal_access_tokens | UPDATE | revoked_at設定 |
| トークンローテーション | personal_access_tokens | INSERT/UPDATE | 新規作成と既存取り消し |

### テーブル別更新項目詳細

#### personal_access_tokens

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | name | フォーム入力値 | トークン名 |
| INSERT | token_digest | トークンのSHA256ハッシュ | 暗号化保存 |
| INSERT | expires_at | フォーム入力値 | NULL許容 |
| INSERT | scopes | 選択されたスコープ配列 | YAML配列 |
| INSERT | user_id | 作成されたボットユーザーID | - |
| UPDATE | revoked_at | 現在日時 | 取り消し時 |

#### users（ボットユーザー）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | username | project_{project_id}_bot_{random} | ボットユーザー名 |
| INSERT | user_type | project_bot | ユーザータイプ |
| INSERT | project_id | プロジェクトID | ボットの所属プロジェクト |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|--------------|----------|
| MSG-118-01 | 成功 | Your new access token has been created. | トークン作成成功時 |
| MSG-118-02 | 成功 | Access token has been revoked. | トークン取り消し成功時 |
| MSG-118-03 | 情報 | This project has no active access tokens. | アクティブトークンなし |
| MSG-118-04 | 情報 | This project has no inactive access tokens. | 非アクティブトークンなし |
| MSG-118-05 | 情報 | Project access token creation is disabled in this group. | グループ設定で作成無効時 |

## 例外処理

| 例外状況 | 対応処理 |
|---------|---------|
| 権限不足 | アクセス拒否画面（403）を表示 |
| プロジェクト未検出 | Not Found画面（404）を表示 |
| トークン作成制限（グループ設定） | 作成フォーム非表示、説明メッセージ表示 |
| トークン名重複 | バリデーションエラーを表示 |

## 備考

- プロジェクトアクセストークンはプロジェクト専用のボットユーザーに紐づく
- トークン値は作成時の1回のみ表示される（セキュリティ上の理由）
- グループの設定でプロジェクトアクセストークンの作成を制限可能
- 非アクティブトークン一覧はバックエンドページネーションで取得
- トークンのローテーションは既存トークンの取り消しと新規作成を一度に行う

---

## コードリーディングガイド

本画面を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

まず、アクセストークンのデータモデルを理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | personal_access_token.rb | `app/models/personal_access_token.rb` | アクセストークンのモデル定義 |
| 1-2 | resource_access_token.rb | `app/models/concerns/resource_access_token.rb` | リソースアクセストークンのconcern |

**読解のコツ**: `token_digest`でトークン値がハッシュ化されて保存される仕組みを理解する。

#### Step 2: エントリーポイントを理解する

処理の起点となるコントローラーを特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | access_tokens_controller.rb | `app/controllers/projects/settings/access_tokens_controller.rb` | 画面表示・トークン操作のエントリーポイント |
| 2-2 | access_tokens_actions.rb | `app/controllers/concerns/access_tokens_actions.rb` | 共通アクションの実装 |

**主要処理フロー**:
1. `index`アクションでトークン一覧を表示
2. `create`アクションでトークン作成
3. `revoke`アクションでトークン取り消し
4. `rotate`アクションでトークンローテーション
5. `inactive`アクションで非アクティブトークン取得（JSON）

#### Step 3: ビューテンプレートを理解する

画面の構成要素を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | index.html.haml | `app/views/projects/settings/access_tokens/index.html.haml` | 画面全体の構成 |

**主要処理フロー**:
- **7行目**: SettingsSectionComponentでセクション表示
- **21行目**: #js-new-access-token-appでVueコンポーネントマウント
- **23-39行目**: CrudComponentでアクティブトークン一覧表示
- **41-46行目**: CrudComponentで非アクティブトークン一覧表示

#### Step 4: サービス層を理解する

ビジネスロジックを担うサービスクラスを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | create_service.rb | `app/services/resource_access_tokens/create_service.rb` | トークン作成のロジック |
| 4-2 | revoke_service.rb | `app/services/resource_access_tokens/revoke_service.rb` | トークン取り消しのロジック |
| 4-3 | rotate_service.rb | `app/services/project_access_tokens/rotate_service.rb` | トークンローテーションのロジック |

### プログラム呼び出し階層図

```
AccessTokensController#index
    │
    ├─ render_access_tokens (from RenderAccessTokens)
    │      ├─ @active_access_tokens
    │      ├─ @active_access_tokens_size
    │      └─ @inactive_access_tokens_size
    │
    └─ render 'index'
           ├─ SettingsSectionComponent
           │      └─ help text
           │
           ├─ #js-new-access-token-app (Vue)
           │
           ├─ CrudComponent (Active tokens)
           │      └─ #js-access-token-table-app (Vue)
           │
           └─ CrudComponent (Inactive tokens)
                  └─ #js-inactive-access-token-table-app (Vue)

AccessTokensController#create
    │
    └─ ResourceAccessTokens::CreateService#execute
           ├─ User.create (bot user)
           ├─ ProjectMember.create
           └─ PersonalAccessToken.create
```

### データフロー図

```
[入力]                    [処理]                         [出力]

トークン作成 ──────────▶ CreateService#execute ──────▶ personal_access_tokens
フォーム                       │                         テーブル
                              │
                              ├──▶ users テーブル（ボットユーザー）
                              │
                              └──▶ project_members テーブル

トークン取り消し ──────▶ RevokeService#execute ──────▶ personal_access_tokens
リクエスト                     │                    (revoked_at更新)
                              │
                              └──▶ users テーブル（ボット無効化）

トークン ────────────▶ RotateService#execute ──────▶ 新トークン作成
ローテーション                  │                    ＋旧トークン取り消し
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| access_tokens_controller.rb | `app/controllers/projects/settings/access_tokens_controller.rb` | コントローラー | リクエスト処理 |
| access_tokens_actions.rb | `app/controllers/concerns/access_tokens_actions.rb` | concern | 共通アクション |
| render_access_tokens.rb | `app/controllers/concerns/render_access_tokens.rb` | concern | トークン表示準備 |
| index.html.haml | `app/views/projects/settings/access_tokens/index.html.haml` | ビュー | 画面テンプレート |
| personal_access_token.rb | `app/models/personal_access_token.rb` | モデル | トークンのデータモデル |
| create_service.rb | `app/services/resource_access_tokens/create_service.rb` | サービス | トークン作成 |
| revoke_service.rb | `app/services/resource_access_tokens/revoke_service.rb` | サービス | トークン取り消し |
| rotate_service.rb | `app/services/project_access_tokens/rotate_service.rb` | サービス | トークンローテーション |
| project_access_token_serializer.rb | `app/serializers/project_access_token_serializer.rb` | シリアライザー | JSON変換 |
| project.rb | `config/routes/project.rb` | 設定 | ルーティング定義 |
