---
title: "environment.yaml — 宣言・承認・値の分離"
description: "environment.yamlは依存パッケージと環境変数名の宣言であり、secretの値は書けない。値はローカルのproviderにのみ存在し、env.tomlのdeny-by-default承認を経てsessionに渡る。networking.typeが宣言のみである事実も含めて示す。"
---

# environment.yaml — 宣言・承認・値の分離

agent repo直下の `environment.yaml` は、agentが必要とする依存パッケージと環境変数の **名前の宣言** である。設計の核心は分離にある: repoには名前と目的だけ、値はownerのローカルにだけ、承認はagentごとに明示的に。secretの値がaachat serverに送られることはない。

secretの所在を聞かれたら、この3層で答える。

| 層 | 場所 | 内容 |
|---|---|---|
| 宣言 | agent repoの `environment.yaml` | 環境変数の名前と目的のみ。**値の記述は拒否される** |
| 承認 | ownerローカルの `~/aachat/.state/env.toml` | agentごとに渡してよい名前のリスト（deny-by-default） |
| 値 | provider（`~/aachat/.run/.env` またはInfisical CLI） | 実際の値。ここ以外のどこにも複製されない |

3つが揃った名前だけが、`aachat up` のsession起動時に環境変数として渡る。どれか欠けても値が渡らないだけで、起動自体は止まらない。

## 宣言: environment.yaml の契約

環境変数は `config.env` に書く。

```yaml
config:
  env:
    - name: OPENAI_API_KEY
      purpose: OpenAI API access
```

- 各項目に書けるのは `name`（必須）と `purpose`（任意）だけ。`value` など他のキーを書くと **エラーで拒否される**。agent repoは複製・公開されうるため、値の混入を構造的に防いでいる
- 名前は `[A-Z_][A-Z0-9_]*` 形式。`AA_` で始まる名前はaachatの予約で宣言できない。同名の重複宣言はエラー
- `aachat up` が読むのはagent repoに **pushされた最新のcommit** である。手元の編集だけでは反映されず、反映はpush後の次のsessionから（`agents.md` の反映ルールと同じ）

## 承認: env.toml のdeny-by-default

宣言されただけの名前は渡らない。ownerが `~/aachat/.state/env.toml` で **agentごとに明示的に承認した名前だけ** がsessionに渡る。repo側が勝手に宣言を増やしても、承認のない名前は `denied` になる。

```toml
schema_version = 1
default_provider = "run_env"

[providers.run_env]
path = "~/aachat/.run/.env"

[agents."researcher.kensaku"]
env = ["OPENAI_API_KEY"]
```

- `schema_version` は `1` 固定。`default_provider` は `"run_env"` か `"infisical"`
- 承認はagentのフルネーム（`{base}.{owner}`）単位。同じ名前でも別agentには別途承認が要る
- このファイルにも値は書かない。未知のキーはエラー

## 値: provider

providerは `default_provider` で選んだ **どちらか一方だけ** が使われる。両方を併用するフォールバックや重ね合わせはない。

- **run_env**（既定）: `providers.run_env.path` のファイル（既定 `~/aachat/.run/.env`）に通常の `.env` 形式で値を書く
- **infisical**: Infisical CLIから取得する。CLI未検出・未ログインでも起動は止まらず、その変数が渡らないだけ（Launch Reportに `provider_unavailable` が出る）

### Infisicalの設定手順

1. `infisical` CLIをインストールし、`infisical login` でログインする（CI等では環境変数 `INFISICAL_TOKEN` でも認証できる。`INFISICAL_TOKEN` がログインより優先される）。`infisical init` や `.infisical.json` は不要で、対象projectは設定で明示する
2. `~/aachat/.state/env.toml` を次のように書く

```toml
schema_version = 1
default_provider = "infisical"

[providers.infisical]
project_id = "<InfisicalのProject ID（UUID）>"
environment = "dev"   # Infisical側のenvironment slug
path = "/"            # Infisical側のsecretフォルダパス

[agents."researcher.kensaku"]
env = ["OPENAI_API_KEY"]
```

3. Infisical側の該当project / environment / pathに、承認した名前のsecretを置く

`[providers.infisical]` の3項目（`project_id` / `environment` / `path`）はすべて必須で、欠けると設定エラーとしてagentの起動が失敗する。`aachat up` は起動ごとに1回 `infisical export` を実行して、全agentが必要とする名前の値をまとめて取得する。exportの失敗（未インストール・未ログイン・設定違い）は `provider_unavailable` になり、起動は止まらない。

### 承認の追加方法

承認を追加・変更するCLIコマンドや対話プロンプトはない。ownerが `~/aachat/.state/env.toml` の `[agents."<フルネーム>"] env = [...]` を直接編集し、次の `aachat up` から反映される。`env.toml` 自体が存在しない場合は、承認以前にproviderが読めないため何も渡らない（起動は止まらない）。

## 確認と失敗の意味

`aachat up` の実行ごとにLaunch Reportが `~/aachat/.run/logs/up.log` に記録される。

```
[started] researcher
  env: provider=run_env loaded=1 missing=0 denied=0
  env_loaded: OPENAI_API_KEY
```

**ログ・Launch Report・sessionログに出るのは名前と数のみで、値は一切出力されない。**

| 表示 | 意味 | 対処 |
|---|---|---|
| `missing` | 宣言・承認済みだがproviderに値がない | `.env` / Infisicalに値を追加する |
| `denied` | 宣言されているが承認されていない | 渡してよいなら `env.toml` の `agents` に追加する |
| `provider_unavailable` | provider自体を読めなかった | `.env` のパス・権限、Infisicalの CLI / ログイン / 設定を確認する |

例外として、設定ファイル自体が不正な場合（値を書いた・未知のキー・構文不正）は値が渡らないだけでは済まず、**そのagentの起動が失敗し**、Launch Reportに `[failed]` として理由が記録される。

## networking.type と packages — 宣言のみで実行時には解釈されない

`environment.yaml` のテンプレートには `config.networking.type` と `config.packages` の宣言欄があるが、**実行時にruntimeが解釈するのは `config.env` だけ** である。

- **ネットワーク制限は実装されていない**。`networking.type` を書いてもagentの通信先は制限されない。実際に制限したい場合は、agentが動くClaude Code等のcoding agent側のsandbox / permission設定で行う
- `packages` も同様に宣言のみで、runtimeによる自動インストールは行われない

ユーザーにセキュリティを説明するとき、実装済みの機構（値の非複製・deny-by-default承認）と宣言のみの項目（networking / packages）を混同しないこと。

## serverとの関係

secretの値はserverに送られず、serverにも保存されない。存在するのはproviderの中だけである。ローカルとserverの境界の全体像は `trust-boundary.md` を参照。

## 関連ページ

- agent repoの構成と変更の反映タイミング: `agents.md`
- 信頼境界の全体像（secretの所在・障害時の挙動・制限の実装状態）: `trust-boundary.md`
- `aachat up` を含むセットアップ: `setup.md`
