ciphergate-cli 0.7.0__tar.gz → 0.7.1__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.0 → ciphergate_cli-0.7.1}/CHANGELOG.md +13 -1
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/PKG-INFO +18 -2
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/README.md +17 -1
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/pyproject.toml +3 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/__init__.py +1 -1
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/cli.py +15 -2
- ciphergate_cli-0.7.1/src/ciphergate/policy/templates.py +36 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/tests/integration/test_cli_e2e.py +30 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/.gitignore +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/LICENSE +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/NOTICE +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/SECURITY.md +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/docs/architecture.md +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/docs/claude-code-tooling.md +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/docs/detector-coverage.md +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/docs/examples.md +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/docs/limitations.md +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/docs/policy-schema.md +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/docs/security-and-privacy.md +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/docs/threat-model.md +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/examples/expected/sample.dev_local_dev.csv +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/examples/expected/sample.dev_local_dev.json +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/examples/expected/sample.dev_local_dev.jsonl +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/examples/expected/sample.dev_local_dev.log +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/examples/sample.csv +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/examples/sample.json +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/examples/sample.jsonl +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/examples/sample.log +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/policies/dev_local.yml +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/policies/developer_logs.yml +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/policies/external_ai.yml +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/policies/financial_template.yml +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/policies/healthcare_template.yml +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/policies/local_debug.yml +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/policies/multi_environment.yml +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/policies/prd_external_ai.yml +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/policies/stg_test.yml +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/policies/test_dataset.yml +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/__main__.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/config.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/constants.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/detectors/__init__.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/detectors/base.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/detectors/custom_regex.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/detectors/dates.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/detectors/email.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/detectors/field_names.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/detectors/ip_address.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/detectors/network.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/detectors/payment_card.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/detectors/phone.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/detectors/presidio_ner.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/detectors/regex_safety.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/detectors/registry.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/detectors/secrets.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/errors.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/models/__init__.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/models/context.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/models/finding.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/models/policy.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/models/report.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/pipeline/__init__.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/pipeline/atomic_output.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/pipeline/batch.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/pipeline/inspector.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/pipeline/paths.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/pipeline/planner.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/pipeline/rescan.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/pipeline/sanitizer.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/pipeline/stdio.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/pipeline/streams.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/policy/__init__.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/policy/context.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/policy/engine.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/policy/loader.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/policy/precedence.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/policy/validator.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/py.typed +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/readers/__init__.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/readers/accesslog_reader.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/readers/base.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/readers/csv_reader.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/readers/json_reader.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/readers/jsonl_reader.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/readers/jsonlog_reader.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/readers/line_structure.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/readers/logfmt_reader.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/readers/stacktrace_reader.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/readers/syslog_reader.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/readers/text_reader.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/reporting/__init__.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/reporting/audit.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/reporting/safe_text.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/reporting/serializer.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/reporting/terminal.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/templates/starter_policy.yml +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/transforms/__init__.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/transforms/date_shift.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/transforms/generalize.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/transforms/keys.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/transforms/pseudonymize.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/transforms/redact.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/transforms/registry.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/src/ciphergate/transforms/replace.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/tests/__init__.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/tests/conftest.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/tests/integration/__init__.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/tests/integration/test_api_batch_streams.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/tests/integration/test_atomic_output.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/tests/integration/test_batch.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/tests/integration/test_domain_templates.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/tests/integration/test_environment_matrix.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/tests/integration/test_pipelines.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/tests/integration/test_stdio.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/tests/regression/__init__.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/tests/regression/test_known_cases.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/tests/security/__init__.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/tests/security/test_key_file.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/tests/security/test_no_network.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/tests/security/test_no_raw_value_leaks.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/tests/security/test_path_safety.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/tests/security/test_policy_fail_closed.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/tests/security/test_review_findings.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/tests/tooling/__init__.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/tests/tooling/test_ci_supply_chain.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/tests/tooling/test_claude_tooling.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/tests/tooling/test_git_tooling.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/tests/tooling/test_publish_workflow.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/tests/unit/__init__.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/tests/unit/test_accesslog.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/tests/unit/test_detectors.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/tests/unit/test_jsonlog.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/tests/unit/test_logfmt.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/tests/unit/test_policy_engine.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/tests/unit/test_policy_precedence.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/tests/unit/test_policy_validation.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/tests/unit/test_presidio_ner.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/tests/unit/test_properties.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/tests/unit/test_readers.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/tests/unit/test_stacktrace.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/tests/unit/test_syslog.py +0 -0
- {ciphergate_cli-0.7.0 → ciphergate_cli-0.7.1}/tests/unit/test_transforms.py +0 -0
|
@@ -6,6 +6,17 @@ versioning: [PEP 440](https://peps.python.org/pep-0440/) with SemVer meaning (pr
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.7.1] - 2026-10-30
|
|
10
|
+
|
|
11
|
+
Makes the starter policy templates available after `pip install`. Existing commands and
|
|
12
|
+
template contents are unchanged.
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- The starter policy templates now ship in the wheel. `ciphergate init --template NAME` writes
|
|
17
|
+
one to a file and `ciphergate init --list-templates` lists them, so a `pip install` no longer
|
|
18
|
+
needs a repository clone to get them. Plain `ciphergate init` is unchanged.
|
|
19
|
+
|
|
9
20
|
## [0.7.0] - 2026-10-30
|
|
10
21
|
|
|
11
22
|
First release published to PyPI. CLI, API and policy behaviour are unchanged, except for the
|
|
@@ -259,7 +270,8 @@ Pre-release (alpha). Licensed under Apache-2.0. Not a final release: the securit
|
|
|
259
270
|
See `docs/limitations.md`. Deferred: optional NER/Presidio detectors, stdin/stdout streaming,
|
|
260
271
|
directory processing, structured log parsers, key files, reversible token vault, lossy decoding.
|
|
261
272
|
|
|
262
|
-
[Unreleased]: https://github.com/aashishkumar-tech/ciphergate/compare/v0.7.
|
|
273
|
+
[Unreleased]: https://github.com/aashishkumar-tech/ciphergate/compare/v0.7.1...HEAD
|
|
274
|
+
[0.7.1]: https://github.com/aashishkumar-tech/ciphergate/compare/v0.7.0...v0.7.1
|
|
263
275
|
[0.7.0]: https://github.com/aashishkumar-tech/ciphergate/compare/v0.6.1...v0.7.0
|
|
264
276
|
[0.6.1]: https://github.com/aashishkumar-tech/ciphergate/compare/v0.6.0...v0.6.1
|
|
265
277
|
[0.6.0]: https://github.com/aashishkumar-tech/ciphergate/compare/v0.5.0...v0.6.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: ciphergate-cli
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.1
|
|
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.7.
|
|
53
|
+
> **Status: 0.7.1 (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.
|
|
@@ -117,8 +117,24 @@ ciphergate --version
|
|
|
117
117
|
|
|
118
118
|
Runtime dependencies: `typer`, `pydantic`, `PyYAML`.
|
|
119
119
|
|
|
120
|
+
## Quick start after `pip install`
|
|
121
|
+
|
|
122
|
+
The policy templates ship with the package. Copy one, review it, then run it on your own file:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
ciphergate init --list-templates
|
|
126
|
+
ciphergate init --template developer_logs --output developer_logs.yml
|
|
127
|
+
ciphergate validate-policy developer_logs.yml
|
|
128
|
+
ciphergate inspect app.log --policy developer_logs.yml --environment dev --destination local_dev
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Every template is a starting point that requires review for your data and destination.
|
|
132
|
+
|
|
120
133
|
## Quick start (synthetic examples)
|
|
121
134
|
|
|
135
|
+
These commands run from a clone of this repository, because `examples/` is not in the package.
|
|
136
|
+
`policies/` in a clone holds the same templates that `ciphergate init --template` writes.
|
|
137
|
+
|
|
122
138
|
```bash
|
|
123
139
|
# 1. Start from a template (refuses to overwrite without --force) and validate it.
|
|
124
140
|
ciphergate init --output ciphergate-policy.yml
|
|
@@ -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.7.
|
|
14
|
+
> **Status: 0.7.1 (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.
|
|
@@ -78,8 +78,24 @@ ciphergate --version
|
|
|
78
78
|
|
|
79
79
|
Runtime dependencies: `typer`, `pydantic`, `PyYAML`.
|
|
80
80
|
|
|
81
|
+
## Quick start after `pip install`
|
|
82
|
+
|
|
83
|
+
The policy templates ship with the package. Copy one, review it, then run it on your own file:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
ciphergate init --list-templates
|
|
87
|
+
ciphergate init --template developer_logs --output developer_logs.yml
|
|
88
|
+
ciphergate validate-policy developer_logs.yml
|
|
89
|
+
ciphergate inspect app.log --policy developer_logs.yml --environment dev --destination local_dev
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Every template is a starting point that requires review for your data and destination.
|
|
93
|
+
|
|
81
94
|
## Quick start (synthetic examples)
|
|
82
95
|
|
|
96
|
+
These commands run from a clone of this repository, because `examples/` is not in the package.
|
|
97
|
+
`policies/` in a clone holds the same templates that `ciphergate init --template` writes.
|
|
98
|
+
|
|
83
99
|
```bash
|
|
84
100
|
# 1. Start from a template (refuses to overwrite without --force) and validate it.
|
|
85
101
|
ciphergate init --output ciphergate-policy.yml
|
|
@@ -62,6 +62,9 @@ path = "src/ciphergate/__init__.py"
|
|
|
62
62
|
|
|
63
63
|
[tool.hatch.build.targets.wheel]
|
|
64
64
|
packages = ["src/ciphergate"]
|
|
65
|
+
# policies/ stays the one source of the starter templates; `ciphergate init --template` reads them.
|
|
66
|
+
[tool.hatch.build.targets.wheel.force-include]
|
|
67
|
+
"policies" = "ciphergate/policies"
|
|
65
68
|
|
|
66
69
|
[tool.hatch.build.targets.sdist]
|
|
67
70
|
include = [
|
|
@@ -22,7 +22,7 @@ Supported public API (everything else is internal and may change without notice)
|
|
|
22
22
|
rescan_directory(root, policy, context=None, *, recursive=False, strict=None) -> BatchReport
|
|
23
23
|
"""
|
|
24
24
|
|
|
25
|
-
__version__ = "0.7.
|
|
25
|
+
__version__ = "0.7.1"
|
|
26
26
|
|
|
27
27
|
from ciphergate.config import RuntimeSettings
|
|
28
28
|
from ciphergate.constants import (
|
|
@@ -74,6 +74,7 @@ from ciphergate.pipeline.stdio import (
|
|
|
74
74
|
)
|
|
75
75
|
from ciphergate.policy.context import evaluate_gates, resolve_context
|
|
76
76
|
from ciphergate.policy.engine import PolicyEngine
|
|
77
|
+
from ciphergate.policy.templates import read_template, template_names
|
|
77
78
|
from ciphergate.policy.validator import load_policy, validate_policy
|
|
78
79
|
from ciphergate.reporting.safe_text import escape_control
|
|
79
80
|
from ciphergate.reporting.serializer import (
|
|
@@ -351,6 +352,13 @@ def init_command(
|
|
|
351
352
|
output: Annotated[
|
|
352
353
|
Path, typer.Option("--output", "-o", help="Where to write the policy.")
|
|
353
354
|
] = Path("ciphergate-policy.yml"),
|
|
355
|
+
template: Annotated[
|
|
356
|
+
str | None,
|
|
357
|
+
typer.Option("--template", "-t", help="Named template (see --list-templates)."),
|
|
358
|
+
] = None,
|
|
359
|
+
list_templates: Annotated[
|
|
360
|
+
bool, typer.Option("--list-templates", help="List named templates and exit.")
|
|
361
|
+
] = False,
|
|
354
362
|
force: ForceOpt = False,
|
|
355
363
|
quiet: QuietOpt = False,
|
|
356
364
|
debug: DebugOpt = False,
|
|
@@ -358,12 +366,17 @@ def init_command(
|
|
|
358
366
|
"""Write a starter policy template (it MUST be reviewed before real use)."""
|
|
359
367
|
|
|
360
368
|
def body() -> int:
|
|
361
|
-
|
|
369
|
+
if list_templates:
|
|
370
|
+
sys.stdout.write("".join(f"{name}\n" for name in template_names()))
|
|
371
|
+
return 0
|
|
362
372
|
text = (
|
|
363
|
-
|
|
373
|
+
read_template(template)
|
|
374
|
+
if template is not None
|
|
375
|
+
else resources.files("ciphergate")
|
|
364
376
|
.joinpath("templates/starter_policy.yml")
|
|
365
377
|
.read_text(encoding="utf-8")
|
|
366
378
|
)
|
|
379
|
+
validate_output_path(output, protected=[], force=force, label="policy")
|
|
367
380
|
with AtomicOutput(output, force=force) as out:
|
|
368
381
|
out.stream.write(text)
|
|
369
382
|
out.publish()
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"""Starter policy templates shipped with the package. Every template requires review before use."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from importlib import resources
|
|
6
|
+
from importlib.resources.abc import Traversable
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
from ciphergate.errors import UsageError
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _templates_dir() -> Traversable:
|
|
13
|
+
packaged = resources.files("ciphergate").joinpath("policies")
|
|
14
|
+
if packaged.is_dir():
|
|
15
|
+
return packaged
|
|
16
|
+
# Editable install: the build copies policies/ into wheels only, so use the source checkout.
|
|
17
|
+
return Path(__file__).resolve().parents[3] / "policies"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def template_names() -> list[str]:
|
|
21
|
+
"""Names accepted by `read_template`, sorted."""
|
|
22
|
+
return sorted(
|
|
23
|
+
entry.name.removesuffix(".yml")
|
|
24
|
+
for entry in _templates_dir().iterdir()
|
|
25
|
+
if entry.name.endswith(".yml")
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def read_template(name: str) -> str:
|
|
30
|
+
"""Return a template's text. `name` is only compared to known names, never used as a path."""
|
|
31
|
+
if name not in template_names():
|
|
32
|
+
raise UsageError(
|
|
33
|
+
"unknown policy template; run: ciphergate init --list-templates",
|
|
34
|
+
code="unknown_policy_template",
|
|
35
|
+
)
|
|
36
|
+
return _templates_dir().joinpath(f"{name}.yml").read_text(encoding="utf-8")
|
|
@@ -40,6 +40,36 @@ def test_init_refuses_overwrite(tmp_path: Path) -> None:
|
|
|
40
40
|
assert invoke("init", "--output", target, "--force").exit_code == 0
|
|
41
41
|
|
|
42
42
|
|
|
43
|
+
def test_init_lists_every_policy_template() -> None:
|
|
44
|
+
r = invoke("init", "--list-templates")
|
|
45
|
+
assert r.exit_code == 0
|
|
46
|
+
assert r.stdout.split() == sorted(p.stem for p in POLICIES.glob("*.yml"))
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
@pytest.mark.parametrize("policy", sorted(POLICIES.glob("*.yml")), ids=lambda p: p.stem)
|
|
50
|
+
def test_init_template_writes_a_valid_copy(tmp_path: Path, policy: Path) -> None:
|
|
51
|
+
target = tmp_path / "p.yml"
|
|
52
|
+
r = invoke("init", "--template", policy.stem, "--output", target)
|
|
53
|
+
assert r.exit_code == 0 and "template" in r.stdout.lower()
|
|
54
|
+
assert target.read_text(encoding="utf-8") == policy.read_text(encoding="utf-8")
|
|
55
|
+
assert invoke("validate-policy", target).exit_code == 0
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def test_init_template_refuses_overwrite(tmp_path: Path) -> None:
|
|
59
|
+
target = tmp_path / "p.yml"
|
|
60
|
+
target.write_text("keep", encoding="utf-8")
|
|
61
|
+
assert invoke("init", "--template", "dev_local", "--output", target).exit_code == 5
|
|
62
|
+
assert target.read_text(encoding="utf-8") == "keep"
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
@pytest.mark.parametrize("name", ["nope", "../pyproject", "dev_local.yml", ""])
|
|
66
|
+
def test_init_unknown_template_fails_and_writes_nothing(tmp_path: Path, name: str) -> None:
|
|
67
|
+
target = tmp_path / "p.yml"
|
|
68
|
+
r = invoke("init", "--template", name, "--output", target)
|
|
69
|
+
assert r.exit_code == 2
|
|
70
|
+
assert "--list-templates" in r.output and not target.exists()
|
|
71
|
+
|
|
72
|
+
|
|
43
73
|
def test_validate_policy_exit_codes(tmp_path: Path) -> None:
|
|
44
74
|
bad = tmp_path / "bad.yml"
|
|
45
75
|
bad.write_text(
|
|
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
|