| 233 | } |
| 234 | |
| 235 | fn prepare_server_config(args: &mut RunArgs, matches: &ArgMatches) -> Result<ServerStartupConfig> { |
| 236 | // Load TOML when explicitly requested, or from the default XDG location |
| 237 | // when that file exists. Missing default config is not an error: runtime |
| 238 | // defaults and OPENSHELL_* env vars are enough for package-managed starts. |
| 239 | let config_path = resolve_config_path(args)?; |
| 240 | let file: Option<ConfigFile> = if let Some(path) = config_path { |
| 241 | Some(config_file::load(&path).map_err(|e| miette::miette!("{e}"))?) |
| 242 | } else { |
| 243 | None |
| 244 | }; |
| 245 | if let Some(file) = file.as_ref() { |
| 246 | merge_file_into_args(args, &file.openshell.gateway, matches); |
| 247 | } |
| 248 | normalize_compute_driver_socket_args(args, matches)?; |
| 249 | |
| 250 | let local_tls = apply_runtime_defaults(args)?; |
| 251 | let guest_tls = local_tls.as_ref().map(GuestTlsPaths::from); |
| 252 | let local_jwt = defaults::complete_local_jwt_config()?; |
| 253 | |
| 254 | let bind = SocketAddr::new(args.bind_address, args.port); |
| 255 | |
| 256 | let has_client_ca = args.tls_client_ca.is_some(); |
| 257 | let has_oidc = args.oidc_issuer.is_some(); |
| 258 | let mtls_auth_enabled = resolve_mtls_auth_enabled(args, matches, file.as_ref()); |
| 259 | |
| 260 | if args.disable_tls && has_client_ca { |
| 261 | return Err(miette::miette!( |
| 262 | "--disable-tls and --tls-client-ca are mutually exclusive. Client certificate verification requires that TLS be enabled." |
| 263 | )); |
| 264 | } |
| 265 | if mtls_auth_enabled && args.disable_tls { |
| 266 | return Err(miette::miette!( |
| 267 | "mTLS user authentication requires TLS. Remove --disable-tls or disable --enable-mtls-auth." |
| 268 | )); |
| 269 | } |
| 270 | if mtls_auth_enabled && !has_client_ca { |
| 271 | return Err(miette::miette!( |
| 272 | "mTLS user authentication requires --tls-client-ca so client certificates can be verified." |
| 273 | )); |
| 274 | } |
| 275 | if mtls_auth_enabled |
| 276 | && matches!( |
| 277 | effective_single_driver(args), |
| 278 | Some(ComputeDriverKind::Kubernetes) |
| 279 | ) |
| 280 | { |
| 281 | return Err(miette::miette!( |
| 282 | "mTLS user authentication is not supported with the Kubernetes compute driver. Configure OIDC or a trusted fronting proxy for user authentication." |
| 283 | )); |
| 284 | } |
| 285 | |
| 286 | let tls = if args.disable_tls { |
| 287 | None |
| 288 | } else { |
| 289 | let cert_path = args.tls_cert.clone().ok_or_else(|| { |
| 290 | miette::miette!( |
| 291 | "--tls-cert is required when TLS is enabled (use --disable-tls to skip)" |
| 292 | ) |