Skip to main content

soma_config/
env_registry.rs

1//! Canonical environment-variable registry.
2//!
3//! Keep setup, docs, and plugin option mapping pointed at this table instead of
4//! scattering env-var knowledge across shell snippets and manifests.
5
6#[cfg(test)]
7#[path = "env_registry_tests.rs"]
8mod tests;
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub enum EnvClassification {
12    KeepEnv,
13    ComposeEnv,
14    TrustedOperatorBootstrap,
15}
16
17#[derive(Debug, Clone, Copy, PartialEq, Eq)]
18pub enum RuntimePlacement {
19    HostOnly,
20    ContainerRequired,
21    ComposeInterpolation,
22    Both,
23}
24
25#[derive(Debug, Clone, Copy, PartialEq, Eq)]
26pub enum LegacyBehavior {
27    Canonical,
28    WarnEnvOverride,
29    Advanced,
30}
31
32#[derive(Debug, Clone, Copy, PartialEq, Eq)]
33pub struct EnvKeySpec {
34    pub key: &'static str,
35    pub classification: EnvClassification,
36    pub placement: RuntimePlacement,
37    pub toml_destination: Option<&'static str>,
38    pub legacy_behavior: LegacyBehavior,
39    pub secret: bool,
40    pub plugin_option: Option<&'static str>,
41}
42
43pub const fn spec(
44    key: &'static str,
45    classification: EnvClassification,
46    placement: RuntimePlacement,
47    toml_destination: Option<&'static str>,
48    legacy_behavior: LegacyBehavior,
49    secret: bool,
50    plugin_option: Option<&'static str>,
51) -> EnvKeySpec {
52    EnvKeySpec {
53        key,
54        classification,
55        placement,
56        toml_destination,
57        legacy_behavior,
58        secret,
59        plugin_option,
60    }
61}
62
63pub const ENV_KEY_SPECS: &[EnvKeySpec] = &[
64    spec(
65        "SOMA_PROVIDER_STATE_PATH",
66        EnvClassification::KeepEnv,
67        RuntimePlacement::HostOnly,
68        None,
69        LegacyBehavior::Advanced,
70        false,
71        None,
72    ),
73    spec(
74        "SOMA_GRADUATION_ROOT",
75        EnvClassification::KeepEnv,
76        RuntimePlacement::HostOnly,
77        None,
78        LegacyBehavior::Advanced,
79        false,
80        None,
81    ),
82    spec(
83        "SOMA_PYTHON_BROKER_ALLOWED_PROVIDERS",
84        EnvClassification::KeepEnv,
85        RuntimePlacement::HostOnly,
86        Some("python.broker_allowed_providers"),
87        LegacyBehavior::Advanced,
88        false,
89        None,
90    ),
91    spec(
92        "SOMA_PYTHON_BROKER_ALLOWED_HTTP_HOSTS",
93        EnvClassification::KeepEnv,
94        RuntimePlacement::HostOnly,
95        Some("python.broker_allowed_http_hosts"),
96        LegacyBehavior::Advanced,
97        false,
98        None,
99    ),
100    spec(
101        "SOMA_PYTHON_BROKER_SECRET_NAMES",
102        EnvClassification::KeepEnv,
103        RuntimePlacement::HostOnly,
104        Some("python.broker_secret_names"),
105        LegacyBehavior::Advanced,
106        false,
107        None,
108    ),
109    spec(
110        "SOMA_PYTHON_BROKER_STATE_NAMESPACES",
111        EnvClassification::KeepEnv,
112        RuntimePlacement::HostOnly,
113        Some("python.broker_state_namespaces"),
114        LegacyBehavior::Advanced,
115        false,
116        None,
117    ),
118    spec(
119        "SOMA_PYTHON_BROKER_ALLOW_LOGGING",
120        EnvClassification::KeepEnv,
121        RuntimePlacement::HostOnly,
122        Some("python.broker_allow_logging"),
123        LegacyBehavior::Advanced,
124        false,
125        None,
126    ),
127    spec(
128        "SOMA_PYTHON_BROKER_ALLOW_METRICS",
129        EnvClassification::KeepEnv,
130        RuntimePlacement::HostOnly,
131        Some("python.broker_allow_metrics"),
132        LegacyBehavior::Advanced,
133        false,
134        None,
135    ),
136    spec(
137        "SOMA_PYTHON_BROKER_ALLOW_PROGRESS",
138        EnvClassification::KeepEnv,
139        RuntimePlacement::HostOnly,
140        Some("python.broker_allow_progress"),
141        LegacyBehavior::Advanced,
142        false,
143        None,
144    ),
145    spec(
146        "SOMA_PYTHON_BROKER_CGROUP_ROOT",
147        EnvClassification::KeepEnv,
148        RuntimePlacement::HostOnly,
149        None,
150        LegacyBehavior::Advanced,
151        false,
152        None,
153    ),
154    spec(
155        "SOMA_PYTHON_EXECUTION_PROFILE",
156        EnvClassification::KeepEnv,
157        RuntimePlacement::HostOnly,
158        Some("python.execution_profile"),
159        LegacyBehavior::Advanced,
160        false,
161        None,
162    ),
163    spec(
164        "SOMA_API_URL",
165        EnvClassification::KeepEnv,
166        RuntimePlacement::HostOnly,
167        Some("soma.api_url"),
168        LegacyBehavior::Canonical,
169        false,
170        Some("CLAUDE_PLUGIN_OPTION_SOMA_API_URL"),
171    ),
172    spec(
173        "SOMA_API_KEY",
174        EnvClassification::KeepEnv,
175        RuntimePlacement::HostOnly,
176        Some("soma.api_key"),
177        LegacyBehavior::Canonical,
178        true,
179        Some("CLAUDE_PLUGIN_OPTION_SOMA_API_KEY"),
180    ),
181    spec(
182        "SOMA_PYTHON_ENVIRONMENT_ENABLED",
183        EnvClassification::KeepEnv,
184        RuntimePlacement::HostOnly,
185        Some("python.environment.enabled"),
186        LegacyBehavior::Advanced,
187        false,
188        None,
189    ),
190    spec(
191        "SOMA_PYTHON_ENVIRONMENT_CACHE_ROOT",
192        EnvClassification::KeepEnv,
193        RuntimePlacement::HostOnly,
194        Some("python.environment.cache_root"),
195        LegacyBehavior::Advanced,
196        false,
197        None,
198    ),
199    spec(
200        "SOMA_PYTHON_ENVIRONMENT_UV_PROGRAM",
201        EnvClassification::KeepEnv,
202        RuntimePlacement::HostOnly,
203        Some("python.environment.uv_program"),
204        LegacyBehavior::Advanced,
205        false,
206        None,
207    ),
208    spec(
209        "SOMA_PYTHON_ENVIRONMENT_UV_VERSION",
210        EnvClassification::KeepEnv,
211        RuntimePlacement::HostOnly,
212        Some("python.environment.uv_version"),
213        LegacyBehavior::Advanced,
214        false,
215        None,
216    ),
217    spec(
218        "SOMA_PYTHON_ENVIRONMENT_PYTHON_EXECUTABLE",
219        EnvClassification::KeepEnv,
220        RuntimePlacement::HostOnly,
221        Some("python.environment.python_executable"),
222        LegacyBehavior::Advanced,
223        false,
224        None,
225    ),
226    spec(
227        "SOMA_PYTHON_ENVIRONMENT_RUNTIME_IMPLEMENTATION",
228        EnvClassification::KeepEnv,
229        RuntimePlacement::HostOnly,
230        Some("python.environment.runtime_implementation"),
231        LegacyBehavior::Advanced,
232        false,
233        None,
234    ),
235    spec(
236        "SOMA_PYTHON_ENVIRONMENT_RUNTIME_VERSION",
237        EnvClassification::KeepEnv,
238        RuntimePlacement::HostOnly,
239        Some("python.environment.runtime_version"),
240        LegacyBehavior::Advanced,
241        false,
242        None,
243    ),
244    spec(
245        "SOMA_PYTHON_ENVIRONMENT_RUNTIME_PLATFORM",
246        EnvClassification::KeepEnv,
247        RuntimePlacement::HostOnly,
248        Some("python.environment.runtime_platform"),
249        LegacyBehavior::Advanced,
250        false,
251        None,
252    ),
253    spec(
254        "SOMA_PYTHON_ENVIRONMENT_WHEEL_PLATFORM_TAG",
255        EnvClassification::KeepEnv,
256        RuntimePlacement::HostOnly,
257        Some("python.environment.wheel_platform_tag"),
258        LegacyBehavior::Advanced,
259        false,
260        None,
261    ),
262    spec(
263        "SOMA_PYTHON_ENVIRONMENT_SDK_WHEEL",
264        EnvClassification::KeepEnv,
265        RuntimePlacement::HostOnly,
266        Some("python.environment.sdk_wheel"),
267        LegacyBehavior::Advanced,
268        false,
269        None,
270    ),
271    spec(
272        "SOMA_PYTHON_ENVIRONMENT_SDK_WHEEL_SHA256",
273        EnvClassification::KeepEnv,
274        RuntimePlacement::HostOnly,
275        Some("python.environment.sdk_wheel_sha256"),
276        LegacyBehavior::Advanced,
277        false,
278        None,
279    ),
280    spec(
281        "SOMA_PYTHON_ENVIRONMENT_OFFLINE",
282        EnvClassification::KeepEnv,
283        RuntimePlacement::HostOnly,
284        Some("python.environment.offline"),
285        LegacyBehavior::Advanced,
286        false,
287        None,
288    ),
289    spec(
290        "SOMA_PYTHON_ENVIRONMENT_UPDATE",
291        EnvClassification::KeepEnv,
292        RuntimePlacement::HostOnly,
293        Some("python.environment.update"),
294        LegacyBehavior::Advanced,
295        false,
296        None,
297    ),
298    spec(
299        "SOMA_PYTHON_ENVIRONMENT_POLICY_VERSION",
300        EnvClassification::KeepEnv,
301        RuntimePlacement::HostOnly,
302        Some("python.environment.policy_version"),
303        LegacyBehavior::Advanced,
304        false,
305        None,
306    ),
307    spec(
308        "SOMA_MCP_TOKEN",
309        EnvClassification::TrustedOperatorBootstrap,
310        RuntimePlacement::Both,
311        Some("mcp.api_token"),
312        LegacyBehavior::Canonical,
313        true,
314        Some("CLAUDE_PLUGIN_OPTION_API_TOKEN"),
315    ),
316    spec(
317        "SOMA_SERVER_URL",
318        EnvClassification::KeepEnv,
319        RuntimePlacement::HostOnly,
320        None,
321        LegacyBehavior::WarnEnvOverride,
322        false,
323        Some("CLAUDE_PLUGIN_OPTION_SERVER_URL"),
324    ),
325    spec(
326        "SOMA_MCP_AUTH_MODE",
327        EnvClassification::KeepEnv,
328        RuntimePlacement::Both,
329        Some("mcp.auth.mode"),
330        LegacyBehavior::Canonical,
331        false,
332        Some("CLAUDE_PLUGIN_OPTION_AUTH_MODE"),
333    ),
334    spec(
335        "SOMA_MCP_NO_AUTH",
336        EnvClassification::TrustedOperatorBootstrap,
337        RuntimePlacement::HostOnly,
338        Some("mcp.no_auth"),
339        LegacyBehavior::Advanced,
340        false,
341        Some("CLAUDE_PLUGIN_OPTION_NO_AUTH"),
342    ),
343    spec(
344        "SOMA_NOAUTH",
345        EnvClassification::TrustedOperatorBootstrap,
346        RuntimePlacement::Both,
347        Some("mcp.trusted_gateway"),
348        LegacyBehavior::Advanced,
349        false,
350        None,
351    ),
352    spec(
353        "SOMA_MCP_PUBLIC_URL",
354        EnvClassification::KeepEnv,
355        RuntimePlacement::Both,
356        Some("mcp.auth.public_url"),
357        LegacyBehavior::Canonical,
358        false,
359        Some("CLAUDE_PLUGIN_OPTION_PUBLIC_URL"),
360    ),
361    spec(
362        "SOMA_MCP_GOOGLE_CLIENT_ID",
363        EnvClassification::TrustedOperatorBootstrap,
364        RuntimePlacement::Both,
365        Some("mcp.auth.google_client_id"),
366        LegacyBehavior::Canonical,
367        true,
368        Some("CLAUDE_PLUGIN_OPTION_GOOGLE_CLIENT_ID"),
369    ),
370    spec(
371        "SOMA_MCP_GOOGLE_CLIENT_SECRET",
372        EnvClassification::TrustedOperatorBootstrap,
373        RuntimePlacement::Both,
374        Some("mcp.auth.google_client_secret"),
375        LegacyBehavior::Canonical,
376        true,
377        Some("CLAUDE_PLUGIN_OPTION_GOOGLE_CLIENT_SECRET"),
378    ),
379    spec(
380        "SOMA_MCP_GOOGLE_CALLBACK_PATH",
381        EnvClassification::TrustedOperatorBootstrap,
382        RuntimePlacement::Both,
383        Some("mcp.auth.google_callback_path"),
384        LegacyBehavior::Canonical,
385        false,
386        None,
387    ),
388    spec(
389        "SOMA_MCP_GOOGLE_SCOPES",
390        EnvClassification::TrustedOperatorBootstrap,
391        RuntimePlacement::Both,
392        Some("mcp.auth.google_scopes"),
393        LegacyBehavior::Canonical,
394        false,
395        None,
396    ),
397    spec(
398        "SOMA_MCP_AUTHELIA_ISSUER_URL",
399        EnvClassification::TrustedOperatorBootstrap,
400        RuntimePlacement::Both,
401        Some("mcp.auth.authelia_issuer_url"),
402        LegacyBehavior::Canonical,
403        false,
404        None,
405    ),
406    spec(
407        "SOMA_MCP_AUTHELIA_CLIENT_ID",
408        EnvClassification::TrustedOperatorBootstrap,
409        RuntimePlacement::Both,
410        Some("mcp.auth.authelia_client_id"),
411        LegacyBehavior::Canonical,
412        true,
413        None,
414    ),
415    spec(
416        "SOMA_MCP_AUTHELIA_CLIENT_SECRET",
417        EnvClassification::TrustedOperatorBootstrap,
418        RuntimePlacement::Both,
419        Some("mcp.auth.authelia_client_secret"),
420        LegacyBehavior::Canonical,
421        true,
422        None,
423    ),
424    spec(
425        "SOMA_MCP_AUTHELIA_CALLBACK_PATH",
426        EnvClassification::TrustedOperatorBootstrap,
427        RuntimePlacement::Both,
428        Some("mcp.auth.authelia_callback_path"),
429        LegacyBehavior::Canonical,
430        false,
431        None,
432    ),
433    spec(
434        "SOMA_MCP_AUTHELIA_SCOPES",
435        EnvClassification::TrustedOperatorBootstrap,
436        RuntimePlacement::Both,
437        Some("mcp.auth.authelia_scopes"),
438        LegacyBehavior::Canonical,
439        false,
440        None,
441    ),
442    spec(
443        "SOMA_MCP_GITHUB_CLIENT_ID",
444        EnvClassification::TrustedOperatorBootstrap,
445        RuntimePlacement::Both,
446        Some("mcp.auth.github_client_id"),
447        LegacyBehavior::Canonical,
448        true,
449        None,
450    ),
451    spec(
452        "SOMA_MCP_GITHUB_CLIENT_SECRET",
453        EnvClassification::TrustedOperatorBootstrap,
454        RuntimePlacement::Both,
455        Some("mcp.auth.github_client_secret"),
456        LegacyBehavior::Canonical,
457        true,
458        None,
459    ),
460    spec(
461        "SOMA_MCP_GITHUB_CALLBACK_PATH",
462        EnvClassification::TrustedOperatorBootstrap,
463        RuntimePlacement::Both,
464        Some("mcp.auth.github_callback_path"),
465        LegacyBehavior::Canonical,
466        false,
467        None,
468    ),
469    spec(
470        "SOMA_MCP_GITHUB_SCOPES",
471        EnvClassification::TrustedOperatorBootstrap,
472        RuntimePlacement::Both,
473        Some("mcp.auth.github_scopes"),
474        LegacyBehavior::Canonical,
475        false,
476        None,
477    ),
478    spec(
479        "SOMA_MCP_AUTH_DEFAULT_PROVIDER",
480        EnvClassification::TrustedOperatorBootstrap,
481        RuntimePlacement::Both,
482        Some("mcp.auth.default_provider"),
483        LegacyBehavior::Canonical,
484        false,
485        None,
486    ),
487    spec(
488        "SOMA_MCP_AUTH_ADMIN_EMAIL",
489        EnvClassification::TrustedOperatorBootstrap,
490        RuntimePlacement::Both,
491        Some("mcp.auth.admin_email"),
492        LegacyBehavior::Canonical,
493        false,
494        Some("CLAUDE_PLUGIN_OPTION_AUTH_ADMIN_EMAIL"),
495    ),
496    spec(
497        "SOMA_MCP_HOST",
498        EnvClassification::ComposeEnv,
499        RuntimePlacement::Both,
500        Some("mcp.host"),
501        LegacyBehavior::Canonical,
502        false,
503        None,
504    ),
505    spec(
506        "SOMA_MCP_SERVER_NAME",
507        EnvClassification::ComposeEnv,
508        RuntimePlacement::Both,
509        Some("mcp.server_name"),
510        LegacyBehavior::Canonical,
511        false,
512        None,
513    ),
514    spec(
515        "SOMA_MCP_PORT",
516        EnvClassification::ComposeEnv,
517        RuntimePlacement::Both,
518        Some("mcp.port"),
519        LegacyBehavior::Canonical,
520        false,
521        None,
522    ),
523    spec(
524        "SOMA_MCP_ALLOWED_HOSTS",
525        EnvClassification::ComposeEnv,
526        RuntimePlacement::Both,
527        Some("mcp.allowed_hosts"),
528        LegacyBehavior::Canonical,
529        false,
530        None,
531    ),
532    spec(
533        "SOMA_MCP_ALLOWED_ORIGINS",
534        EnvClassification::ComposeEnv,
535        RuntimePlacement::Both,
536        Some("mcp.allowed_origins"),
537        LegacyBehavior::Canonical,
538        false,
539        None,
540    ),
541    spec(
542        "SOMA_MCP_TRACE_HEADERS",
543        EnvClassification::KeepEnv,
544        RuntimePlacement::Both,
545        Some("mcp.trace_headers"),
546        LegacyBehavior::Canonical,
547        false,
548        Some("CLAUDE_PLUGIN_OPTION_TRACE_HEADERS"),
549    ),
550    spec(
551        "SOMA_MCP_STATIC_TOKEN_WRITE",
552        EnvClassification::TrustedOperatorBootstrap,
553        RuntimePlacement::Both,
554        Some("mcp.static_token_write"),
555        LegacyBehavior::Advanced,
556        false,
557        None,
558    ),
559    spec(
560        "SOMA_MCP_AUTH_BOOTSTRAP_SECRET",
561        EnvClassification::TrustedOperatorBootstrap,
562        RuntimePlacement::Both,
563        Some("mcp.auth.bootstrap_secret"),
564        LegacyBehavior::Canonical,
565        true,
566        None,
567    ),
568    spec(
569        "SOMA_MCP_AUTH_SQLITE_PATH",
570        EnvClassification::TrustedOperatorBootstrap,
571        RuntimePlacement::Both,
572        Some("mcp.auth.sqlite_path"),
573        LegacyBehavior::Canonical,
574        false,
575        None,
576    ),
577    spec(
578        "SOMA_MCP_AUTH_KEY_PATH",
579        EnvClassification::TrustedOperatorBootstrap,
580        RuntimePlacement::Both,
581        Some("mcp.auth.key_path"),
582        LegacyBehavior::Canonical,
583        false,
584        None,
585    ),
586    spec(
587        "SOMA_MCP_AUTH_ACCESS_TOKEN_TTL_SECS",
588        EnvClassification::TrustedOperatorBootstrap,
589        RuntimePlacement::Both,
590        Some("mcp.auth.access_token_ttl_secs"),
591        LegacyBehavior::Canonical,
592        false,
593        None,
594    ),
595    spec(
596        "SOMA_MCP_AUTH_REFRESH_TOKEN_TTL_SECS",
597        EnvClassification::TrustedOperatorBootstrap,
598        RuntimePlacement::Both,
599        Some("mcp.auth.refresh_token_ttl_secs"),
600        LegacyBehavior::Canonical,
601        false,
602        None,
603    ),
604    spec(
605        "SOMA_MCP_AUTH_CODE_TTL_SECS",
606        EnvClassification::TrustedOperatorBootstrap,
607        RuntimePlacement::Both,
608        Some("mcp.auth.auth_code_ttl_secs"),
609        LegacyBehavior::Canonical,
610        false,
611        None,
612    ),
613    spec(
614        "SOMA_MCP_AUTH_REGISTER_REQUESTS_PER_MINUTE",
615        EnvClassification::TrustedOperatorBootstrap,
616        RuntimePlacement::Both,
617        Some("mcp.auth.register_rpm"),
618        LegacyBehavior::Canonical,
619        false,
620        None,
621    ),
622    spec(
623        "SOMA_MCP_AUTH_AUTHORIZE_REQUESTS_PER_MINUTE",
624        EnvClassification::TrustedOperatorBootstrap,
625        RuntimePlacement::Both,
626        Some("mcp.auth.authorize_rpm"),
627        LegacyBehavior::Canonical,
628        false,
629        None,
630    ),
631    spec(
632        "SOMA_MCP_AUTH_MAX_PENDING_OAUTH_STATES",
633        EnvClassification::TrustedOperatorBootstrap,
634        RuntimePlacement::Both,
635        Some("mcp.auth.max_pending_oauth_states"),
636        LegacyBehavior::Canonical,
637        false,
638        None,
639    ),
640    spec(
641        "SOMA_MCP_AUTH_ALLOWED_REDIRECT_URIS",
642        EnvClassification::TrustedOperatorBootstrap,
643        RuntimePlacement::Both,
644        Some("mcp.auth.allowed_client_redirect_uris"),
645        LegacyBehavior::Canonical,
646        false,
647        None,
648    ),
649    spec(
650        "SOMA_MCP_TOKEN_ENCRYPTION_KEY",
651        EnvClassification::TrustedOperatorBootstrap,
652        RuntimePlacement::Both,
653        Some("mcp.auth.token_encryption_key"),
654        LegacyBehavior::Canonical,
655        true,
656        None,
657    ),
658];
659
660pub fn all_specs() -> &'static [EnvKeySpec] {
661    ENV_KEY_SPECS
662}
663
664pub fn spec_for(key: &str) -> Option<&'static EnvKeySpec> {
665    ENV_KEY_SPECS.iter().find(|spec| spec.key == key)
666}
667
668pub fn plugin_option_mappings() -> impl Iterator<Item = (&'static str, &'static str)> {
669    ENV_KEY_SPECS
670        .iter()
671        .filter_map(|spec| spec.plugin_option.map(|option| (option, spec.key)))
672}