Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 52 additions & 3 deletions docs/user/cli-reference/03-env.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,17 +84,33 @@ devbase env get AWS_PROFILE
環境変数を削除します。

```
devbase env delete KEY
devbase env delete KEY [-p]
```

| オプション | 説明 |
|-----------|------|
| `-p` | プロジェクト設定から削除(デフォルトはグローバル)。`projects/<name>` 配下で実行してください |

```bash
# グローバルから削除
devbase env delete OLD_API_KEY

# カレントプロジェクトの設定から削除
devbase env delete GCP_ACTIVE_PROFILE -p
```

## `devbase env edit`

デフォルトエディタで `.env` ファイルを開きます。
デフォルトエディタで設定を開きます。設定が暗号化されている場合は、復号した内容を一時ファイルで編集し、保存時に再暗号化します。

```
devbase env edit
devbase env edit [-p]
```

| オプション | 説明 |
|-----------|------|
| `-p` | カレントプロジェクトの設定を開く(デフォルトはグローバル)。`projects/<name>` 配下で実行してください |

## `devbase env project`

プロジェクト固有の環境変数を対話式で設定します。
Expand All @@ -103,6 +119,39 @@ devbase env edit
devbase env project
```

## `devbase env keygen`

設定の暗号化に使う devbase 専用の age 鍵を生成します。鍵ファイルは `0600`、置き場のディレクトリは `0700` で作成されます。

```
devbase env keygen [--force] [-y|--yes]
```

| オプション | 説明 |
|-----------|------|
| `--force` | 既存の鍵を作り直す。**旧鍵でしか復号できない機密は失われます** |
| `-y`, `--yes` | `--force` 時の確認プロンプトを省略(CI 等での自動実行用) |

鍵の場所は次のとおりで、コマンドラインからは指定できません(生成先と復号時の探索先を必ず一致させるため)。別の場所に置きたい場合は `DEVBASE_AGE_KEY_FILE` を設定してから実行します。

| 指定 | 鍵ファイルのパス |
|-----|-----------------|
| 既定 | `~/.config/devbase/age/keys.txt`(`XDG_CONFIG_HOME` があればその配下) |
| `DEVBASE_AGE_KEY_FILE` | 指定したパスをそのまま使用 |

```bash
# 既定の場所に生成する(既に鍵があれば公開鍵を表示するだけで何もしない)
devbase env keygen

# 置き場を変えて生成する
DEVBASE_AGE_KEY_FILE=~/keys/devbase-age.txt devbase env keygen

# 既存の鍵を捨てて作り直す(確認プロンプトあり)
devbase env keygen --force
```

> **鍵のバックアップは必須です。** この鍵を失うと、暗号化した機密は誰にも復号できません(devbase 側にも復旧手段はありません)。生成後に表示される鍵ファイルを、パスワード管理ツールなど端末とは別の場所へ必ず複製してください。鍵は全ワークスペース共通のため、`--force` で作り直すと他のワークスペースで暗号化した機密も復号できなくなります。

## `devbase env export`

複数プロジェクトの `.env` 群を暗号化したまま 1 つのバンドルにまとめて書き出します。
Expand Down
2 changes: 1 addition & 1 deletion docs/user/cli-reference/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ devbase の全コマンドの構文、オプション、使用例をまとめた
|---------|------|
| [トップレベルコマンド](01-toplevel.md) | `init` / `status` / `bin/rc` |
| [project グループ](02-project.md) | コンテナのライフサイクル管理・一覧(`up` / `down` / `login` / `ps` / `logs` / `scale` / `build` / `rebuild` / `list`)と非推奨の `container` グループ |
| [env グループ](03-env.md) | 環境変数の管理(`init` / `sync` / `list` / `set` / `get` / `delete` / `edit` / `project` / `export` / `import`) |
| [env グループ](03-env.md) | 環境変数の管理(`init` / `sync` / `list` / `set` / `get` / `delete` / `edit` / `project` / `keygen` / `export` / `import`) |
| [plugin グループ](04-plugin.md) | プラグインの管理(`list` / `install` / `uninstall` / `update` / `info` / `sync` / `migrate` / `repo *`) |
| [snapshot グループ](05-snapshot.md) | スナップショットの管理(`create` / `list` / `restore` / `copy` / `delete` / `rotate`) |

Expand Down
11 changes: 10 additions & 1 deletion etc/_devbase
Original file line number Diff line number Diff line change
Expand Up @@ -245,9 +245,18 @@ _devbase() {
'1:assignment:' \
'--project[Set in project .env]' '-p[Set in project .env]'
;;
get|delete)
get)
_arguments '1:key:'
;;
delete)
_arguments \
'1:key:' \
'--project[Delete from project .env]' '-p[Delete from project .env]'
;;
edit)
_arguments \
'--project[Edit project .env]' '-p[Edit project .env]'
;;
export)
_arguments \
'1:dest:_files' \
Expand Down
2 changes: 1 addition & 1 deletion etc/devbase-completion.bash
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ _devbase_completions() {
COMPREPLY=($(compgen -W "--global -g --project -p --reveal -r --keys -k" -- "$cur"))
fi
;;
set)
set|delete|edit)
if [[ "$cur" == -* ]]; then
COMPREPLY=($(compgen -W "--project -p" -- "$cur"))
fi
Expand Down
6 changes: 4 additions & 2 deletions issues/plan35.md
Original file line number Diff line number Diff line change
Expand Up @@ -268,8 +268,8 @@ release branch: `release/PLAN35` / base branch: `main`
| PR # | branch 名 | 概要 | 対応する段階 | 依存 | 並行可否 |
|---|---|---|---|---|---|
| 1 | `feature/PLAN35-secret-store` | 秘密ストアの抽象層 + age 実装 + 鍵生成 (`devbase env keygen`) と受信者管理 | 段階 1 | なし | ○ |
| 2 | `feature/PLAN35-env-commands` | 設定操作コマンド群 (`init`/`sync`/`set`/`get`/`delete`/`edit`/`list`) の保存先切替、`encrypt`/`decrypt` 移行コマンド | 段階 2・5(移行) | PR1 | × |
| 3 | `feature/PLAN35-runtime` | 起動ラッパーの機密読み込み廃止、`env exec` によるホスト側処理への注入、変数名のみを列挙する構成生成、プロジェクト構成の移行 | 段階 3・4 | PR2 | × |
| 2 | `feature/PLAN35-env-commands` | 設定操作コマンド群 (`init`/`sync`/`set`/`get`/`delete`/`edit`/`list`) の保存先切替 | 段階 2 | PR1 | × |
| 3 | `feature/PLAN35-runtime` | 起動ラッパーの機密読み込み廃止、`env exec` によるホスト側処理への注入、変数名のみを列挙する構成生成、`encrypt`/`decrypt` による移行 | 段階 3・4・5(移行) | PR2 | × |
| 4 | `feature/PLAN35-ops-docs` | `rekey` / `doctor`、除外設定の修正、取り込みバックアップの暗号化、ドキュメント | 段階 5(残り) | PR3 | × |

段階 6 (SOPS を差し替え先として実装) は本 release のスコープ外とし、運用要件が出た時点で別 plan に切り出す。
Expand All @@ -278,6 +278,8 @@ release branch: `release/PLAN35` / base branch: `main`

4 本すべてが `lib/devbase/env/` の同一層を触るため、worktree による並行開発の利得よりコンフリクト解消のコストが上回る。PR1 の抽象層が確定しないと PR2 の保存先切替は書けず、PR2 の読み込み経路が確定しないと PR3 の注入経路は書けない。したがって「PR n を release へ merge → PR n+1 を release から切る」の直列で進める。

移行コマンド (`encrypt` / `decrypt`) は当初 PR2 に置く想定だったが、PR3 へ移した。共通の機密を暗号化した時点で平文ファイルは消えるため、コンテナ構成がそのファイルを参照したままだと起動が失敗する。移行手段と、それを受け止める起動経路の変更は同じ PR に入っていないと、その PR だけを取り込んだ状態が壊れる。

### 11.2 ホスト側で機密を必要とする処理の洗い出し(段階 3 の必須事前作業)

`bin/devbase` が `set -a; source $DEVBASE_ROOT/.env` で読み込んだ値に依存するホスト側処理は、実測で以下の 2 系統のみだった。
Expand Down
9 changes: 8 additions & 1 deletion lib/devbase/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,10 +275,17 @@ def _add_env_parser(subparsers):
env_get = env_sub.add_parser('get', help='Get a variable')
env_get.add_argument('key', help='Variable name')

# delete / edit の --project は set と対。設定が暗号化されると利用者がエディタで
# 直接開いて消せなくなるため、プロジェクト設定を CLI から掃除する経路を残す。
env_delete = env_sub.add_parser('delete', help='Delete a variable')
env_delete.add_argument('key', help='Variable name')
env_delete.add_argument('--project', '-p', action='store_true',
help='Delete from project .env')

env_edit = env_sub.add_parser('edit', help='Open .env in editor')
env_edit.add_argument('--project', '-p', action='store_true',
help='Edit project .env')

env_sub.add_parser('edit', help='Open .env in editor')
env_sub.add_parser('project', help='Setup project-specific variables')

# 生成先を選ぶオプションは置かない。復号側は $DEVBASE_AGE_KEY_FILE か既定パスしか
Expand Down
Loading