问题
当前 IAevatarSecretStore(AevatarSecretsStore)将 secrets 写入本地文件 ~/.aevatar/secrets.json,且通过 AddAevatarConfig() 在所有宿主中统一注册。Mainnet 项目(Aevatar.Mainnet.Host.Api)也继承了这一行为,导致生产环境存在将 secrets 落地到本地文件的风险。
方案
不依赖运行时配置:只要入口是 mainnet 项目,就彻底切断本地文件 secrets store 的注册路径。
具体做法
- 新建
EnvironmentSecretsStore(src/Aevatar.Configuration/):实现 IAevatarSecretsStore,只从 IConfiguration(含 AEVATAR_ 环境变量)读取,Set/Remove 直接抛 InvalidOperationException
AddAevatarConfig() 拆分:提供一个 AddAevatarConfig(bool allowLocalFileStore = true) 重载,false 时注册 EnvironmentSecretsStore 替代 AevatarSecretsStore
AevatarConfigLoader 同步保护:allowLocalFileStore=false 时跳过 secrets.json 的加载
- Mainnet 项目显式调用:
Aevatar.Mainnet.Host.Api 的 bootstrap 链路中传入 allowLocalFileStore: false,其他项目(localnet、tools、demos)保持默认行为
关键约束
- mainnet 仍可通过
AEVATAR_ 环境变量注入 secrets(部署平台管理,不落地)
Set/Remove 在 mainnet 必须炸在调用点,不允许静默忽略
- 不修改
IAevatarSecretsStore 接口本身
问题
当前
IAevatarSecretStore(AevatarSecretsStore)将 secrets 写入本地文件~/.aevatar/secrets.json,且通过AddAevatarConfig()在所有宿主中统一注册。Mainnet 项目(Aevatar.Mainnet.Host.Api)也继承了这一行为,导致生产环境存在将 secrets 落地到本地文件的风险。方案
不依赖运行时配置:只要入口是 mainnet 项目,就彻底切断本地文件 secrets store 的注册路径。
具体做法
EnvironmentSecretsStore(src/Aevatar.Configuration/):实现IAevatarSecretsStore,只从IConfiguration(含AEVATAR_环境变量)读取,Set/Remove直接抛InvalidOperationExceptionAddAevatarConfig()拆分:提供一个AddAevatarConfig(bool allowLocalFileStore = true)重载,false时注册EnvironmentSecretsStore替代AevatarSecretsStoreAevatarConfigLoader同步保护:allowLocalFileStore=false时跳过secrets.json的加载Aevatar.Mainnet.Host.Api的 bootstrap 链路中传入allowLocalFileStore: false,其他项目(localnet、tools、demos)保持默认行为关键约束
AEVATAR_环境变量注入 secrets(部署平台管理,不落地)Set/Remove在 mainnet 必须炸在调用点,不允许静默忽略IAevatarSecretsStore接口本身