ciphergate-cli 0.7.1__tar.gz → 0.8.0__tar.gz
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.
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/CHANGELOG.md +11 -1
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/PKG-INFO +11 -2
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/README.md +10 -1
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/__init__.py +6 -1
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/policy/templates.py +6 -0
- ciphergate_cli-0.8.0/tests/unit/test_policy_templates.py +55 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/.gitignore +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/LICENSE +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/NOTICE +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/SECURITY.md +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/docs/architecture.md +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/docs/claude-code-tooling.md +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/docs/detector-coverage.md +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/docs/examples.md +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/docs/limitations.md +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/docs/policy-schema.md +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/docs/security-and-privacy.md +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/docs/threat-model.md +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/examples/expected/sample.dev_local_dev.csv +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/examples/expected/sample.dev_local_dev.json +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/examples/expected/sample.dev_local_dev.jsonl +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/examples/expected/sample.dev_local_dev.log +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/examples/sample.csv +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/examples/sample.json +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/examples/sample.jsonl +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/examples/sample.log +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/policies/dev_local.yml +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/policies/developer_logs.yml +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/policies/external_ai.yml +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/policies/financial_template.yml +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/policies/healthcare_template.yml +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/policies/local_debug.yml +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/policies/multi_environment.yml +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/policies/prd_external_ai.yml +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/policies/stg_test.yml +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/policies/test_dataset.yml +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/pyproject.toml +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/__main__.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/cli.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/config.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/constants.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/detectors/__init__.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/detectors/base.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/detectors/custom_regex.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/detectors/dates.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/detectors/email.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/detectors/field_names.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/detectors/ip_address.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/detectors/network.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/detectors/payment_card.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/detectors/phone.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/detectors/presidio_ner.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/detectors/regex_safety.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/detectors/registry.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/detectors/secrets.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/errors.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/models/__init__.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/models/context.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/models/finding.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/models/policy.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/models/report.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/pipeline/__init__.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/pipeline/atomic_output.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/pipeline/batch.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/pipeline/inspector.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/pipeline/paths.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/pipeline/planner.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/pipeline/rescan.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/pipeline/sanitizer.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/pipeline/stdio.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/pipeline/streams.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/policy/__init__.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/policy/context.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/policy/engine.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/policy/loader.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/policy/precedence.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/policy/validator.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/py.typed +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/readers/__init__.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/readers/accesslog_reader.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/readers/base.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/readers/csv_reader.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/readers/json_reader.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/readers/jsonl_reader.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/readers/jsonlog_reader.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/readers/line_structure.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/readers/logfmt_reader.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/readers/stacktrace_reader.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/readers/syslog_reader.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/readers/text_reader.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/reporting/__init__.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/reporting/audit.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/reporting/safe_text.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/reporting/serializer.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/reporting/terminal.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/templates/starter_policy.yml +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/transforms/__init__.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/transforms/date_shift.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/transforms/generalize.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/transforms/keys.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/transforms/pseudonymize.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/transforms/redact.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/transforms/registry.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/src/ciphergate/transforms/replace.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/tests/__init__.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/tests/conftest.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/tests/integration/__init__.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/tests/integration/test_api_batch_streams.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/tests/integration/test_atomic_output.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/tests/integration/test_batch.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/tests/integration/test_cli_e2e.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/tests/integration/test_domain_templates.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/tests/integration/test_environment_matrix.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/tests/integration/test_pipelines.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/tests/integration/test_stdio.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/tests/regression/__init__.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/tests/regression/test_known_cases.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/tests/security/__init__.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/tests/security/test_key_file.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/tests/security/test_no_network.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/tests/security/test_no_raw_value_leaks.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/tests/security/test_path_safety.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/tests/security/test_policy_fail_closed.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/tests/security/test_review_findings.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/tests/tooling/__init__.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/tests/tooling/test_ci_supply_chain.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/tests/tooling/test_claude_tooling.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/tests/tooling/test_git_tooling.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/tests/tooling/test_publish_workflow.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/tests/unit/__init__.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/tests/unit/test_accesslog.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/tests/unit/test_detectors.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/tests/unit/test_jsonlog.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/tests/unit/test_logfmt.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/tests/unit/test_policy_engine.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/tests/unit/test_policy_precedence.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/tests/unit/test_policy_validation.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/tests/unit/test_presidio_ner.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/tests/unit/test_properties.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/tests/unit/test_readers.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/tests/unit/test_stacktrace.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/tests/unit/test_syslog.py +0 -0
- {ciphergate_cli-0.7.1 → ciphergate_cli-0.8.0}/tests/unit/test_transforms.py +0 -0
|
@@ -6,6 +6,15 @@ versioning: [PEP 440](https://peps.python.org/pep-0440/) with SemVer meaning (pr
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.8.0] - 2026-10-30
|
|
10
|
+
|
|
11
|
+
Adds the packaged policy templates to the Python API. Existing behaviour is unchanged.
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- Python API for the packaged policy templates: `load_template(name)` returns a `Policy` and
|
|
16
|
+
`template_names()` lists the names. An unknown name raises `UsageError`.
|
|
17
|
+
|
|
9
18
|
## [0.7.1] - 2026-10-30
|
|
10
19
|
|
|
11
20
|
Makes the starter policy templates available after `pip install`. Existing commands and
|
|
@@ -270,7 +279,8 @@ Pre-release (alpha). Licensed under Apache-2.0. Not a final release: the securit
|
|
|
270
279
|
See `docs/limitations.md`. Deferred: optional NER/Presidio detectors, stdin/stdout streaming,
|
|
271
280
|
directory processing, structured log parsers, key files, reversible token vault, lossy decoding.
|
|
272
281
|
|
|
273
|
-
[Unreleased]: https://github.com/aashishkumar-tech/ciphergate/compare/v0.
|
|
282
|
+
[Unreleased]: https://github.com/aashishkumar-tech/ciphergate/compare/v0.8.0...HEAD
|
|
283
|
+
[0.8.0]: https://github.com/aashishkumar-tech/ciphergate/compare/v0.7.1...v0.8.0
|
|
274
284
|
[0.7.1]: https://github.com/aashishkumar-tech/ciphergate/compare/v0.7.0...v0.7.1
|
|
275
285
|
[0.7.0]: https://github.com/aashishkumar-tech/ciphergate/compare/v0.6.1...v0.7.0
|
|
276
286
|
[0.6.1]: https://github.com/aashishkumar-tech/ciphergate/compare/v0.6.0...v0.6.1
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: ciphergate-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.8.0
|
|
4
4
|
Summary: Local-first, environment- and destination-aware inspection and sanitization of logs and test datasets.
|
|
5
5
|
Project-URL: Homepage, https://github.com/aashishkumar-tech/ciphergate
|
|
6
6
|
Project-URL: Source, https://github.com/aashishkumar-tech/ciphergate
|
|
@@ -50,7 +50,7 @@ vendor ticket. CipherGate replaces that with a local, explainable, scriptable ga
|
|
|
50
50
|
inspect -> plan -> sanitize --apply -> rescan
|
|
51
51
|
```
|
|
52
52
|
|
|
53
|
-
> **Status: 0.
|
|
53
|
+
> **Status: 0.8.0 (alpha).** No detector finds every sensitive value. A passing run means the
|
|
54
54
|
> configured processing completed under the selected policy; it is **not** proof that the output
|
|
55
55
|
> contains no sensitive information, and it is not a compliance (GDPR, HIPAA, PCI DSS, ...) or
|
|
56
56
|
> anonymization guarantee. Policy templates must be reviewed before use.
|
|
@@ -494,6 +494,15 @@ report = sanitize_file("app.log", "app.clean.log", policy,
|
|
|
494
494
|
print(report.status, report.exit_code)
|
|
495
495
|
```
|
|
496
496
|
|
|
497
|
+
After `pip install`, there is no `policies/` folder. Load a packaged template by name instead;
|
|
498
|
+
`template_names()` lists them. Templates require review for your data and destination.
|
|
499
|
+
|
|
500
|
+
```python
|
|
501
|
+
from ciphergate import load_template, template_names
|
|
502
|
+
print(template_names())
|
|
503
|
+
policy = load_template("developer_logs")
|
|
504
|
+
```
|
|
505
|
+
|
|
497
506
|
Streams and directories use the same pipeline and the same safety rules as the CLI:
|
|
498
507
|
|
|
499
508
|
```python
|
|
@@ -11,7 +11,7 @@ vendor ticket. CipherGate replaces that with a local, explainable, scriptable ga
|
|
|
11
11
|
inspect -> plan -> sanitize --apply -> rescan
|
|
12
12
|
```
|
|
13
13
|
|
|
14
|
-
> **Status: 0.
|
|
14
|
+
> **Status: 0.8.0 (alpha).** No detector finds every sensitive value. A passing run means the
|
|
15
15
|
> configured processing completed under the selected policy; it is **not** proof that the output
|
|
16
16
|
> contains no sensitive information, and it is not a compliance (GDPR, HIPAA, PCI DSS, ...) or
|
|
17
17
|
> anonymization guarantee. Policy templates must be reviewed before use.
|
|
@@ -455,6 +455,15 @@ report = sanitize_file("app.log", "app.clean.log", policy,
|
|
|
455
455
|
print(report.status, report.exit_code)
|
|
456
456
|
```
|
|
457
457
|
|
|
458
|
+
After `pip install`, there is no `policies/` folder. Load a packaged template by name instead;
|
|
459
|
+
`template_names()` lists them. Templates require review for your data and destination.
|
|
460
|
+
|
|
461
|
+
```python
|
|
462
|
+
from ciphergate import load_template, template_names
|
|
463
|
+
print(template_names())
|
|
464
|
+
policy = load_template("developer_logs")
|
|
465
|
+
```
|
|
466
|
+
|
|
458
467
|
Streams and directories use the same pipeline and the same safety rules as the CLI:
|
|
459
468
|
|
|
460
469
|
```python
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
Supported public API (everything else is internal and may change without notice)::
|
|
4
4
|
|
|
5
5
|
load_policy(path) -> Policy
|
|
6
|
+
load_template(name) -> Policy # a packaged template; review it before relying on it
|
|
7
|
+
template_names() -> list[str]
|
|
6
8
|
validate_policy(path_or_policy) -> ValidationResult
|
|
7
9
|
inspect_file(path, policy, context=None) -> RunReport
|
|
8
10
|
plan_file(path, policy, context=None) -> RunReport
|
|
@@ -22,7 +24,7 @@ Supported public API (everything else is internal and may change without notice)
|
|
|
22
24
|
rescan_directory(root, policy, context=None, *, recursive=False, strict=None) -> BatchReport
|
|
23
25
|
"""
|
|
24
26
|
|
|
25
|
-
__version__ = "0.
|
|
27
|
+
__version__ = "0.8.0"
|
|
26
28
|
|
|
27
29
|
from ciphergate.config import RuntimeSettings
|
|
28
30
|
from ciphergate.constants import (
|
|
@@ -55,6 +57,7 @@ from ciphergate.pipeline.streams import (
|
|
|
55
57
|
rescan_stream,
|
|
56
58
|
sanitize_stream,
|
|
57
59
|
)
|
|
60
|
+
from ciphergate.policy.templates import load_template, template_names
|
|
58
61
|
from ciphergate.policy.validator import (
|
|
59
62
|
Policy,
|
|
60
63
|
ValidationResult,
|
|
@@ -82,6 +85,7 @@ __all__ = [
|
|
|
82
85
|
"inspect_file",
|
|
83
86
|
"inspect_stream",
|
|
84
87
|
"load_policy",
|
|
88
|
+
"load_template",
|
|
85
89
|
"plan_directory",
|
|
86
90
|
"plan_file",
|
|
87
91
|
"plan_stream",
|
|
@@ -91,5 +95,6 @@ __all__ = [
|
|
|
91
95
|
"sanitize_directory",
|
|
92
96
|
"sanitize_file",
|
|
93
97
|
"sanitize_stream",
|
|
98
|
+
"template_names",
|
|
94
99
|
"validate_policy",
|
|
95
100
|
]
|
|
@@ -7,6 +7,7 @@ from importlib.resources.abc import Traversable
|
|
|
7
7
|
from pathlib import Path
|
|
8
8
|
|
|
9
9
|
from ciphergate.errors import UsageError
|
|
10
|
+
from ciphergate.policy.validator import Policy, load_policy_text
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
def _templates_dir() -> Traversable:
|
|
@@ -34,3 +35,8 @@ def read_template(name: str) -> str:
|
|
|
34
35
|
code="unknown_policy_template",
|
|
35
36
|
)
|
|
36
37
|
return _templates_dir().joinpath(f"{name}.yml").read_text(encoding="utf-8")
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def load_template(name: str) -> Policy:
|
|
41
|
+
"""Load a named template as a `Policy`. It is a starting point that requires review."""
|
|
42
|
+
return load_policy_text(read_template(name), source_name=f"{name}.yml")
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"""Packaged policy templates through the public Python API."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
import pytest
|
|
8
|
+
|
|
9
|
+
import ciphergate
|
|
10
|
+
from ciphergate import (
|
|
11
|
+
ContextInput,
|
|
12
|
+
RunStatus,
|
|
13
|
+
load_policy,
|
|
14
|
+
load_template,
|
|
15
|
+
sanitize_file,
|
|
16
|
+
template_names,
|
|
17
|
+
)
|
|
18
|
+
from ciphergate.errors import CipherGateError, UsageError
|
|
19
|
+
from tests.conftest import EXAMPLES, POLICIES
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def test_public_exports() -> None:
|
|
23
|
+
for name in ("load_template", "template_names"):
|
|
24
|
+
assert name in ciphergate.__all__ and hasattr(ciphergate, name)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def test_names_match_the_policy_files() -> None:
|
|
28
|
+
assert template_names() == sorted(p.stem for p in POLICIES.glob("*.yml"))
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@pytest.mark.parametrize("name", template_names())
|
|
32
|
+
def test_load_template_matches_the_policy_file(name: str) -> None:
|
|
33
|
+
policy = load_template(name)
|
|
34
|
+
assert policy.name == load_policy(POLICIES / f"{name}.yml").name
|
|
35
|
+
assert policy.source_name == f"{name}.yml"
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@pytest.mark.parametrize("name", ["nope", "../pyproject", "dev_local.yml", ""])
|
|
39
|
+
def test_unknown_template_is_rejected(name: str) -> None:
|
|
40
|
+
with pytest.raises(UsageError) as err:
|
|
41
|
+
load_template(name)
|
|
42
|
+
assert err.value.code == "unknown_policy_template"
|
|
43
|
+
assert isinstance(err.value, CipherGateError)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def test_loaded_template_still_blocks_and_publishes_nothing(tmp_path: Path) -> None:
|
|
47
|
+
output = tmp_path / "out.log"
|
|
48
|
+
report = sanitize_file(
|
|
49
|
+
EXAMPLES / "sample.log",
|
|
50
|
+
output,
|
|
51
|
+
load_template("prd_external_ai"),
|
|
52
|
+
ContextInput(),
|
|
53
|
+
)
|
|
54
|
+
assert report.status == RunStatus.BLOCKED and report.exit_code == 1
|
|
55
|
+
assert not output.exists()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|