@@ -56,10 +56,9 @@ namespace themis::transaction {
5656/* *
5757 * @brief Mutual-TLS credential bundle for gRPC channel creation.
5858 *
59- * When all three PEM fields are non-empty the adapters will create a channel
60- * backed by `grpc::SslCredentials`; if any field is empty (or the struct is
61- * absent) the adapters fall back to `InsecureChannelCredentials()` and emit a
62- * `spdlog::warn` so the fallback is always visible in logs.
59+ * This path is fail-closed: the adapter will only create a secure gRPC channel
60+ * when all three PEM fields are present and valid. Missing material is rejected
61+ * unless `allow_insecure` is explicitly set for a local test-only override.
6362 *
6463 * @note For production deployments populate from files or a secret manager —
6564 * never hard-code PEM material in source code.
@@ -79,6 +78,13 @@ struct MtlsConfig {
7978 * match the dial address (e.g. `"localhost"` vs `"127.0.0.1"`).
8079 */
8180 std::string target_name_override;
81+ /* *
82+ * @brief Allow the explicit development/test-only insecure fallback.
83+ *
84+ * This must remain false in production. The distributed transaction path
85+ * treats any other usage as a hard error to avoid silent trust degradation.
86+ */
87+ bool allow_insecure = false ;
8288};
8389
8490// ─────────────────────────────────────────────────────────────────────────────
@@ -109,9 +115,9 @@ class GrpcRpcPhase1Adapter {
109115 * @param timeout gRPC deadline applied to every PREPARE call.
110116 * @param mtls Optional mTLS credential bundle. When present and
111117 * all three PEM fields are non-empty, the channel is
112- * created with `grpc::SslCredentials`. Otherwise
113- * `InsecureChannelCredentials()` is used and a
114- * warning is logged .
118+ * created with `grpc::SslCredentials`. Missing PEM
119+ * material is rejected unless `allow_insecure` is
120+ * explicitly set for a local test override .
115121 * @return Callable compatible with
116122 * `DistributedTransactionManager::RpcPhase1Fn`.
117123 */
0 commit comments