truthound 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.
- truthound/__init__.py +162 -0
- truthound/adapters.py +100 -0
- truthound/api.py +365 -0
- truthound/audit/__init__.py +248 -0
- truthound/audit/core.py +967 -0
- truthound/audit/filters.py +620 -0
- truthound/audit/formatters.py +707 -0
- truthound/audit/logger.py +902 -0
- truthound/audit/middleware.py +571 -0
- truthound/audit/storage.py +1083 -0
- truthound/benchmark/__init__.py +123 -0
- truthound/benchmark/base.py +757 -0
- truthound/benchmark/comparison.py +635 -0
- truthound/benchmark/generators.py +706 -0
- truthound/benchmark/reporters.py +718 -0
- truthound/benchmark/runner.py +635 -0
- truthound/benchmark/scenarios.py +712 -0
- truthound/cache.py +252 -0
- truthound/checkpoint/__init__.py +136 -0
- truthound/checkpoint/actions/__init__.py +164 -0
- truthound/checkpoint/actions/base.py +324 -0
- truthound/checkpoint/actions/custom.py +234 -0
- truthound/checkpoint/actions/discord_notify.py +290 -0
- truthound/checkpoint/actions/email_notify.py +405 -0
- truthound/checkpoint/actions/github_action.py +406 -0
- truthound/checkpoint/actions/opsgenie.py +1499 -0
- truthound/checkpoint/actions/pagerduty.py +226 -0
- truthound/checkpoint/actions/slack_notify.py +233 -0
- truthound/checkpoint/actions/store_result.py +249 -0
- truthound/checkpoint/actions/teams_notify.py +1570 -0
- truthound/checkpoint/actions/telegram_notify.py +419 -0
- truthound/checkpoint/actions/update_docs.py +552 -0
- truthound/checkpoint/actions/webhook.py +293 -0
- truthound/checkpoint/analytics/__init__.py +147 -0
- truthound/checkpoint/analytics/aggregations/__init__.py +23 -0
- truthound/checkpoint/analytics/aggregations/rollup.py +481 -0
- truthound/checkpoint/analytics/aggregations/time_bucket.py +306 -0
- truthound/checkpoint/analytics/analyzers/__init__.py +17 -0
- truthound/checkpoint/analytics/analyzers/anomaly.py +386 -0
- truthound/checkpoint/analytics/analyzers/base.py +270 -0
- truthound/checkpoint/analytics/analyzers/forecast.py +421 -0
- truthound/checkpoint/analytics/analyzers/trend.py +314 -0
- truthound/checkpoint/analytics/models.py +292 -0
- truthound/checkpoint/analytics/protocols.py +549 -0
- truthound/checkpoint/analytics/service.py +718 -0
- truthound/checkpoint/analytics/stores/__init__.py +16 -0
- truthound/checkpoint/analytics/stores/base.py +306 -0
- truthound/checkpoint/analytics/stores/memory_store.py +353 -0
- truthound/checkpoint/analytics/stores/sqlite_store.py +557 -0
- truthound/checkpoint/analytics/stores/timescale_store.py +501 -0
- truthound/checkpoint/async_actions.py +794 -0
- truthound/checkpoint/async_base.py +708 -0
- truthound/checkpoint/async_checkpoint.py +617 -0
- truthound/checkpoint/async_runner.py +639 -0
- truthound/checkpoint/checkpoint.py +527 -0
- truthound/checkpoint/ci/__init__.py +61 -0
- truthound/checkpoint/ci/detector.py +355 -0
- truthound/checkpoint/ci/reporter.py +436 -0
- truthound/checkpoint/ci/templates.py +454 -0
- truthound/checkpoint/circuitbreaker/__init__.py +133 -0
- truthound/checkpoint/circuitbreaker/breaker.py +542 -0
- truthound/checkpoint/circuitbreaker/core.py +252 -0
- truthound/checkpoint/circuitbreaker/detection.py +459 -0
- truthound/checkpoint/circuitbreaker/middleware.py +389 -0
- truthound/checkpoint/circuitbreaker/registry.py +357 -0
- truthound/checkpoint/distributed/__init__.py +139 -0
- truthound/checkpoint/distributed/backends/__init__.py +35 -0
- truthound/checkpoint/distributed/backends/celery_backend.py +503 -0
- truthound/checkpoint/distributed/backends/kubernetes_backend.py +696 -0
- truthound/checkpoint/distributed/backends/local_backend.py +397 -0
- truthound/checkpoint/distributed/backends/ray_backend.py +625 -0
- truthound/checkpoint/distributed/base.py +774 -0
- truthound/checkpoint/distributed/orchestrator.py +765 -0
- truthound/checkpoint/distributed/protocols.py +842 -0
- truthound/checkpoint/distributed/registry.py +449 -0
- truthound/checkpoint/idempotency/__init__.py +120 -0
- truthound/checkpoint/idempotency/core.py +295 -0
- truthound/checkpoint/idempotency/fingerprint.py +454 -0
- truthound/checkpoint/idempotency/locking.py +604 -0
- truthound/checkpoint/idempotency/service.py +592 -0
- truthound/checkpoint/idempotency/stores.py +653 -0
- truthound/checkpoint/monitoring/__init__.py +134 -0
- truthound/checkpoint/monitoring/aggregators/__init__.py +15 -0
- truthound/checkpoint/monitoring/aggregators/base.py +372 -0
- truthound/checkpoint/monitoring/aggregators/realtime.py +300 -0
- truthound/checkpoint/monitoring/aggregators/window.py +493 -0
- truthound/checkpoint/monitoring/collectors/__init__.py +17 -0
- truthound/checkpoint/monitoring/collectors/base.py +257 -0
- truthound/checkpoint/monitoring/collectors/memory_collector.py +617 -0
- truthound/checkpoint/monitoring/collectors/prometheus_collector.py +451 -0
- truthound/checkpoint/monitoring/collectors/redis_collector.py +518 -0
- truthound/checkpoint/monitoring/events.py +410 -0
- truthound/checkpoint/monitoring/protocols.py +636 -0
- truthound/checkpoint/monitoring/service.py +578 -0
- truthound/checkpoint/monitoring/views/__init__.py +17 -0
- truthound/checkpoint/monitoring/views/base.py +172 -0
- truthound/checkpoint/monitoring/views/queue_view.py +220 -0
- truthound/checkpoint/monitoring/views/task_view.py +240 -0
- truthound/checkpoint/monitoring/views/worker_view.py +263 -0
- truthound/checkpoint/registry.py +337 -0
- truthound/checkpoint/runner.py +356 -0
- truthound/checkpoint/transaction/__init__.py +133 -0
- truthound/checkpoint/transaction/base.py +389 -0
- truthound/checkpoint/transaction/compensatable.py +537 -0
- truthound/checkpoint/transaction/coordinator.py +576 -0
- truthound/checkpoint/transaction/executor.py +622 -0
- truthound/checkpoint/transaction/idempotency.py +534 -0
- truthound/checkpoint/transaction/saga/__init__.py +143 -0
- truthound/checkpoint/transaction/saga/builder.py +584 -0
- truthound/checkpoint/transaction/saga/definition.py +515 -0
- truthound/checkpoint/transaction/saga/event_store.py +542 -0
- truthound/checkpoint/transaction/saga/patterns.py +833 -0
- truthound/checkpoint/transaction/saga/runner.py +718 -0
- truthound/checkpoint/transaction/saga/state_machine.py +793 -0
- truthound/checkpoint/transaction/saga/strategies.py +780 -0
- truthound/checkpoint/transaction/saga/testing.py +886 -0
- truthound/checkpoint/triggers/__init__.py +58 -0
- truthound/checkpoint/triggers/base.py +237 -0
- truthound/checkpoint/triggers/event.py +385 -0
- truthound/checkpoint/triggers/schedule.py +355 -0
- truthound/cli.py +2358 -0
- truthound/cli_modules/__init__.py +124 -0
- truthound/cli_modules/advanced/__init__.py +45 -0
- truthound/cli_modules/advanced/benchmark.py +343 -0
- truthound/cli_modules/advanced/docs.py +225 -0
- truthound/cli_modules/advanced/lineage.py +209 -0
- truthound/cli_modules/advanced/ml.py +320 -0
- truthound/cli_modules/advanced/realtime.py +196 -0
- truthound/cli_modules/checkpoint/__init__.py +46 -0
- truthound/cli_modules/checkpoint/init.py +114 -0
- truthound/cli_modules/checkpoint/list.py +71 -0
- truthound/cli_modules/checkpoint/run.py +159 -0
- truthound/cli_modules/checkpoint/validate.py +67 -0
- truthound/cli_modules/common/__init__.py +71 -0
- truthound/cli_modules/common/errors.py +414 -0
- truthound/cli_modules/common/options.py +419 -0
- truthound/cli_modules/common/output.py +507 -0
- truthound/cli_modules/common/protocol.py +552 -0
- truthound/cli_modules/core/__init__.py +48 -0
- truthound/cli_modules/core/check.py +123 -0
- truthound/cli_modules/core/compare.py +104 -0
- truthound/cli_modules/core/learn.py +57 -0
- truthound/cli_modules/core/mask.py +77 -0
- truthound/cli_modules/core/profile.py +65 -0
- truthound/cli_modules/core/scan.py +61 -0
- truthound/cli_modules/profiler/__init__.py +51 -0
- truthound/cli_modules/profiler/auto_profile.py +175 -0
- truthound/cli_modules/profiler/metadata.py +107 -0
- truthound/cli_modules/profiler/suite.py +283 -0
- truthound/cli_modules/registry.py +431 -0
- truthound/cli_modules/scaffolding/__init__.py +89 -0
- truthound/cli_modules/scaffolding/base.py +631 -0
- truthound/cli_modules/scaffolding/commands.py +545 -0
- truthound/cli_modules/scaffolding/plugins.py +1072 -0
- truthound/cli_modules/scaffolding/reporters.py +594 -0
- truthound/cli_modules/scaffolding/validators.py +1127 -0
- truthound/common/__init__.py +18 -0
- truthound/common/resilience/__init__.py +130 -0
- truthound/common/resilience/bulkhead.py +266 -0
- truthound/common/resilience/circuit_breaker.py +516 -0
- truthound/common/resilience/composite.py +332 -0
- truthound/common/resilience/config.py +292 -0
- truthound/common/resilience/protocols.py +217 -0
- truthound/common/resilience/rate_limiter.py +404 -0
- truthound/common/resilience/retry.py +341 -0
- truthound/datadocs/__init__.py +260 -0
- truthound/datadocs/base.py +571 -0
- truthound/datadocs/builder.py +761 -0
- truthound/datadocs/charts.py +764 -0
- truthound/datadocs/dashboard/__init__.py +63 -0
- truthound/datadocs/dashboard/app.py +576 -0
- truthound/datadocs/dashboard/components.py +584 -0
- truthound/datadocs/dashboard/state.py +240 -0
- truthound/datadocs/engine/__init__.py +46 -0
- truthound/datadocs/engine/context.py +376 -0
- truthound/datadocs/engine/pipeline.py +618 -0
- truthound/datadocs/engine/registry.py +469 -0
- truthound/datadocs/exporters/__init__.py +49 -0
- truthound/datadocs/exporters/base.py +198 -0
- truthound/datadocs/exporters/html.py +178 -0
- truthound/datadocs/exporters/json_exporter.py +253 -0
- truthound/datadocs/exporters/markdown.py +284 -0
- truthound/datadocs/exporters/pdf.py +392 -0
- truthound/datadocs/i18n/__init__.py +86 -0
- truthound/datadocs/i18n/catalog.py +960 -0
- truthound/datadocs/i18n/formatting.py +505 -0
- truthound/datadocs/i18n/loader.py +256 -0
- truthound/datadocs/i18n/plurals.py +378 -0
- truthound/datadocs/renderers/__init__.py +42 -0
- truthound/datadocs/renderers/base.py +401 -0
- truthound/datadocs/renderers/custom.py +342 -0
- truthound/datadocs/renderers/jinja.py +697 -0
- truthound/datadocs/sections.py +736 -0
- truthound/datadocs/styles.py +931 -0
- truthound/datadocs/themes/__init__.py +101 -0
- truthound/datadocs/themes/base.py +336 -0
- truthound/datadocs/themes/default.py +417 -0
- truthound/datadocs/themes/enterprise.py +419 -0
- truthound/datadocs/themes/loader.py +336 -0
- truthound/datadocs/themes.py +301 -0
- truthound/datadocs/transformers/__init__.py +57 -0
- truthound/datadocs/transformers/base.py +268 -0
- truthound/datadocs/transformers/enrichers.py +544 -0
- truthound/datadocs/transformers/filters.py +447 -0
- truthound/datadocs/transformers/i18n.py +468 -0
- truthound/datadocs/versioning/__init__.py +62 -0
- truthound/datadocs/versioning/diff.py +639 -0
- truthound/datadocs/versioning/storage.py +497 -0
- truthound/datadocs/versioning/version.py +358 -0
- truthound/datasources/__init__.py +223 -0
- truthound/datasources/_async_protocols.py +222 -0
- truthound/datasources/_protocols.py +159 -0
- truthound/datasources/adapters.py +428 -0
- truthound/datasources/async_base.py +599 -0
- truthound/datasources/async_factory.py +511 -0
- truthound/datasources/base.py +516 -0
- truthound/datasources/factory.py +433 -0
- truthound/datasources/nosql/__init__.py +47 -0
- truthound/datasources/nosql/base.py +487 -0
- truthound/datasources/nosql/elasticsearch.py +801 -0
- truthound/datasources/nosql/mongodb.py +636 -0
- truthound/datasources/pandas_optimized.py +582 -0
- truthound/datasources/pandas_source.py +216 -0
- truthound/datasources/polars_source.py +395 -0
- truthound/datasources/spark_source.py +479 -0
- truthound/datasources/sql/__init__.py +154 -0
- truthound/datasources/sql/base.py +710 -0
- truthound/datasources/sql/bigquery.py +410 -0
- truthound/datasources/sql/cloud_base.py +199 -0
- truthound/datasources/sql/databricks.py +471 -0
- truthound/datasources/sql/mysql.py +316 -0
- truthound/datasources/sql/oracle.py +427 -0
- truthound/datasources/sql/postgresql.py +321 -0
- truthound/datasources/sql/redshift.py +479 -0
- truthound/datasources/sql/snowflake.py +439 -0
- truthound/datasources/sql/sqlite.py +286 -0
- truthound/datasources/sql/sqlserver.py +437 -0
- truthound/datasources/streaming/__init__.py +47 -0
- truthound/datasources/streaming/base.py +350 -0
- truthound/datasources/streaming/kafka.py +670 -0
- truthound/decorators.py +98 -0
- truthound/docs/__init__.py +69 -0
- truthound/docs/extractor.py +971 -0
- truthound/docs/generator.py +601 -0
- truthound/docs/parser.py +1037 -0
- truthound/docs/renderer.py +999 -0
- truthound/drift/__init__.py +22 -0
- truthound/drift/compare.py +189 -0
- truthound/drift/detectors.py +464 -0
- truthound/drift/report.py +160 -0
- truthound/execution/__init__.py +65 -0
- truthound/execution/_protocols.py +324 -0
- truthound/execution/base.py +576 -0
- truthound/execution/distributed/__init__.py +179 -0
- truthound/execution/distributed/aggregations.py +731 -0
- truthound/execution/distributed/arrow_bridge.py +817 -0
- truthound/execution/distributed/base.py +550 -0
- truthound/execution/distributed/dask_engine.py +976 -0
- truthound/execution/distributed/mixins.py +766 -0
- truthound/execution/distributed/protocols.py +756 -0
- truthound/execution/distributed/ray_engine.py +1127 -0
- truthound/execution/distributed/registry.py +446 -0
- truthound/execution/distributed/spark_engine.py +1011 -0
- truthound/execution/distributed/validator_adapter.py +682 -0
- truthound/execution/pandas_engine.py +401 -0
- truthound/execution/polars_engine.py +497 -0
- truthound/execution/pushdown/__init__.py +230 -0
- truthound/execution/pushdown/ast.py +1550 -0
- truthound/execution/pushdown/builder.py +1550 -0
- truthound/execution/pushdown/dialects.py +1072 -0
- truthound/execution/pushdown/executor.py +829 -0
- truthound/execution/pushdown/optimizer.py +1041 -0
- truthound/execution/sql_engine.py +518 -0
- truthound/infrastructure/__init__.py +189 -0
- truthound/infrastructure/audit.py +1515 -0
- truthound/infrastructure/config.py +1133 -0
- truthound/infrastructure/encryption.py +1132 -0
- truthound/infrastructure/logging.py +1503 -0
- truthound/infrastructure/metrics.py +1220 -0
- truthound/lineage/__init__.py +89 -0
- truthound/lineage/base.py +746 -0
- truthound/lineage/impact_analysis.py +474 -0
- truthound/lineage/integrations/__init__.py +22 -0
- truthound/lineage/integrations/openlineage.py +548 -0
- truthound/lineage/tracker.py +512 -0
- truthound/lineage/visualization/__init__.py +33 -0
- truthound/lineage/visualization/protocols.py +145 -0
- truthound/lineage/visualization/renderers/__init__.py +20 -0
- truthound/lineage/visualization/renderers/cytoscape.py +329 -0
- truthound/lineage/visualization/renderers/d3.py +331 -0
- truthound/lineage/visualization/renderers/graphviz.py +276 -0
- truthound/lineage/visualization/renderers/mermaid.py +308 -0
- truthound/maskers.py +113 -0
- truthound/ml/__init__.py +124 -0
- truthound/ml/anomaly_models/__init__.py +31 -0
- truthound/ml/anomaly_models/ensemble.py +362 -0
- truthound/ml/anomaly_models/isolation_forest.py +444 -0
- truthound/ml/anomaly_models/statistical.py +392 -0
- truthound/ml/base.py +1178 -0
- truthound/ml/drift_detection/__init__.py +26 -0
- truthound/ml/drift_detection/concept.py +381 -0
- truthound/ml/drift_detection/distribution.py +361 -0
- truthound/ml/drift_detection/feature.py +442 -0
- truthound/ml/drift_detection/multivariate.py +495 -0
- truthound/ml/monitoring/__init__.py +88 -0
- truthound/ml/monitoring/alerting/__init__.py +33 -0
- truthound/ml/monitoring/alerting/handlers.py +427 -0
- truthound/ml/monitoring/alerting/rules.py +508 -0
- truthound/ml/monitoring/collectors/__init__.py +19 -0
- truthound/ml/monitoring/collectors/composite.py +105 -0
- truthound/ml/monitoring/collectors/drift.py +324 -0
- truthound/ml/monitoring/collectors/performance.py +179 -0
- truthound/ml/monitoring/collectors/quality.py +369 -0
- truthound/ml/monitoring/monitor.py +536 -0
- truthound/ml/monitoring/protocols.py +451 -0
- truthound/ml/monitoring/stores/__init__.py +15 -0
- truthound/ml/monitoring/stores/memory.py +201 -0
- truthound/ml/monitoring/stores/prometheus.py +296 -0
- truthound/ml/rule_learning/__init__.py +25 -0
- truthound/ml/rule_learning/constraint_miner.py +443 -0
- truthound/ml/rule_learning/pattern_learner.py +499 -0
- truthound/ml/rule_learning/profile_learner.py +462 -0
- truthound/multitenancy/__init__.py +326 -0
- truthound/multitenancy/core.py +852 -0
- truthound/multitenancy/integration.py +597 -0
- truthound/multitenancy/isolation.py +630 -0
- truthound/multitenancy/manager.py +770 -0
- truthound/multitenancy/middleware.py +765 -0
- truthound/multitenancy/quota.py +537 -0
- truthound/multitenancy/resolvers.py +603 -0
- truthound/multitenancy/storage.py +703 -0
- truthound/observability/__init__.py +307 -0
- truthound/observability/context.py +531 -0
- truthound/observability/instrumentation.py +611 -0
- truthound/observability/logging.py +887 -0
- truthound/observability/metrics.py +1157 -0
- truthound/observability/tracing/__init__.py +178 -0
- truthound/observability/tracing/baggage.py +310 -0
- truthound/observability/tracing/config.py +426 -0
- truthound/observability/tracing/exporter.py +787 -0
- truthound/observability/tracing/integration.py +1018 -0
- truthound/observability/tracing/otel/__init__.py +146 -0
- truthound/observability/tracing/otel/adapter.py +982 -0
- truthound/observability/tracing/otel/bridge.py +1177 -0
- truthound/observability/tracing/otel/compat.py +681 -0
- truthound/observability/tracing/otel/config.py +691 -0
- truthound/observability/tracing/otel/detection.py +327 -0
- truthound/observability/tracing/otel/protocols.py +426 -0
- truthound/observability/tracing/processor.py +561 -0
- truthound/observability/tracing/propagator.py +757 -0
- truthound/observability/tracing/provider.py +569 -0
- truthound/observability/tracing/resource.py +515 -0
- truthound/observability/tracing/sampler.py +487 -0
- truthound/observability/tracing/span.py +676 -0
- truthound/plugins/__init__.py +198 -0
- truthound/plugins/base.py +599 -0
- truthound/plugins/cli.py +680 -0
- truthound/plugins/dependencies/__init__.py +42 -0
- truthound/plugins/dependencies/graph.py +422 -0
- truthound/plugins/dependencies/resolver.py +417 -0
- truthound/plugins/discovery.py +379 -0
- truthound/plugins/docs/__init__.py +46 -0
- truthound/plugins/docs/extractor.py +444 -0
- truthound/plugins/docs/renderer.py +499 -0
- truthound/plugins/enterprise_manager.py +877 -0
- truthound/plugins/examples/__init__.py +19 -0
- truthound/plugins/examples/custom_validators.py +317 -0
- truthound/plugins/examples/slack_notifier.py +312 -0
- truthound/plugins/examples/xml_reporter.py +254 -0
- truthound/plugins/hooks.py +558 -0
- truthound/plugins/lifecycle/__init__.py +43 -0
- truthound/plugins/lifecycle/hot_reload.py +402 -0
- truthound/plugins/lifecycle/manager.py +371 -0
- truthound/plugins/manager.py +736 -0
- truthound/plugins/registry.py +338 -0
- truthound/plugins/security/__init__.py +93 -0
- truthound/plugins/security/exceptions.py +332 -0
- truthound/plugins/security/policies.py +348 -0
- truthound/plugins/security/protocols.py +643 -0
- truthound/plugins/security/sandbox/__init__.py +45 -0
- truthound/plugins/security/sandbox/context.py +158 -0
- truthound/plugins/security/sandbox/engines/__init__.py +19 -0
- truthound/plugins/security/sandbox/engines/container.py +379 -0
- truthound/plugins/security/sandbox/engines/noop.py +144 -0
- truthound/plugins/security/sandbox/engines/process.py +336 -0
- truthound/plugins/security/sandbox/factory.py +211 -0
- truthound/plugins/security/signing/__init__.py +57 -0
- truthound/plugins/security/signing/service.py +330 -0
- truthound/plugins/security/signing/trust_store.py +368 -0
- truthound/plugins/security/signing/verifier.py +459 -0
- truthound/plugins/versioning/__init__.py +41 -0
- truthound/plugins/versioning/constraints.py +297 -0
- truthound/plugins/versioning/resolver.py +329 -0
- truthound/profiler/__init__.py +1729 -0
- truthound/profiler/_lazy.py +452 -0
- truthound/profiler/ab_testing/__init__.py +80 -0
- truthound/profiler/ab_testing/analysis.py +449 -0
- truthound/profiler/ab_testing/base.py +257 -0
- truthound/profiler/ab_testing/experiment.py +395 -0
- truthound/profiler/ab_testing/tracking.py +368 -0
- truthound/profiler/auto_threshold.py +1170 -0
- truthound/profiler/base.py +579 -0
- truthound/profiler/cache_patterns.py +911 -0
- truthound/profiler/caching.py +1303 -0
- truthound/profiler/column_profiler.py +712 -0
- truthound/profiler/comparison.py +1007 -0
- truthound/profiler/custom_patterns.py +1170 -0
- truthound/profiler/dashboard/__init__.py +50 -0
- truthound/profiler/dashboard/app.py +476 -0
- truthound/profiler/dashboard/components.py +457 -0
- truthound/profiler/dashboard/config.py +72 -0
- truthound/profiler/distributed/__init__.py +83 -0
- truthound/profiler/distributed/base.py +281 -0
- truthound/profiler/distributed/dask_backend.py +498 -0
- truthound/profiler/distributed/local_backend.py +293 -0
- truthound/profiler/distributed/profiler.py +304 -0
- truthound/profiler/distributed/ray_backend.py +374 -0
- truthound/profiler/distributed/spark_backend.py +375 -0
- truthound/profiler/distributed.py +1366 -0
- truthound/profiler/enterprise_sampling.py +1065 -0
- truthound/profiler/errors.py +488 -0
- truthound/profiler/evolution/__init__.py +91 -0
- truthound/profiler/evolution/alerts.py +426 -0
- truthound/profiler/evolution/changes.py +206 -0
- truthound/profiler/evolution/compatibility.py +365 -0
- truthound/profiler/evolution/detector.py +372 -0
- truthound/profiler/evolution/protocols.py +121 -0
- truthound/profiler/generators/__init__.py +48 -0
- truthound/profiler/generators/base.py +384 -0
- truthound/profiler/generators/ml_rules.py +375 -0
- truthound/profiler/generators/pattern_rules.py +384 -0
- truthound/profiler/generators/schema_rules.py +267 -0
- truthound/profiler/generators/stats_rules.py +324 -0
- truthound/profiler/generators/suite_generator.py +857 -0
- truthound/profiler/i18n.py +1542 -0
- truthound/profiler/incremental.py +554 -0
- truthound/profiler/incremental_validation.py +1710 -0
- truthound/profiler/integration/__init__.py +73 -0
- truthound/profiler/integration/adapters.py +345 -0
- truthound/profiler/integration/context.py +371 -0
- truthound/profiler/integration/executor.py +527 -0
- truthound/profiler/integration/naming.py +75 -0
- truthound/profiler/integration/protocols.py +243 -0
- truthound/profiler/memory.py +1185 -0
- truthound/profiler/migration/__init__.py +60 -0
- truthound/profiler/migration/base.py +345 -0
- truthound/profiler/migration/manager.py +444 -0
- truthound/profiler/migration/v1_0_to_v1_1.py +484 -0
- truthound/profiler/ml/__init__.py +73 -0
- truthound/profiler/ml/base.py +244 -0
- truthound/profiler/ml/classifier.py +507 -0
- truthound/profiler/ml/feature_extraction.py +604 -0
- truthound/profiler/ml/pretrained.py +448 -0
- truthound/profiler/ml_inference.py +1276 -0
- truthound/profiler/native_patterns.py +815 -0
- truthound/profiler/observability.py +1184 -0
- truthound/profiler/process_timeout.py +1566 -0
- truthound/profiler/progress.py +568 -0
- truthound/profiler/progress_callbacks.py +1734 -0
- truthound/profiler/quality.py +1345 -0
- truthound/profiler/resilience.py +1180 -0
- truthound/profiler/sampled_matcher.py +794 -0
- truthound/profiler/sampling.py +1288 -0
- truthound/profiler/scheduling/__init__.py +82 -0
- truthound/profiler/scheduling/protocols.py +214 -0
- truthound/profiler/scheduling/scheduler.py +474 -0
- truthound/profiler/scheduling/storage.py +457 -0
- truthound/profiler/scheduling/triggers.py +449 -0
- truthound/profiler/schema.py +603 -0
- truthound/profiler/streaming.py +685 -0
- truthound/profiler/streaming_patterns.py +1354 -0
- truthound/profiler/suite_cli.py +625 -0
- truthound/profiler/suite_config.py +789 -0
- truthound/profiler/suite_export.py +1268 -0
- truthound/profiler/table_profiler.py +547 -0
- truthound/profiler/timeout.py +565 -0
- truthound/profiler/validation.py +1532 -0
- truthound/profiler/visualization/__init__.py +118 -0
- truthound/profiler/visualization/base.py +346 -0
- truthound/profiler/visualization/generator.py +1259 -0
- truthound/profiler/visualization/plotly_renderer.py +811 -0
- truthound/profiler/visualization/renderers.py +669 -0
- truthound/profiler/visualization/sections.py +540 -0
- truthound/profiler/visualization.py +2122 -0
- truthound/profiler/yaml_validation.py +1151 -0
- truthound/py.typed +0 -0
- truthound/ratelimit/__init__.py +248 -0
- truthound/ratelimit/algorithms.py +1108 -0
- truthound/ratelimit/core.py +573 -0
- truthound/ratelimit/integration.py +532 -0
- truthound/ratelimit/limiter.py +663 -0
- truthound/ratelimit/middleware.py +700 -0
- truthound/ratelimit/policy.py +792 -0
- truthound/ratelimit/storage.py +763 -0
- truthound/rbac/__init__.py +340 -0
- truthound/rbac/core.py +976 -0
- truthound/rbac/integration.py +760 -0
- truthound/rbac/manager.py +1052 -0
- truthound/rbac/middleware.py +842 -0
- truthound/rbac/policy.py +954 -0
- truthound/rbac/storage.py +878 -0
- truthound/realtime/__init__.py +141 -0
- truthound/realtime/adapters/__init__.py +43 -0
- truthound/realtime/adapters/base.py +533 -0
- truthound/realtime/adapters/kafka.py +487 -0
- truthound/realtime/adapters/kinesis.py +479 -0
- truthound/realtime/adapters/mock.py +243 -0
- truthound/realtime/base.py +553 -0
- truthound/realtime/factory.py +382 -0
- truthound/realtime/incremental.py +660 -0
- truthound/realtime/processing/__init__.py +67 -0
- truthound/realtime/processing/exactly_once.py +575 -0
- truthound/realtime/processing/state.py +547 -0
- truthound/realtime/processing/windows.py +647 -0
- truthound/realtime/protocols.py +569 -0
- truthound/realtime/streaming.py +605 -0
- truthound/realtime/testing/__init__.py +32 -0
- truthound/realtime/testing/containers.py +615 -0
- truthound/realtime/testing/fixtures.py +484 -0
- truthound/report.py +280 -0
- truthound/reporters/__init__.py +46 -0
- truthound/reporters/_protocols.py +30 -0
- truthound/reporters/base.py +324 -0
- truthound/reporters/ci/__init__.py +66 -0
- truthound/reporters/ci/azure.py +436 -0
- truthound/reporters/ci/base.py +509 -0
- truthound/reporters/ci/bitbucket.py +567 -0
- truthound/reporters/ci/circleci.py +547 -0
- truthound/reporters/ci/detection.py +364 -0
- truthound/reporters/ci/factory.py +182 -0
- truthound/reporters/ci/github.py +388 -0
- truthound/reporters/ci/gitlab.py +471 -0
- truthound/reporters/ci/jenkins.py +525 -0
- truthound/reporters/console_reporter.py +299 -0
- truthound/reporters/factory.py +211 -0
- truthound/reporters/html_reporter.py +524 -0
- truthound/reporters/json_reporter.py +256 -0
- truthound/reporters/markdown_reporter.py +280 -0
- truthound/reporters/sdk/__init__.py +174 -0
- truthound/reporters/sdk/builder.py +558 -0
- truthound/reporters/sdk/mixins.py +1150 -0
- truthound/reporters/sdk/schema.py +1493 -0
- truthound/reporters/sdk/templates.py +666 -0
- truthound/reporters/sdk/testing.py +968 -0
- truthound/scanners.py +170 -0
- truthound/scheduling/__init__.py +122 -0
- truthound/scheduling/cron.py +1136 -0
- truthound/scheduling/presets.py +212 -0
- truthound/schema.py +275 -0
- truthound/secrets/__init__.py +173 -0
- truthound/secrets/base.py +618 -0
- truthound/secrets/cloud.py +682 -0
- truthound/secrets/integration.py +507 -0
- truthound/secrets/manager.py +633 -0
- truthound/secrets/oidc/__init__.py +172 -0
- truthound/secrets/oidc/base.py +902 -0
- truthound/secrets/oidc/credential_provider.py +623 -0
- truthound/secrets/oidc/exchangers.py +1001 -0
- truthound/secrets/oidc/github/__init__.py +110 -0
- truthound/secrets/oidc/github/claims.py +718 -0
- truthound/secrets/oidc/github/enhanced_provider.py +693 -0
- truthound/secrets/oidc/github/trust_policy.py +742 -0
- truthound/secrets/oidc/github/verification.py +723 -0
- truthound/secrets/oidc/github/workflow.py +691 -0
- truthound/secrets/oidc/providers.py +825 -0
- truthound/secrets/providers.py +506 -0
- truthound/secrets/resolver.py +495 -0
- truthound/stores/__init__.py +177 -0
- truthound/stores/backends/__init__.py +18 -0
- truthound/stores/backends/_protocols.py +340 -0
- truthound/stores/backends/azure_blob.py +530 -0
- truthound/stores/backends/concurrent_filesystem.py +915 -0
- truthound/stores/backends/connection_pool.py +1365 -0
- truthound/stores/backends/database.py +743 -0
- truthound/stores/backends/filesystem.py +538 -0
- truthound/stores/backends/gcs.py +399 -0
- truthound/stores/backends/memory.py +354 -0
- truthound/stores/backends/s3.py +434 -0
- truthound/stores/backpressure/__init__.py +84 -0
- truthound/stores/backpressure/base.py +375 -0
- truthound/stores/backpressure/circuit_breaker.py +434 -0
- truthound/stores/backpressure/monitor.py +376 -0
- truthound/stores/backpressure/strategies.py +677 -0
- truthound/stores/base.py +551 -0
- truthound/stores/batching/__init__.py +65 -0
- truthound/stores/batching/base.py +305 -0
- truthound/stores/batching/buffer.py +370 -0
- truthound/stores/batching/store.py +248 -0
- truthound/stores/batching/writer.py +521 -0
- truthound/stores/caching/__init__.py +60 -0
- truthound/stores/caching/backends.py +684 -0
- truthound/stores/caching/base.py +356 -0
- truthound/stores/caching/store.py +305 -0
- truthound/stores/compression/__init__.py +193 -0
- truthound/stores/compression/adaptive.py +694 -0
- truthound/stores/compression/base.py +514 -0
- truthound/stores/compression/pipeline.py +868 -0
- truthound/stores/compression/providers.py +672 -0
- truthound/stores/compression/streaming.py +832 -0
- truthound/stores/concurrency/__init__.py +81 -0
- truthound/stores/concurrency/atomic.py +556 -0
- truthound/stores/concurrency/index.py +775 -0
- truthound/stores/concurrency/locks.py +576 -0
- truthound/stores/concurrency/manager.py +482 -0
- truthound/stores/encryption/__init__.py +297 -0
- truthound/stores/encryption/base.py +952 -0
- truthound/stores/encryption/keys.py +1191 -0
- truthound/stores/encryption/pipeline.py +903 -0
- truthound/stores/encryption/providers.py +953 -0
- truthound/stores/encryption/streaming.py +950 -0
- truthound/stores/expectations.py +227 -0
- truthound/stores/factory.py +246 -0
- truthound/stores/migration/__init__.py +75 -0
- truthound/stores/migration/base.py +480 -0
- truthound/stores/migration/manager.py +347 -0
- truthound/stores/migration/registry.py +382 -0
- truthound/stores/migration/store.py +559 -0
- truthound/stores/observability/__init__.py +106 -0
- truthound/stores/observability/audit.py +718 -0
- truthound/stores/observability/config.py +270 -0
- truthound/stores/observability/factory.py +208 -0
- truthound/stores/observability/metrics.py +636 -0
- truthound/stores/observability/protocols.py +410 -0
- truthound/stores/observability/store.py +570 -0
- truthound/stores/observability/tracing.py +784 -0
- truthound/stores/replication/__init__.py +76 -0
- truthound/stores/replication/base.py +260 -0
- truthound/stores/replication/monitor.py +269 -0
- truthound/stores/replication/store.py +439 -0
- truthound/stores/replication/syncer.py +391 -0
- truthound/stores/results.py +359 -0
- truthound/stores/retention/__init__.py +77 -0
- truthound/stores/retention/base.py +378 -0
- truthound/stores/retention/policies.py +621 -0
- truthound/stores/retention/scheduler.py +279 -0
- truthound/stores/retention/store.py +526 -0
- truthound/stores/streaming/__init__.py +138 -0
- truthound/stores/streaming/base.py +801 -0
- truthound/stores/streaming/database.py +984 -0
- truthound/stores/streaming/filesystem.py +719 -0
- truthound/stores/streaming/reader.py +629 -0
- truthound/stores/streaming/s3.py +843 -0
- truthound/stores/streaming/writer.py +790 -0
- truthound/stores/tiering/__init__.py +108 -0
- truthound/stores/tiering/base.py +462 -0
- truthound/stores/tiering/manager.py +249 -0
- truthound/stores/tiering/policies.py +692 -0
- truthound/stores/tiering/store.py +526 -0
- truthound/stores/versioning/__init__.py +56 -0
- truthound/stores/versioning/base.py +376 -0
- truthound/stores/versioning/store.py +660 -0
- truthound/stores/versioning/strategies.py +353 -0
- truthound/types.py +56 -0
- truthound/validators/__init__.py +774 -0
- truthound/validators/aggregate/__init__.py +27 -0
- truthound/validators/aggregate/central.py +116 -0
- truthound/validators/aggregate/extremes.py +116 -0
- truthound/validators/aggregate/spread.py +118 -0
- truthound/validators/aggregate/sum.py +64 -0
- truthound/validators/aggregate/type.py +78 -0
- truthound/validators/anomaly/__init__.py +93 -0
- truthound/validators/anomaly/base.py +431 -0
- truthound/validators/anomaly/ml_based.py +1190 -0
- truthound/validators/anomaly/multivariate.py +647 -0
- truthound/validators/anomaly/statistical.py +599 -0
- truthound/validators/base.py +1089 -0
- truthound/validators/business_rule/__init__.py +46 -0
- truthound/validators/business_rule/base.py +147 -0
- truthound/validators/business_rule/checksum.py +509 -0
- truthound/validators/business_rule/financial.py +526 -0
- truthound/validators/cache.py +733 -0
- truthound/validators/completeness/__init__.py +39 -0
- truthound/validators/completeness/conditional.py +73 -0
- truthound/validators/completeness/default.py +98 -0
- truthound/validators/completeness/empty.py +103 -0
- truthound/validators/completeness/nan.py +337 -0
- truthound/validators/completeness/null.py +152 -0
- truthound/validators/cross_table/__init__.py +17 -0
- truthound/validators/cross_table/aggregate.py +333 -0
- truthound/validators/cross_table/row_count.py +122 -0
- truthound/validators/datetime/__init__.py +29 -0
- truthound/validators/datetime/format.py +78 -0
- truthound/validators/datetime/freshness.py +269 -0
- truthound/validators/datetime/order.py +73 -0
- truthound/validators/datetime/parseable.py +185 -0
- truthound/validators/datetime/range.py +202 -0
- truthound/validators/datetime/timezone.py +69 -0
- truthound/validators/distribution/__init__.py +49 -0
- truthound/validators/distribution/distribution.py +128 -0
- truthound/validators/distribution/monotonic.py +119 -0
- truthound/validators/distribution/outlier.py +178 -0
- truthound/validators/distribution/quantile.py +80 -0
- truthound/validators/distribution/range.py +254 -0
- truthound/validators/distribution/set.py +125 -0
- truthound/validators/distribution/statistical.py +459 -0
- truthound/validators/drift/__init__.py +79 -0
- truthound/validators/drift/base.py +427 -0
- truthound/validators/drift/multi_feature.py +401 -0
- truthound/validators/drift/numeric.py +395 -0
- truthound/validators/drift/psi.py +446 -0
- truthound/validators/drift/statistical.py +510 -0
- truthound/validators/enterprise.py +1658 -0
- truthound/validators/geospatial/__init__.py +80 -0
- truthound/validators/geospatial/base.py +97 -0
- truthound/validators/geospatial/boundary.py +238 -0
- truthound/validators/geospatial/coordinate.py +351 -0
- truthound/validators/geospatial/distance.py +399 -0
- truthound/validators/geospatial/polygon.py +665 -0
- truthound/validators/i18n/__init__.py +308 -0
- truthound/validators/i18n/bidi.py +571 -0
- truthound/validators/i18n/catalogs.py +570 -0
- truthound/validators/i18n/dialects.py +763 -0
- truthound/validators/i18n/extended_catalogs.py +549 -0
- truthound/validators/i18n/formatting.py +1434 -0
- truthound/validators/i18n/loader.py +1020 -0
- truthound/validators/i18n/messages.py +521 -0
- truthound/validators/i18n/plural.py +683 -0
- truthound/validators/i18n/protocols.py +855 -0
- truthound/validators/i18n/tms.py +1162 -0
- truthound/validators/localization/__init__.py +53 -0
- truthound/validators/localization/base.py +122 -0
- truthound/validators/localization/chinese.py +362 -0
- truthound/validators/localization/japanese.py +275 -0
- truthound/validators/localization/korean.py +524 -0
- truthound/validators/memory/__init__.py +94 -0
- truthound/validators/memory/approximate_knn.py +506 -0
- truthound/validators/memory/base.py +547 -0
- truthound/validators/memory/sgd_online.py +719 -0
- truthound/validators/memory/streaming_ecdf.py +753 -0
- truthound/validators/ml_feature/__init__.py +54 -0
- truthound/validators/ml_feature/base.py +249 -0
- truthound/validators/ml_feature/correlation.py +299 -0
- truthound/validators/ml_feature/leakage.py +344 -0
- truthound/validators/ml_feature/null_impact.py +270 -0
- truthound/validators/ml_feature/scale.py +264 -0
- truthound/validators/multi_column/__init__.py +89 -0
- truthound/validators/multi_column/arithmetic.py +284 -0
- truthound/validators/multi_column/base.py +231 -0
- truthound/validators/multi_column/comparison.py +273 -0
- truthound/validators/multi_column/consistency.py +312 -0
- truthound/validators/multi_column/statistical.py +299 -0
- truthound/validators/optimization/__init__.py +164 -0
- truthound/validators/optimization/aggregation.py +563 -0
- truthound/validators/optimization/covariance.py +556 -0
- truthound/validators/optimization/geo.py +626 -0
- truthound/validators/optimization/graph.py +587 -0
- truthound/validators/optimization/orchestrator.py +970 -0
- truthound/validators/optimization/profiling.py +1312 -0
- truthound/validators/privacy/__init__.py +223 -0
- truthound/validators/privacy/base.py +635 -0
- truthound/validators/privacy/ccpa.py +670 -0
- truthound/validators/privacy/gdpr.py +728 -0
- truthound/validators/privacy/global_patterns.py +604 -0
- truthound/validators/privacy/plugins.py +867 -0
- truthound/validators/profiling/__init__.py +52 -0
- truthound/validators/profiling/base.py +175 -0
- truthound/validators/profiling/cardinality.py +312 -0
- truthound/validators/profiling/entropy.py +391 -0
- truthound/validators/profiling/frequency.py +455 -0
- truthound/validators/pushdown_support.py +660 -0
- truthound/validators/query/__init__.py +91 -0
- truthound/validators/query/aggregate.py +346 -0
- truthound/validators/query/base.py +246 -0
- truthound/validators/query/column.py +249 -0
- truthound/validators/query/expression.py +274 -0
- truthound/validators/query/result.py +323 -0
- truthound/validators/query/row_count.py +264 -0
- truthound/validators/referential/__init__.py +80 -0
- truthound/validators/referential/base.py +395 -0
- truthound/validators/referential/cascade.py +391 -0
- truthound/validators/referential/circular.py +563 -0
- truthound/validators/referential/foreign_key.py +624 -0
- truthound/validators/referential/orphan.py +485 -0
- truthound/validators/registry.py +112 -0
- truthound/validators/schema/__init__.py +41 -0
- truthound/validators/schema/column_count.py +142 -0
- truthound/validators/schema/column_exists.py +80 -0
- truthound/validators/schema/column_order.py +82 -0
- truthound/validators/schema/column_pair.py +85 -0
- truthound/validators/schema/column_pair_set.py +195 -0
- truthound/validators/schema/column_type.py +94 -0
- truthound/validators/schema/multi_column.py +53 -0
- truthound/validators/schema/multi_column_aggregate.py +175 -0
- truthound/validators/schema/referential.py +274 -0
- truthound/validators/schema/table_schema.py +91 -0
- truthound/validators/schema_validator.py +219 -0
- truthound/validators/sdk/__init__.py +250 -0
- truthound/validators/sdk/builder.py +680 -0
- truthound/validators/sdk/decorators.py +474 -0
- truthound/validators/sdk/enterprise/__init__.py +211 -0
- truthound/validators/sdk/enterprise/docs.py +725 -0
- truthound/validators/sdk/enterprise/fuzzing.py +659 -0
- truthound/validators/sdk/enterprise/licensing.py +709 -0
- truthound/validators/sdk/enterprise/manager.py +543 -0
- truthound/validators/sdk/enterprise/resources.py +628 -0
- truthound/validators/sdk/enterprise/sandbox.py +766 -0
- truthound/validators/sdk/enterprise/signing.py +603 -0
- truthound/validators/sdk/enterprise/templates.py +865 -0
- truthound/validators/sdk/enterprise/versioning.py +659 -0
- truthound/validators/sdk/templates.py +757 -0
- truthound/validators/sdk/testing.py +807 -0
- truthound/validators/security/__init__.py +181 -0
- truthound/validators/security/redos/__init__.py +182 -0
- truthound/validators/security/redos/core.py +861 -0
- truthound/validators/security/redos/cpu_monitor.py +593 -0
- truthound/validators/security/redos/cve_database.py +791 -0
- truthound/validators/security/redos/ml/__init__.py +155 -0
- truthound/validators/security/redos/ml/base.py +785 -0
- truthound/validators/security/redos/ml/datasets.py +618 -0
- truthound/validators/security/redos/ml/features.py +359 -0
- truthound/validators/security/redos/ml/models.py +1000 -0
- truthound/validators/security/redos/ml/predictor.py +507 -0
- truthound/validators/security/redos/ml/storage.py +632 -0
- truthound/validators/security/redos/ml/training.py +571 -0
- truthound/validators/security/redos/ml_analyzer.py +937 -0
- truthound/validators/security/redos/optimizer.py +674 -0
- truthound/validators/security/redos/profiler.py +682 -0
- truthound/validators/security/redos/re2_engine.py +709 -0
- truthound/validators/security/redos.py +886 -0
- truthound/validators/security/sql_security.py +1247 -0
- truthound/validators/streaming/__init__.py +126 -0
- truthound/validators/streaming/base.py +292 -0
- truthound/validators/streaming/completeness.py +210 -0
- truthound/validators/streaming/mixin.py +575 -0
- truthound/validators/streaming/range.py +308 -0
- truthound/validators/streaming/sources.py +846 -0
- truthound/validators/string/__init__.py +57 -0
- truthound/validators/string/casing.py +158 -0
- truthound/validators/string/charset.py +96 -0
- truthound/validators/string/format.py +501 -0
- truthound/validators/string/json.py +77 -0
- truthound/validators/string/json_schema.py +184 -0
- truthound/validators/string/length.py +104 -0
- truthound/validators/string/like_pattern.py +237 -0
- truthound/validators/string/regex.py +202 -0
- truthound/validators/string/regex_extended.py +435 -0
- truthound/validators/table/__init__.py +88 -0
- truthound/validators/table/base.py +78 -0
- truthound/validators/table/column_count.py +198 -0
- truthound/validators/table/freshness.py +362 -0
- truthound/validators/table/row_count.py +251 -0
- truthound/validators/table/schema.py +333 -0
- truthound/validators/table/size.py +285 -0
- truthound/validators/timeout/__init__.py +102 -0
- truthound/validators/timeout/advanced/__init__.py +247 -0
- truthound/validators/timeout/advanced/circuit_breaker.py +675 -0
- truthound/validators/timeout/advanced/prediction.py +773 -0
- truthound/validators/timeout/advanced/priority.py +618 -0
- truthound/validators/timeout/advanced/redis_backend.py +770 -0
- truthound/validators/timeout/advanced/retry.py +721 -0
- truthound/validators/timeout/advanced/sampling.py +788 -0
- truthound/validators/timeout/advanced/sla.py +661 -0
- truthound/validators/timeout/advanced/telemetry.py +804 -0
- truthound/validators/timeout/cascade.py +477 -0
- truthound/validators/timeout/deadline.py +657 -0
- truthound/validators/timeout/degradation.py +525 -0
- truthound/validators/timeout/distributed.py +597 -0
- truthound/validators/timeseries/__init__.py +89 -0
- truthound/validators/timeseries/base.py +326 -0
- truthound/validators/timeseries/completeness.py +617 -0
- truthound/validators/timeseries/gap.py +485 -0
- truthound/validators/timeseries/monotonic.py +310 -0
- truthound/validators/timeseries/seasonality.py +422 -0
- truthound/validators/timeseries/trend.py +510 -0
- truthound/validators/uniqueness/__init__.py +59 -0
- truthound/validators/uniqueness/approximate.py +475 -0
- truthound/validators/uniqueness/distinct_values.py +253 -0
- truthound/validators/uniqueness/duplicate.py +118 -0
- truthound/validators/uniqueness/primary_key.py +140 -0
- truthound/validators/uniqueness/unique.py +191 -0
- truthound/validators/uniqueness/within_record.py +599 -0
- truthound/validators/utils.py +756 -0
- truthound-1.0.8.dist-info/METADATA +474 -0
- truthound-1.0.8.dist-info/RECORD +877 -0
- truthound-1.0.8.dist-info/WHEEL +4 -0
- truthound-1.0.8.dist-info/entry_points.txt +2 -0
- truthound-1.0.8.dist-info/licenses/LICENSE +190 -0
|
@@ -0,0 +1,643 @@
|
|
|
1
|
+
"""Security protocols for plugin system.
|
|
2
|
+
|
|
3
|
+
This module defines all Protocol interfaces for the plugin security system.
|
|
4
|
+
Following Protocol-first design, all components are defined as runtime-checkable
|
|
5
|
+
Protocols to enable:
|
|
6
|
+
- Type checking at runtime
|
|
7
|
+
- Easy mocking in tests
|
|
8
|
+
- Flexible implementations
|
|
9
|
+
- Clear contracts between components
|
|
10
|
+
|
|
11
|
+
Design Principles:
|
|
12
|
+
1. Protocol-First: All abstractions are Protocol-based
|
|
13
|
+
2. Immutable Data: Configuration uses frozen dataclasses
|
|
14
|
+
3. Fail-Safe Defaults: Default values are always secure
|
|
15
|
+
4. Composition: Components can be composed via dependency injection
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from __future__ import annotations
|
|
19
|
+
|
|
20
|
+
from abc import abstractmethod
|
|
21
|
+
from dataclasses import dataclass, field
|
|
22
|
+
from datetime import datetime, timezone
|
|
23
|
+
from enum import Enum, auto
|
|
24
|
+
from pathlib import Path
|
|
25
|
+
from typing import (
|
|
26
|
+
TYPE_CHECKING,
|
|
27
|
+
Any,
|
|
28
|
+
Callable,
|
|
29
|
+
Protocol,
|
|
30
|
+
TypeVar,
|
|
31
|
+
runtime_checkable,
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
if TYPE_CHECKING:
|
|
35
|
+
pass
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
# =============================================================================
|
|
39
|
+
# Enumerations
|
|
40
|
+
# =============================================================================
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class IsolationLevel(Enum):
|
|
44
|
+
"""Plugin isolation level.
|
|
45
|
+
|
|
46
|
+
Determines the level of isolation when executing plugin code.
|
|
47
|
+
|
|
48
|
+
Levels:
|
|
49
|
+
NONE: No isolation, code runs in main process (trusted plugins only)
|
|
50
|
+
PROCESS: Separate process with resource limits
|
|
51
|
+
CONTAINER: Docker/Podman container isolation
|
|
52
|
+
WASM: WebAssembly sandbox (most restrictive)
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
NONE = auto()
|
|
56
|
+
PROCESS = auto()
|
|
57
|
+
CONTAINER = auto()
|
|
58
|
+
WASM = auto()
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class TrustLevel(str, Enum):
|
|
62
|
+
"""Trust level for signers and certificates.
|
|
63
|
+
|
|
64
|
+
Values:
|
|
65
|
+
TRUSTED: Fully trusted signer
|
|
66
|
+
VERIFIED: Verified but not fully trusted
|
|
67
|
+
UNKNOWN: Unknown signer
|
|
68
|
+
REVOKED: Revoked certificate/signature
|
|
69
|
+
"""
|
|
70
|
+
|
|
71
|
+
TRUSTED = "trusted"
|
|
72
|
+
VERIFIED = "verified"
|
|
73
|
+
UNKNOWN = "unknown"
|
|
74
|
+
REVOKED = "revoked"
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
# =============================================================================
|
|
78
|
+
# Resource and Policy Data Classes
|
|
79
|
+
# =============================================================================
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
@dataclass(frozen=True)
|
|
83
|
+
class ResourceLimits:
|
|
84
|
+
"""Resource limits for sandboxed execution.
|
|
85
|
+
|
|
86
|
+
All limits are enforced by the sandbox engine. Values of 0 or negative
|
|
87
|
+
mean unlimited (not recommended for untrusted code).
|
|
88
|
+
|
|
89
|
+
Attributes:
|
|
90
|
+
max_memory_mb: Maximum memory in megabytes
|
|
91
|
+
max_cpu_percent: Maximum CPU usage (0-100)
|
|
92
|
+
max_execution_time_sec: Maximum execution time in seconds
|
|
93
|
+
max_file_descriptors: Maximum open file descriptors
|
|
94
|
+
allowed_paths: Paths the plugin can access (read-only by default)
|
|
95
|
+
writable_paths: Paths the plugin can write to
|
|
96
|
+
denied_syscalls: System calls to block (Linux-specific)
|
|
97
|
+
"""
|
|
98
|
+
|
|
99
|
+
max_memory_mb: int = 512
|
|
100
|
+
max_cpu_percent: float = 50.0
|
|
101
|
+
max_execution_time_sec: float = 30.0
|
|
102
|
+
max_file_descriptors: int = 100
|
|
103
|
+
allowed_paths: tuple[str, ...] = ()
|
|
104
|
+
writable_paths: tuple[str, ...] = ()
|
|
105
|
+
denied_syscalls: tuple[str, ...] = (
|
|
106
|
+
"fork",
|
|
107
|
+
"vfork",
|
|
108
|
+
"clone",
|
|
109
|
+
"execve",
|
|
110
|
+
"execveat",
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
@classmethod
|
|
114
|
+
def minimal(cls) -> "ResourceLimits":
|
|
115
|
+
"""Create minimal resource limits for untrusted code."""
|
|
116
|
+
return cls(
|
|
117
|
+
max_memory_mb=128,
|
|
118
|
+
max_cpu_percent=25.0,
|
|
119
|
+
max_execution_time_sec=10.0,
|
|
120
|
+
max_file_descriptors=10,
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
@classmethod
|
|
124
|
+
def standard(cls) -> "ResourceLimits":
|
|
125
|
+
"""Create standard resource limits."""
|
|
126
|
+
return cls()
|
|
127
|
+
|
|
128
|
+
@classmethod
|
|
129
|
+
def generous(cls) -> "ResourceLimits":
|
|
130
|
+
"""Create generous resource limits for trusted code."""
|
|
131
|
+
return cls(
|
|
132
|
+
max_memory_mb=2048,
|
|
133
|
+
max_cpu_percent=100.0,
|
|
134
|
+
max_execution_time_sec=300.0,
|
|
135
|
+
max_file_descriptors=1000,
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
@dataclass(frozen=True)
|
|
140
|
+
class SecurityPolicy:
|
|
141
|
+
"""Comprehensive security policy for plugin execution.
|
|
142
|
+
|
|
143
|
+
This policy controls all aspects of plugin security including isolation,
|
|
144
|
+
resource limits, network access, and signature requirements.
|
|
145
|
+
|
|
146
|
+
Attributes:
|
|
147
|
+
isolation_level: Level of process isolation
|
|
148
|
+
resource_limits: Resource usage limits
|
|
149
|
+
allow_network: Whether network access is allowed
|
|
150
|
+
allow_subprocess: Whether spawning subprocesses is allowed
|
|
151
|
+
allow_file_write: Whether writing to files is allowed
|
|
152
|
+
allowed_modules: Python modules the plugin can import
|
|
153
|
+
blocked_modules: Python modules the plugin cannot import
|
|
154
|
+
required_signatures: Minimum number of valid signatures required
|
|
155
|
+
require_trusted_signer: Whether signer must be in trust store
|
|
156
|
+
signature_max_age_days: Maximum age of signature in days (0 = no limit)
|
|
157
|
+
"""
|
|
158
|
+
|
|
159
|
+
isolation_level: IsolationLevel = IsolationLevel.PROCESS
|
|
160
|
+
resource_limits: ResourceLimits = field(default_factory=ResourceLimits)
|
|
161
|
+
allow_network: bool = False
|
|
162
|
+
allow_subprocess: bool = False
|
|
163
|
+
allow_file_write: bool = False
|
|
164
|
+
allowed_modules: tuple[str, ...] = (
|
|
165
|
+
"polars",
|
|
166
|
+
"numpy",
|
|
167
|
+
"pandas",
|
|
168
|
+
"truthound",
|
|
169
|
+
"json",
|
|
170
|
+
"datetime",
|
|
171
|
+
"dataclasses",
|
|
172
|
+
"typing",
|
|
173
|
+
"collections",
|
|
174
|
+
"itertools",
|
|
175
|
+
"functools",
|
|
176
|
+
"math",
|
|
177
|
+
"statistics",
|
|
178
|
+
"re",
|
|
179
|
+
"hashlib",
|
|
180
|
+
"base64",
|
|
181
|
+
)
|
|
182
|
+
blocked_modules: tuple[str, ...] = (
|
|
183
|
+
"os",
|
|
184
|
+
"subprocess",
|
|
185
|
+
"shutil",
|
|
186
|
+
"socket",
|
|
187
|
+
"urllib",
|
|
188
|
+
"requests",
|
|
189
|
+
"http",
|
|
190
|
+
"ftplib",
|
|
191
|
+
"smtplib",
|
|
192
|
+
"telnetlib",
|
|
193
|
+
"ctypes",
|
|
194
|
+
"multiprocessing",
|
|
195
|
+
"threading",
|
|
196
|
+
"asyncio.subprocess",
|
|
197
|
+
"sys",
|
|
198
|
+
"importlib",
|
|
199
|
+
"builtins",
|
|
200
|
+
"code",
|
|
201
|
+
"codeop",
|
|
202
|
+
"compile",
|
|
203
|
+
"eval",
|
|
204
|
+
"exec",
|
|
205
|
+
"pickle",
|
|
206
|
+
"marshal",
|
|
207
|
+
)
|
|
208
|
+
required_signatures: int = 1
|
|
209
|
+
require_trusted_signer: bool = True
|
|
210
|
+
signature_max_age_days: int = 365
|
|
211
|
+
|
|
212
|
+
@classmethod
|
|
213
|
+
def strict(cls) -> "SecurityPolicy":
|
|
214
|
+
"""Create strict security policy for untrusted plugins."""
|
|
215
|
+
return cls(
|
|
216
|
+
isolation_level=IsolationLevel.CONTAINER,
|
|
217
|
+
resource_limits=ResourceLimits.minimal(),
|
|
218
|
+
allow_network=False,
|
|
219
|
+
allow_subprocess=False,
|
|
220
|
+
allow_file_write=False,
|
|
221
|
+
required_signatures=2,
|
|
222
|
+
require_trusted_signer=True,
|
|
223
|
+
signature_max_age_days=90,
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
@classmethod
|
|
227
|
+
def standard(cls) -> "SecurityPolicy":
|
|
228
|
+
"""Create standard security policy."""
|
|
229
|
+
return cls()
|
|
230
|
+
|
|
231
|
+
@classmethod
|
|
232
|
+
def permissive(cls) -> "SecurityPolicy":
|
|
233
|
+
"""Create permissive policy for trusted plugins."""
|
|
234
|
+
return cls(
|
|
235
|
+
isolation_level=IsolationLevel.NONE,
|
|
236
|
+
resource_limits=ResourceLimits.generous(),
|
|
237
|
+
allow_network=True,
|
|
238
|
+
allow_subprocess=False,
|
|
239
|
+
allow_file_write=True,
|
|
240
|
+
required_signatures=0,
|
|
241
|
+
require_trusted_signer=False,
|
|
242
|
+
signature_max_age_days=0,
|
|
243
|
+
)
|
|
244
|
+
|
|
245
|
+
@classmethod
|
|
246
|
+
def development(cls) -> "SecurityPolicy":
|
|
247
|
+
"""Create development policy (no security checks)."""
|
|
248
|
+
return cls(
|
|
249
|
+
isolation_level=IsolationLevel.NONE,
|
|
250
|
+
resource_limits=ResourceLimits.generous(),
|
|
251
|
+
allow_network=True,
|
|
252
|
+
allow_subprocess=True,
|
|
253
|
+
allow_file_write=True,
|
|
254
|
+
allowed_modules=(), # Empty means all allowed
|
|
255
|
+
blocked_modules=(), # Empty means none blocked
|
|
256
|
+
required_signatures=0,
|
|
257
|
+
require_trusted_signer=False,
|
|
258
|
+
)
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
# =============================================================================
|
|
262
|
+
# Sandbox Protocols
|
|
263
|
+
# =============================================================================
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
@runtime_checkable
|
|
267
|
+
class SandboxContext(Protocol):
|
|
268
|
+
"""Context for sandbox execution.
|
|
269
|
+
|
|
270
|
+
Represents a sandboxed execution environment with its configuration
|
|
271
|
+
and current state.
|
|
272
|
+
"""
|
|
273
|
+
|
|
274
|
+
@property
|
|
275
|
+
def plugin_id(self) -> str:
|
|
276
|
+
"""Unique identifier of the plugin being sandboxed."""
|
|
277
|
+
...
|
|
278
|
+
|
|
279
|
+
@property
|
|
280
|
+
def policy(self) -> SecurityPolicy:
|
|
281
|
+
"""Security policy for this sandbox."""
|
|
282
|
+
...
|
|
283
|
+
|
|
284
|
+
@property
|
|
285
|
+
def sandbox_id(self) -> str:
|
|
286
|
+
"""Unique identifier for this sandbox instance."""
|
|
287
|
+
...
|
|
288
|
+
|
|
289
|
+
def is_alive(self) -> bool:
|
|
290
|
+
"""Check if sandbox is still running.
|
|
291
|
+
|
|
292
|
+
Returns:
|
|
293
|
+
True if sandbox process/container is running
|
|
294
|
+
"""
|
|
295
|
+
...
|
|
296
|
+
|
|
297
|
+
def get_resource_usage(self) -> dict[str, float]:
|
|
298
|
+
"""Get current resource usage.
|
|
299
|
+
|
|
300
|
+
Returns:
|
|
301
|
+
Dict with keys: memory_mb, cpu_percent, execution_time_sec
|
|
302
|
+
"""
|
|
303
|
+
...
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
@runtime_checkable
|
|
307
|
+
class SandboxEngine(Protocol):
|
|
308
|
+
"""Engine for creating and managing sandboxed execution environments.
|
|
309
|
+
|
|
310
|
+
Implementations provide different isolation mechanisms:
|
|
311
|
+
- ProcessSandbox: Subprocess with resource limits
|
|
312
|
+
- ContainerSandbox: Docker/Podman containers
|
|
313
|
+
- WasmSandbox: WebAssembly isolation
|
|
314
|
+
"""
|
|
315
|
+
|
|
316
|
+
@property
|
|
317
|
+
def isolation_level(self) -> IsolationLevel:
|
|
318
|
+
"""The isolation level provided by this engine."""
|
|
319
|
+
...
|
|
320
|
+
|
|
321
|
+
def create_sandbox(
|
|
322
|
+
self,
|
|
323
|
+
plugin_id: str,
|
|
324
|
+
policy: SecurityPolicy,
|
|
325
|
+
) -> SandboxContext:
|
|
326
|
+
"""Create a new sandbox context for a plugin.
|
|
327
|
+
|
|
328
|
+
Args:
|
|
329
|
+
plugin_id: Unique identifier for the plugin
|
|
330
|
+
policy: Security policy to apply
|
|
331
|
+
|
|
332
|
+
Returns:
|
|
333
|
+
SandboxContext for execution
|
|
334
|
+
"""
|
|
335
|
+
...
|
|
336
|
+
|
|
337
|
+
async def execute(
|
|
338
|
+
self,
|
|
339
|
+
context: SandboxContext,
|
|
340
|
+
func: Callable[..., Any],
|
|
341
|
+
*args: Any,
|
|
342
|
+
**kwargs: Any,
|
|
343
|
+
) -> Any:
|
|
344
|
+
"""Execute a function within the sandbox.
|
|
345
|
+
|
|
346
|
+
Args:
|
|
347
|
+
context: Sandbox context to use
|
|
348
|
+
func: Function to execute
|
|
349
|
+
*args: Positional arguments for func
|
|
350
|
+
**kwargs: Keyword arguments for func
|
|
351
|
+
|
|
352
|
+
Returns:
|
|
353
|
+
Result of function execution
|
|
354
|
+
|
|
355
|
+
Raises:
|
|
356
|
+
SandboxTimeoutError: If execution times out
|
|
357
|
+
SandboxResourceError: If resource limits exceeded
|
|
358
|
+
SandboxSecurityViolation: If security policy violated
|
|
359
|
+
"""
|
|
360
|
+
...
|
|
361
|
+
|
|
362
|
+
def terminate(self, context: SandboxContext) -> None:
|
|
363
|
+
"""Terminate a sandbox.
|
|
364
|
+
|
|
365
|
+
Args:
|
|
366
|
+
context: Sandbox to terminate
|
|
367
|
+
"""
|
|
368
|
+
...
|
|
369
|
+
|
|
370
|
+
async def cleanup(self) -> None:
|
|
371
|
+
"""Clean up all sandbox resources."""
|
|
372
|
+
...
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
# =============================================================================
|
|
376
|
+
# Signing Protocols
|
|
377
|
+
# =============================================================================
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
@dataclass(frozen=True)
|
|
381
|
+
class SignatureInfo:
|
|
382
|
+
"""Information about a plugin signature.
|
|
383
|
+
|
|
384
|
+
Attributes:
|
|
385
|
+
signer_id: Identifier of the signer
|
|
386
|
+
algorithm: Algorithm used for signing (e.g., "RSA-SHA256", "Ed25519")
|
|
387
|
+
signature: Base64-encoded signature bytes
|
|
388
|
+
timestamp: When the signature was created
|
|
389
|
+
expires_at: When the signature expires (None = never)
|
|
390
|
+
certificate_chain: Chain of certificates (issuer chain)
|
|
391
|
+
metadata: Additional metadata about the signature
|
|
392
|
+
"""
|
|
393
|
+
|
|
394
|
+
signer_id: str
|
|
395
|
+
algorithm: str
|
|
396
|
+
signature: bytes
|
|
397
|
+
timestamp: datetime = field(default_factory=lambda: datetime.now(timezone.utc))
|
|
398
|
+
expires_at: datetime | None = None
|
|
399
|
+
certificate_chain: tuple[bytes, ...] = ()
|
|
400
|
+
metadata: dict[str, Any] = field(default_factory=dict)
|
|
401
|
+
|
|
402
|
+
def is_expired(self) -> bool:
|
|
403
|
+
"""Check if signature has expired."""
|
|
404
|
+
if self.expires_at is None:
|
|
405
|
+
return False
|
|
406
|
+
return datetime.now(timezone.utc) > self.expires_at
|
|
407
|
+
|
|
408
|
+
@property
|
|
409
|
+
def age_days(self) -> int:
|
|
410
|
+
"""Get age of signature in days."""
|
|
411
|
+
delta = datetime.now(timezone.utc) - self.timestamp
|
|
412
|
+
return delta.days
|
|
413
|
+
|
|
414
|
+
|
|
415
|
+
@dataclass(frozen=True)
|
|
416
|
+
class VerificationResult:
|
|
417
|
+
"""Result of signature verification.
|
|
418
|
+
|
|
419
|
+
Attributes:
|
|
420
|
+
is_valid: Whether signature is valid
|
|
421
|
+
signer_id: ID of the signer (if verified)
|
|
422
|
+
trust_level: Trust level of the signer
|
|
423
|
+
errors: List of error messages (if any)
|
|
424
|
+
warnings: List of warning messages (if any)
|
|
425
|
+
verified_at: When verification was performed
|
|
426
|
+
"""
|
|
427
|
+
|
|
428
|
+
is_valid: bool
|
|
429
|
+
signer_id: str | None = None
|
|
430
|
+
trust_level: TrustLevel = TrustLevel.UNKNOWN
|
|
431
|
+
errors: tuple[str, ...] = ()
|
|
432
|
+
warnings: tuple[str, ...] = ()
|
|
433
|
+
verified_at: datetime = field(default_factory=lambda: datetime.now(timezone.utc))
|
|
434
|
+
|
|
435
|
+
@classmethod
|
|
436
|
+
def success(
|
|
437
|
+
cls,
|
|
438
|
+
signer_id: str,
|
|
439
|
+
trust_level: TrustLevel = TrustLevel.TRUSTED,
|
|
440
|
+
warnings: tuple[str, ...] = (),
|
|
441
|
+
) -> "VerificationResult":
|
|
442
|
+
"""Create successful verification result."""
|
|
443
|
+
return cls(
|
|
444
|
+
is_valid=True,
|
|
445
|
+
signer_id=signer_id,
|
|
446
|
+
trust_level=trust_level,
|
|
447
|
+
warnings=warnings,
|
|
448
|
+
)
|
|
449
|
+
|
|
450
|
+
@classmethod
|
|
451
|
+
def failure(cls, *errors: str) -> "VerificationResult":
|
|
452
|
+
"""Create failed verification result."""
|
|
453
|
+
return cls(
|
|
454
|
+
is_valid=False,
|
|
455
|
+
errors=errors,
|
|
456
|
+
)
|
|
457
|
+
|
|
458
|
+
|
|
459
|
+
@runtime_checkable
|
|
460
|
+
class SigningService(Protocol):
|
|
461
|
+
"""Service for signing and verifying plugins.
|
|
462
|
+
|
|
463
|
+
Provides cryptographic signing and verification of plugin code
|
|
464
|
+
to ensure integrity and authenticity.
|
|
465
|
+
"""
|
|
466
|
+
|
|
467
|
+
def sign(
|
|
468
|
+
self,
|
|
469
|
+
plugin_path: Path,
|
|
470
|
+
private_key: bytes,
|
|
471
|
+
certificate: bytes | None = None,
|
|
472
|
+
metadata: dict[str, Any] | None = None,
|
|
473
|
+
) -> SignatureInfo:
|
|
474
|
+
"""Sign a plugin.
|
|
475
|
+
|
|
476
|
+
Args:
|
|
477
|
+
plugin_path: Path to plugin file or directory
|
|
478
|
+
private_key: PEM-encoded private key
|
|
479
|
+
certificate: Optional X.509 certificate
|
|
480
|
+
metadata: Additional metadata to include
|
|
481
|
+
|
|
482
|
+
Returns:
|
|
483
|
+
SignatureInfo with signature details
|
|
484
|
+
"""
|
|
485
|
+
...
|
|
486
|
+
|
|
487
|
+
def verify(
|
|
488
|
+
self,
|
|
489
|
+
plugin_path: Path,
|
|
490
|
+
signature: SignatureInfo,
|
|
491
|
+
) -> VerificationResult:
|
|
492
|
+
"""Verify a plugin signature.
|
|
493
|
+
|
|
494
|
+
Args:
|
|
495
|
+
plugin_path: Path to plugin file or directory
|
|
496
|
+
signature: Signature to verify
|
|
497
|
+
|
|
498
|
+
Returns:
|
|
499
|
+
VerificationResult with verification status
|
|
500
|
+
"""
|
|
501
|
+
...
|
|
502
|
+
|
|
503
|
+
def get_plugin_hash(self, plugin_path: Path) -> str:
|
|
504
|
+
"""Get hash of plugin content for signing.
|
|
505
|
+
|
|
506
|
+
Args:
|
|
507
|
+
plugin_path: Path to plugin
|
|
508
|
+
|
|
509
|
+
Returns:
|
|
510
|
+
Hex-encoded hash of plugin content
|
|
511
|
+
"""
|
|
512
|
+
...
|
|
513
|
+
|
|
514
|
+
|
|
515
|
+
@runtime_checkable
|
|
516
|
+
class TrustStore(Protocol):
|
|
517
|
+
"""Store for trusted certificates and signers.
|
|
518
|
+
|
|
519
|
+
Manages the set of trusted certificates and signers that are
|
|
520
|
+
allowed to sign plugins.
|
|
521
|
+
"""
|
|
522
|
+
|
|
523
|
+
def add_trusted_certificate(
|
|
524
|
+
self,
|
|
525
|
+
certificate: bytes,
|
|
526
|
+
trust_level: TrustLevel = TrustLevel.TRUSTED,
|
|
527
|
+
metadata: dict[str, Any] | None = None,
|
|
528
|
+
) -> str:
|
|
529
|
+
"""Add a certificate to the trust store.
|
|
530
|
+
|
|
531
|
+
Args:
|
|
532
|
+
certificate: DER or PEM encoded certificate
|
|
533
|
+
trust_level: Trust level for this certificate
|
|
534
|
+
metadata: Additional metadata
|
|
535
|
+
|
|
536
|
+
Returns:
|
|
537
|
+
Certificate ID
|
|
538
|
+
"""
|
|
539
|
+
...
|
|
540
|
+
|
|
541
|
+
def remove_certificate(self, cert_id: str) -> bool:
|
|
542
|
+
"""Remove a certificate from trust store.
|
|
543
|
+
|
|
544
|
+
Args:
|
|
545
|
+
cert_id: Certificate ID
|
|
546
|
+
|
|
547
|
+
Returns:
|
|
548
|
+
True if removed, False if not found
|
|
549
|
+
"""
|
|
550
|
+
...
|
|
551
|
+
|
|
552
|
+
def revoke_certificate(
|
|
553
|
+
self,
|
|
554
|
+
cert_id: str,
|
|
555
|
+
reason: str = "",
|
|
556
|
+
) -> bool:
|
|
557
|
+
"""Revoke a certificate.
|
|
558
|
+
|
|
559
|
+
Args:
|
|
560
|
+
cert_id: Certificate ID
|
|
561
|
+
reason: Reason for revocation
|
|
562
|
+
|
|
563
|
+
Returns:
|
|
564
|
+
True if revoked, False if not found
|
|
565
|
+
"""
|
|
566
|
+
...
|
|
567
|
+
|
|
568
|
+
def is_trusted(self, certificate: bytes) -> tuple[bool, TrustLevel]:
|
|
569
|
+
"""Check if certificate is trusted.
|
|
570
|
+
|
|
571
|
+
Args:
|
|
572
|
+
certificate: Certificate to check
|
|
573
|
+
|
|
574
|
+
Returns:
|
|
575
|
+
Tuple of (is_trusted, trust_level)
|
|
576
|
+
"""
|
|
577
|
+
...
|
|
578
|
+
|
|
579
|
+
def get_trust_level(self, signer_id: str) -> TrustLevel:
|
|
580
|
+
"""Get trust level for a signer.
|
|
581
|
+
|
|
582
|
+
Args:
|
|
583
|
+
signer_id: Signer identifier
|
|
584
|
+
|
|
585
|
+
Returns:
|
|
586
|
+
Trust level of the signer
|
|
587
|
+
"""
|
|
588
|
+
...
|
|
589
|
+
|
|
590
|
+
def list_certificates(self) -> list[dict[str, Any]]:
|
|
591
|
+
"""List all certificates in store.
|
|
592
|
+
|
|
593
|
+
Returns:
|
|
594
|
+
List of certificate info dicts
|
|
595
|
+
"""
|
|
596
|
+
...
|
|
597
|
+
|
|
598
|
+
|
|
599
|
+
@runtime_checkable
|
|
600
|
+
class VerificationHandler(Protocol):
|
|
601
|
+
"""Handler in verification chain.
|
|
602
|
+
|
|
603
|
+
Implements Chain of Responsibility pattern for multi-step
|
|
604
|
+
signature verification.
|
|
605
|
+
"""
|
|
606
|
+
|
|
607
|
+
def set_next(self, handler: "VerificationHandler") -> "VerificationHandler":
|
|
608
|
+
"""Set the next handler in the chain.
|
|
609
|
+
|
|
610
|
+
Args:
|
|
611
|
+
handler: Next handler
|
|
612
|
+
|
|
613
|
+
Returns:
|
|
614
|
+
The next handler (for chaining)
|
|
615
|
+
"""
|
|
616
|
+
...
|
|
617
|
+
|
|
618
|
+
def verify(
|
|
619
|
+
self,
|
|
620
|
+
plugin_path: Path,
|
|
621
|
+
signature: SignatureInfo,
|
|
622
|
+
context: dict[str, Any],
|
|
623
|
+
) -> VerificationResult | None:
|
|
624
|
+
"""Verify signature in this step of the chain.
|
|
625
|
+
|
|
626
|
+
Args:
|
|
627
|
+
plugin_path: Path to plugin
|
|
628
|
+
signature: Signature to verify
|
|
629
|
+
context: Shared context for chain
|
|
630
|
+
|
|
631
|
+
Returns:
|
|
632
|
+
VerificationResult if verification completed (success or failure),
|
|
633
|
+
None to continue to next handler
|
|
634
|
+
"""
|
|
635
|
+
...
|
|
636
|
+
|
|
637
|
+
|
|
638
|
+
# =============================================================================
|
|
639
|
+
# Type Variables
|
|
640
|
+
# =============================================================================
|
|
641
|
+
|
|
642
|
+
T = TypeVar("T")
|
|
643
|
+
SandboxEngineT = TypeVar("SandboxEngineT", bound=SandboxEngine)
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"""Sandbox execution module for plugin isolation.
|
|
2
|
+
|
|
3
|
+
This module provides sandbox implementations for executing plugin code
|
|
4
|
+
in isolated environments with resource limits and security restrictions.
|
|
5
|
+
|
|
6
|
+
Architecture:
|
|
7
|
+
SandboxFactory creates the appropriate SandboxEngine based on
|
|
8
|
+
the requested isolation level. Each engine implements the SandboxEngine
|
|
9
|
+
protocol and provides a different level of isolation.
|
|
10
|
+
|
|
11
|
+
Available Engines:
|
|
12
|
+
- NoopSandbox: No isolation (for trusted plugins)
|
|
13
|
+
- ProcessSandbox: Subprocess with resource limits
|
|
14
|
+
- ContainerSandbox: Docker/Podman container
|
|
15
|
+
- WasmSandbox: WebAssembly sandbox (future)
|
|
16
|
+
|
|
17
|
+
Example:
|
|
18
|
+
>>> from truthound.plugins.security.sandbox import (
|
|
19
|
+
... SandboxFactory,
|
|
20
|
+
... ProcessSandboxEngine,
|
|
21
|
+
... )
|
|
22
|
+
>>> from truthound.plugins.security import SecurityPolicy
|
|
23
|
+
>>>
|
|
24
|
+
>>> # Create sandbox via factory
|
|
25
|
+
>>> policy = SecurityPolicy.standard()
|
|
26
|
+
>>> engine = SandboxFactory.create(policy.isolation_level)
|
|
27
|
+
>>> context = engine.create_sandbox("my-plugin", policy)
|
|
28
|
+
>>> result = await engine.execute(context, my_func, arg1, arg2)
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
from __future__ import annotations
|
|
32
|
+
|
|
33
|
+
from truthound.plugins.security.sandbox.factory import SandboxFactory
|
|
34
|
+
from truthound.plugins.security.sandbox.context import SandboxContextImpl
|
|
35
|
+
from truthound.plugins.security.sandbox.engines.noop import NoopSandboxEngine
|
|
36
|
+
from truthound.plugins.security.sandbox.engines.process import ProcessSandboxEngine
|
|
37
|
+
from truthound.plugins.security.sandbox.engines.container import ContainerSandboxEngine
|
|
38
|
+
|
|
39
|
+
__all__ = [
|
|
40
|
+
"SandboxFactory",
|
|
41
|
+
"SandboxContextImpl",
|
|
42
|
+
"NoopSandboxEngine",
|
|
43
|
+
"ProcessSandboxEngine",
|
|
44
|
+
"ContainerSandboxEngine",
|
|
45
|
+
]
|