genesis-flow 1.0.6__py3-none-any.whl → 1.0.8__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: genesis-flow
3
- Version: 1.0.6
3
+ Version: 1.0.8
4
4
  Summary: Genesis-Flow: MLflow v3.1.4 compatible fork for Genesis platform
5
5
  Maintainer-email: Databricks <mlflow-oss-maintainers@googlegroups.com>
6
6
  License: Copyright 2018 Databricks, Inc. All rights reserved.
@@ -378,6 +378,10 @@ poetry install --with dev
378
378
 
379
379
  ```python
380
380
  import mlflow
381
+ import os
382
+
383
+ # Optional: Disable secure model loading if you encounter loading issues
384
+ # os.environ["MLFLOW_ENABLE_SECURE_MODEL_LOADING"] = "false"
381
385
 
382
386
  # Set tracking URI (supports file, PostgreSQL, etc.)
383
387
  mlflow.set_tracking_uri("file:///path/to/mlruns")
@@ -504,7 +508,7 @@ export MLFLOW_POSTGRES_USERNAME="user@tenant"
504
508
  export GOOGLE_APPLICATION_CREDENTIALS="/path/to/service-account.json"
505
509
 
506
510
  # Security configuration
507
- export MLFLOW_ENABLE_SECURE_MODEL_LOADING=true
511
+ export MLFLOW_ENABLE_SECURE_MODEL_LOADING=true # Can be set to false if model loading fails
508
512
  export MLFLOW_STRICT_INPUT_VALIDATION=true
509
513
  ```
510
514
 
@@ -761,11 +765,32 @@ entry_points = {
761
765
 
762
766
  - ✅ **Input validation** against injection attacks
763
767
  - ✅ **Path traversal protection** for file operations
764
- - ✅ **Secure pickle loading** with restricted unpickling
768
+ - ✅ **Secure pickle loading** with restricted unpickling (configurable via `MLFLOW_ENABLE_SECURE_MODEL_LOADING`)
765
769
  - ✅ **Authentication hooks** for enterprise SSO integration
766
770
  - ✅ **Audit logging** for compliance requirements
767
771
  - ✅ **Encrypted communication** support
768
772
 
773
+ #### Secure Model Loading Configuration
774
+
775
+ Genesis-Flow includes enhanced security for model loading that prevents arbitrary code execution from untrusted pickle files. This feature can be configured using the `MLFLOW_ENABLE_SECURE_MODEL_LOADING` environment variable:
776
+
777
+ ```bash
778
+ # Enable secure model loading (default - recommended for production)
779
+ export MLFLOW_ENABLE_SECURE_MODEL_LOADING=true
780
+
781
+ # Disable secure model loading (use with caution - only for trusted models)
782
+ export MLFLOW_ENABLE_SECURE_MODEL_LOADING=false
783
+ ```
784
+
785
+ **When to disable secure loading:**
786
+ - When loading legacy models that contain custom classes not in the allowlist
787
+ - During development with trusted model sources
788
+ - When migrating from standard MLflow with complex custom models
789
+
790
+ **Security implications:**
791
+ - When enabled: Only whitelisted classes can be deserialized, preventing arbitrary code execution
792
+ - When disabled: Standard cloudpickle behavior, any Python object can be loaded (potential security risk)
793
+
769
794
  ### Security Best Practices
770
795
 
771
796
  1. **Use MongoDB authentication** in production
@@ -1,4 +1,4 @@
1
- genesis_flow-1.0.6.dist-info/licenses/LICENSE.txt,sha256=Y5U1Xebzka__NZlqMPtBsYm0mRpMtUmTrONatpoL-ig,11382
1
+ genesis_flow-1.0.8.dist-info/licenses/LICENSE.txt,sha256=Y5U1Xebzka__NZlqMPtBsYm0mRpMtUmTrONatpoL-ig,11382
2
2
  mlflow/__init__.py,sha256=-_r__N5Afed81pLVtr2wKbHQIA0aj9u9n_7kWGxLWi4,11194
3
3
  mlflow/__main__.py,sha256=_PcdoxKehR_a2MI6GqBfzYzRCXZhVyDCSdbxDWVlWd4,39
4
4
  mlflow/cli.py,sha256=f1ObrWZ03HgRiRoVEE1Gffe-dGcSY7CxJyEFgb5VUMM,26137
@@ -311,7 +311,7 @@ mlflow/pyfunc/backend.py,sha256=5-tjUnY1nPecoNCxFjhLjPbhHsDGR9_0P9ym02_J3HA,2077
311
311
  mlflow/pyfunc/context.py,sha256=nXQcP61XR7cKx6CeFsdAM4TD-NOrIEt_GQSfJ990xc4,3007
312
312
  mlflow/pyfunc/dbconnect_artifact_cache.py,sha256=-Ji_GU-NLvGyxYrOFhR81SYn4E6ykiFcZl35hRQ9c6A,5769
313
313
  mlflow/pyfunc/mlserver.py,sha256=ER7tXcOZ-tAUblMbgqPVT2E8BtBGH1HXLSSOmsQUB_c,1271
314
- mlflow/pyfunc/model.py,sha256=aDwfNKgoVw4sl9W0WZfOa9st5WTsSF3NWbF5TgM3bDs,64507
314
+ mlflow/pyfunc/model.py,sha256=by6xBLOmu1D1B0sH9B2LpVe6TjS14D0sStE60iJ9ofk,65686
315
315
  mlflow/pyfunc/spark_model_cache.py,sha256=sFFAi-LxXEJdqk8szm32XxK5IFsISpxxVjAWjWbHZ1U,2091
316
316
  mlflow/pyfunc/stdin_server.py,sha256=gNkWxlCz3KLu6jvZNeNytmKAy4j5gIXOpIehrizm43s,1362
317
317
  mlflow/pyfunc/loaders/__init__.py,sha256=W3Bny093PoREOCqavIzKJ3lYeZUBXhxk3EDkCqc_lBc,276
@@ -613,7 +613,7 @@ mlflow/utils/requirements_utils.py,sha256=79BL9iFqg9H4VRYiqk-gTLlrfLyUY7KVG4BDV8
613
613
  mlflow/utils/rest_utils.py,sha256=R5MZk0Ck358VeW-DKqpfSyDHbWjg_slQTpRfr4ZLDLM,26664
614
614
  mlflow/utils/search_logged_model_utils.py,sha256=JWczQxogo4u9Gr3gfoSVf7tVny1e-rxfAchh3Vqy6RU,4289
615
615
  mlflow/utils/search_utils.py,sha256=PgXtwlViHvmahY63otykh5iJVW0PR9DIwetrvCCBw2U,86142
616
- mlflow/utils/secure_loading.py,sha256=yJpKwrhzINmo0yVdp6fXvbNkZu_HEdwyB8deljGDXxk,10095
616
+ mlflow/utils/secure_loading.py,sha256=X4AdKHDkIzMvriFwCvTPLhN-yPbqs6dgUOB244Q_gRM,11892
617
617
  mlflow/utils/security_validation.py,sha256=cLBrLNOoVJuAffO677v0m_v4i-01v7aLk-sJk87mpkQ,12830
618
618
  mlflow/utils/server_cli_utils.py,sha256=gbT5CVkOLorSw-y8bnNSBEP9mClcVTagtTN5SK5Azhw,2381
619
619
  mlflow/utils/spark_utils.py,sha256=zUbQIRAtwyU3rDJK8m7v42KO2TSGn28Coe_UYBEhIWA,395
@@ -641,8 +641,8 @@ mlflow/utils/autologging_utils/metrics_queue.py,sha256=bwpMX7Go6xFxrpYROi6rDBdVt
641
641
  mlflow/utils/autologging_utils/safety.py,sha256=IwbTbusyE87Hc4qkhhvMikoaZqX9kpr972FWS2B8goc,51465
642
642
  mlflow/utils/autologging_utils/versioning.py,sha256=2hSN4KXFWEJCcopDdLG6BiPeqSoqjETeNMuUBsCCwlI,3762
643
643
  mlflow/utils/import_hooks/__init__.py,sha256=werje98Woelkbwrhtlb8wmRdt3RtiL--LqGru7Xh3YU,13589
644
- genesis_flow-1.0.6.dist-info/METADATA,sha256=_ofi_wrmOHLBu-0gjHwRW97dMrrVpnksdsLhUr1WrlU,33401
645
- genesis_flow-1.0.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
646
- genesis_flow-1.0.6.dist-info/entry_points.txt,sha256=YZZiTHSYQpv8vou6gdqWI17piK9Pm0P3BmZ-xepUtnw,449
647
- genesis_flow-1.0.6.dist-info/top_level.txt,sha256=wm8UqYyUHI21EvrTDHb3eYICy0dOVDLBhAL-jp5zbuI,7
648
- genesis_flow-1.0.6.dist-info/RECORD,,
644
+ genesis_flow-1.0.8.dist-info/METADATA,sha256=tam5UxyijS6-7TN_92L9-e7BHQKsKtpyNoMBhCCNGLw,34630
645
+ genesis_flow-1.0.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
646
+ genesis_flow-1.0.8.dist-info/entry_points.txt,sha256=YZZiTHSYQpv8vou6gdqWI17piK9Pm0P3BmZ-xepUtnw,449
647
+ genesis_flow-1.0.8.dist-info/top_level.txt,sha256=wm8UqYyUHI21EvrTDHb3eYICy0dOVDLBhAL-jp5zbuI,7
648
+ genesis_flow-1.0.8.dist-info/RECORD,,
mlflow/pyfunc/model.py CHANGED
@@ -819,27 +819,52 @@ def _maybe_compress_cloudpickle_dump(python_model, path, compression):
819
819
 
820
820
  def _maybe_decompress_cloudpickle_load(path, compression):
821
821
  """
822
- Genesis-Flow: Secure model loading with safety checks.
822
+ Genesis-Flow: Model loading with optional security checks.
823
+
824
+ Security can be disabled by setting MLFLOW_ENABLE_SECURE_MODEL_LOADING=false
825
+ Default behavior is secure loading (enabled).
823
826
  """
824
- from mlflow.utils.secure_loading import SecureModelLoader, SecurityError
827
+ import os
828
+ import cloudpickle
825
829
 
826
830
  _check_compression_supported(compression)
827
831
 
828
- # For compressed files, we need to decompress first then load securely
829
- if compression and compression != "none":
830
- import tempfile
831
- file_open = _COMPRESSION_INFO.get(compression, {}).get("open", open)
832
- with file_open(path, "rb") as compressed_f:
833
- with tempfile.NamedTemporaryFile(delete=False) as temp_f:
834
- temp_f.write(compressed_f.read())
835
- temp_path = temp_f.name
836
- try:
837
- return SecureModelLoader.safe_cloudpickle_load(temp_path)
838
- finally:
839
- os.unlink(temp_path)
832
+ # Check if secure loading should be used (default: true for security)
833
+ use_secure_loading = os.getenv('MLFLOW_ENABLE_SECURE_MODEL_LOADING', 'true').lower() != 'false'
834
+
835
+ if use_secure_loading:
836
+ # Use secure loading for enhanced security
837
+ from mlflow.utils.secure_loading import SecureModelLoader, SecurityError
838
+
839
+ # For compressed files, we need to decompress first then load securely
840
+ if compression and compression != "none":
841
+ import tempfile
842
+ file_open = _COMPRESSION_INFO.get(compression, {}).get("open", open)
843
+ with file_open(path, "rb") as compressed_f:
844
+ with tempfile.NamedTemporaryFile(delete=False) as temp_f:
845
+ temp_f.write(compressed_f.read())
846
+ temp_path = temp_f.name
847
+ try:
848
+ return SecureModelLoader.safe_cloudpickle_load(temp_path)
849
+ finally:
850
+ os.unlink(temp_path)
851
+ else:
852
+ # Direct secure loading for uncompressed files
853
+ return SecureModelLoader.safe_cloudpickle_load(path)
840
854
  else:
841
- # Direct secure loading for uncompressed files
842
- return SecureModelLoader.safe_cloudpickle_load(path)
855
+ # Use standard cloudpickle loading (original MLflow behavior)
856
+ # Warning: This bypasses security checks and may allow arbitrary code execution
857
+ import logging
858
+ logger = logging.getLogger(__name__)
859
+ logger.warning(
860
+ "Secure model loading is disabled. Models will be loaded without security checks. "
861
+ "This may allow arbitrary code execution. Set MLFLOW_ENABLE_SECURE_MODEL_LOADING=true "
862
+ "to enable secure loading."
863
+ )
864
+
865
+ file_open = _COMPRESSION_INFO.get(compression, {}).get("open", open)
866
+ with file_open(path, "rb") as f:
867
+ return cloudpickle.load(f)
843
868
 
844
869
 
845
870
  if IS_PYDANTIC_V2_OR_NEWER:
@@ -17,6 +17,10 @@ logger = logging.getLogger(__name__)
17
17
 
18
18
  # Allowlist of safe classes that can be unpickled
19
19
  SAFE_PICKLE_CLASSES = {
20
+
21
+ # STD types
22
+ 'time.time',
23
+
20
24
  # NumPy types
21
25
  'numpy.ndarray',
22
26
  'numpy.dtype',
@@ -42,7 +46,7 @@ SAFE_PICKLE_CLASSES = {
42
46
  # Built-in types
43
47
  'builtins.dict', 'builtins.list', 'builtins.tuple', 'builtins.set',
44
48
  'builtins.str', 'builtins.int', 'builtins.float', 'builtins.bool',
45
- 'builtins.type',
49
+ 'builtins.type', 'builtins.object',
46
50
 
47
51
  # Collections
48
52
  'collections.OrderedDict',
@@ -62,6 +66,15 @@ SAFE_PICKLE_CLASSES = {
62
66
  'cloudpickle.cloudpickle._function_setstate',
63
67
  'cloudpickle.cloudpickle._make_empty_cell',
64
68
  'cloudpickle.cloudpickle._make_cell',
69
+ 'cloudpickle.cloudpickle.subimport',
70
+ 'cloudpickle.cloudpickle_fast._class_setstate',
71
+ 'cloudpickle.cloudpickle_fast._function_setstate',
72
+ 'cloudpickle.cloudpickle_fast._builtin_type',
73
+ 'cloudpickle.cloudpickle_fast._make_skeleton_class',
74
+ 'cloudpickle.cloudpickle_fast._make_function',
75
+ 'cloudpickle.cloudpickle_fast._make_empty_cell',
76
+ 'cloudpickle.cloudpickle_fast._make_cell',
77
+ 'cloudpickle.cloudpickle_fast.subimport',
65
78
 
66
79
  # Sentence Transformers
67
80
  'sentence_transformers.SentenceTransformer.SentenceTransformer',
@@ -103,6 +116,49 @@ SAFE_PICKLE_CLASSES = {
103
116
  'tokenizers.Tokenizer',
104
117
  'tokenizers.models.Model',
105
118
  'tokenizers.AddedToken',
119
+
120
+ # PyTorch
121
+ 'model.load_checkpoint',
122
+ 'torch.device',
123
+ 'model.SepClassifier',
124
+
125
+ # Generic model module classes (commonly used in custom ML models)
126
+ # These are general enough to be safe but specific to model loading
127
+ 'model.Model',
128
+ 'model.BaseModel',
129
+ 'model.PythonModel',
130
+ 'model.MLModel',
131
+ 'model.NeuralNetwork',
132
+ 'model.Classifier',
133
+ 'model.Regressor',
134
+ 'model.Predictor',
135
+ 'model.Estimator',
136
+ 'model.Pipeline',
137
+ 'model.Transformer',
138
+ 'model.Encoder',
139
+ 'model.Decoder',
140
+ 'model.Generator',
141
+ 'model.Discriminator',
142
+ 'model.load_model',
143
+ 'model.save_model',
144
+ 'model.predict',
145
+ 'model.transform',
146
+ 'model.fit',
147
+ 'model.evaluate',
148
+ 'model.train',
149
+ 'model.inference',
150
+ 'model.forward',
151
+ 'model.backward',
152
+
153
+ # Additional model-related common class names
154
+ 'model.ModelConfig',
155
+ 'model.ModelWrapper',
156
+ 'model.ModelFactory',
157
+ 'model.ModelRegistry',
158
+ 'model.ModelLoader',
159
+ 'model.ModelState',
160
+ 'model.ModelCheckpoint',
161
+ 'model.ModelArtifact',
106
162
  }
107
163
 
108
164
 
@@ -144,11 +200,14 @@ class RestrictedUnpickler(pickle.Unpickler):
144
200
  'numpy': ['ndarray', 'dtype', 'int32', 'int64', 'float32', 'float64', 'bool_'],
145
201
  'pandas': ['DataFrame', 'Series', 'Index'],
146
202
  'builtins': ['dict', 'list', 'tuple', 'set', 'str', 'int', 'float', 'bool'],
203
+ 'model': ['*'], # Allow all classes from 'model' module for custom models
147
204
  }
148
205
 
149
- if module in safe_modules and name in safe_modules[module]:
150
- logger.debug(f"Loading safe module class: {full_name}")
151
- return super().find_class(module, name)
206
+ if module in safe_modules:
207
+ # Check if all classes are allowed ('*') or if specific class is in list
208
+ if safe_modules[module] == ['*'] or name in safe_modules[module]:
209
+ logger.debug(f"Loading safe module class: {full_name}")
210
+ return super().find_class(module, name)
152
211
 
153
212
  # Log and block unsafe class
154
213
  logger.warning(f"Blocked potentially unsafe class: {full_name}")