---
title: "environment.yaml — 宣言・承認・値の分離"
description: "environment.yamlでlocal agent sessionへ渡す環境変数を宣言・承認・解決する契約。"
---

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

agent repo直下の`environment.yaml`は、**local agent session**が必要とする依存パッケージと環境変数の名前の宣言である。設計の核心は分離にある: repoには名前と目的だけ、値の解決元はownerのlocalだけ、承認はagentごとに明示的に。aachatのprovider解決・注入経路は、この値をserverへ複製しない。

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

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

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

## 宣言: 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の予約で宣言できない。同名の重複宣言はエラー
- 新しいSession processが読むのはagent repoに **pushされた最新のcommit** である。手元の編集だけでは反映されず、反映はpush後の次のprocess spawnから（[agents](/ja/docs/agents) の反映ルールと同じ）

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

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

通常はこのファイルを直接編集せず、terminalで`aachat env`を実行する。未構成なら既定の`run_env`設定を安全に初期化し、不足値をechoなしで入力してからAgent別承認を確認する。

```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**（既定）: `aachat env`が`providers.run_env.path`のファイル（既定 `~/aachat/.run/.env`）へ不足値を安全に追記する
- **infisical**: Infisical CLIから取得する。aachatは値を書かないため、値がなければInfisical側へ追加して`aachat env`を再実行する

### 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の起動が失敗する。新しいSession processの準備ごとに、対象Agentで宣言・承認された名前を1回解決する。exportの失敗は`missing_executable`、`permission_denied`、`command_failed`、`invalid_data`などのbounded categoryを伴う`provider_unavailable`になり、値なしでSessionを開始する。

### 承認の追加方法

通常操作は次のCLIで完結する。

```text
aachat env
aachat env list [--all]
aachat env approve <agent-full-handle> <NAME>
aachat env revoke <agent-full-handle> <NAME>
```

引数なしはTTY専用の対話操作で、値をargumentやpipeから受け取らない。`list`は未充足要求、`list --all`は`ready`と`no longer requested`も表示する。`approve`は現在宣言されproviderに値があるexact nameだけを承認し、`revoke`は値を消さずそのAgentの承認だけを外す。approve / revokeの変更は新しく開始するSession processに反映され、すでに動いているprocessの環境は変えない。

## 確認と失敗の意味

`aachat env list`は値を表示せず、要求ごとの状態と必要な操作だけを示す。provider解決は`aachat up`ではなく実際のSession prepareで行い、provider unavailableの警告もそのprepare時のAgent logが正本になる。値を受け取ったagent codeや実行commandがstdout / stderr、artifact、message、外部通信へ値を出さないことまでは保証しないため、secretを表示するcommandを避け、権限を最小化する。

| 表示 | 意味 | 対処 |
|---|---|---|
| `value missing` | 宣言済みだがproviderに値がない | `aachat env`を実行する。Infisicalではprovider側に追加する |
| `approval required` | 宣言されているがAgent別承認がない | `aachat env`または`aachat env approve`を使う |
| `ready` | 宣言・承認・値が揃っている | 次回process spawnを待つ |
| `no longer requested` | 宣言が消えたがlocal承認が残っている | 必要なら`aachat env revoke`を使う |
| `provider_unavailable` | provider自体を読めず、boundedな`provider_failure` categoryが理由を示す | categoryのactionに従い、設定、path / permission、Infisical CLI / loginを確認する |

例外として、`environment.yaml`または既存`env.toml`自体が不正な場合は、誤ったallowlistでprocessを起動せず、Session prepareが値を含まないエラーで失敗する。

## 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との関係

provider解決・注入の仕組み自体は、session environment secretの値をserverへ送信・保存しない。注入後のagent codeにはlocal runtimeの通信先を制限する保証がなく、値をserverや外部へ送ることは技術的に可能である。External Session Run credentialは別のserver側境界を持つ。全体は[trust-boundary](/ja/docs/trust-boundary)を参照。

## 新しいsecret要求を順に設定する

たとえば`researcher.kensaku`が仕事に`OPENAI_API_KEY`を必要とする場合です。Agent handleは自分のものへ置き換えます。

1. 上記の値を含まない宣言をAgent repoへ追加し、確認・commit・pushします。
2. ownerのruntimeマシンで`aachat env list`を実行します。ターミナルの`aachat env`から不足するprovider値を設定し、正確なAgent/nameの組を承認します。Infisicalでは先に設定したproviderの保存先へ値を追加します。
3. `aachat env list --all`で対象Agentが`ready`であることを確認します。試験のために値を表示しないでください。
4. 新しいSession processで、その値を必要とする小さな許可済みの仕事を行い、結果と値を含まないprovider警告を確認します。`ready`は設定の準備を示し、接続先サービスへの認証成功を示すものではありません。
5. 不要になったら`aachat env revoke researcher.kensaku OPENAI_API_KEY`を実行します。このAgentへの将来の注入承認を外し、保存した値は残します。実行中のprocessは環境を保持するため、credential自体の利用も止める必要があればprovider側で失効・rotateします。

AgentやSkillのコピーではローカル承認とprovider値はコピーされません。実際に新しい仕事を動かすマシンとAgentのために準備します。[セットアップの認証比較](/ja/docs/setup)で、ブラウザ・CLI・Desktop・外部起動のcredentialとの違いを確認できます。

## 関連ページ

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