ikiprotect 1.0.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.
Files changed (69) hide show
  1. ikiprotect-1.0.0/.github/workflows/python.yml +30 -0
  2. ikiprotect-1.0.0/.gitignore +13 -0
  3. ikiprotect-1.0.0/LICENSE +21 -0
  4. ikiprotect-1.0.0/PKG-INFO +312 -0
  5. ikiprotect-1.0.0/README.MD +282 -0
  6. ikiprotect-1.0.0/assets/image.png +0 -0
  7. ikiprotect-1.0.0/examples/example_usage.py +350 -0
  8. ikiprotect-1.0.0/pyproject.toml +41 -0
  9. ikiprotect-1.0.0/src/iki_protect/__init__.py +5 -0
  10. ikiprotect-1.0.0/src/iki_protect/__main__.py +4 -0
  11. ikiprotect-1.0.0/src/iki_protect/cli/__init__.py +1 -0
  12. ikiprotect-1.0.0/src/iki_protect/cli/app.py +47 -0
  13. ikiprotect-1.0.0/src/iki_protect/cli/commands/__init__.py +3 -0
  14. ikiprotect-1.0.0/src/iki_protect/cli/commands/decrypt.py +152 -0
  15. ikiprotect-1.0.0/src/iki_protect/cli/commands/detect.py +123 -0
  16. ikiprotect-1.0.0/src/iki_protect/cli/commands/encrypt.py +172 -0
  17. ikiprotect-1.0.0/src/iki_protect/cli/commands/hash_cmd.py +337 -0
  18. ikiprotect-1.0.0/src/iki_protect/cli/commands/jwt_cmd.py +135 -0
  19. ikiprotect-1.0.0/src/iki_protect/cli/commands/keys.py +127 -0
  20. ikiprotect-1.0.0/src/iki_protect/cli/commands/mask.py +54 -0
  21. ikiprotect-1.0.0/src/iki_protect/cli/commands/sign.py +56 -0
  22. ikiprotect-1.0.0/src/iki_protect/cli/facade.py +5 -0
  23. ikiprotect-1.0.0/src/iki_protect/content/__init__.py +1 -0
  24. ikiprotect-1.0.0/src/iki_protect/content/base.py +34 -0
  25. ikiprotect-1.0.0/src/iki_protect/content/config_file.py +46 -0
  26. ikiprotect-1.0.0/src/iki_protect/content/plain_text.py +10 -0
  27. ikiprotect-1.0.0/src/iki_protect/core/__init__.py +11 -0
  28. ikiprotect-1.0.0/src/iki_protect/core/config.py +62 -0
  29. ikiprotect-1.0.0/src/iki_protect/core/detectors/__init__.py +30 -0
  30. ikiprotect-1.0.0/src/iki_protect/core/detectors/base.py +41 -0
  31. ikiprotect-1.0.0/src/iki_protect/core/detectors/regex_detectors.py +233 -0
  32. ikiprotect-1.0.0/src/iki_protect/core/detectors/registry.py +108 -0
  33. ikiprotect-1.0.0/src/iki_protect/core/errors.py +26 -0
  34. ikiprotect-1.0.0/src/iki_protect/core/keys/__init__.py +5 -0
  35. ikiprotect-1.0.0/src/iki_protect/core/keys/kms.py +119 -0
  36. ikiprotect-1.0.0/src/iki_protect/core/keys/manager.py +198 -0
  37. ikiprotect-1.0.0/src/iki_protect/core/keys/sss.py +54 -0
  38. ikiprotect-1.0.0/src/iki_protect/core/strategies/__init__.py +1 -0
  39. ikiprotect-1.0.0/src/iki_protect/core/strategies/encryption/__init__.py +1 -0
  40. ikiprotect-1.0.0/src/iki_protect/core/strategies/encryption/hpke.py +102 -0
  41. ikiprotect-1.0.0/src/iki_protect/core/strategies/encryption/hybrid_kem.py +51 -0
  42. ikiprotect-1.0.0/src/iki_protect/core/strategies/encryption/symmetric.py +419 -0
  43. ikiprotect-1.0.0/src/iki_protect/core/strategies/hashing/__init__.py +1 -0
  44. ikiprotect-1.0.0/src/iki_protect/core/strategies/hashing/envelope.py +154 -0
  45. ikiprotect-1.0.0/src/iki_protect/core/strategies/hashing/fast_hash.py +101 -0
  46. ikiprotect-1.0.0/src/iki_protect/core/strategies/hashing/kdf.py +25 -0
  47. ikiprotect-1.0.0/src/iki_protect/core/strategies/hashing/slow_hash.py +119 -0
  48. ikiprotect-1.0.0/src/iki_protect/core/strategies/jwt/__init__.py +1 -0
  49. ikiprotect-1.0.0/src/iki_protect/core/strategies/jwt/jwt_strategy.py +242 -0
  50. ikiprotect-1.0.0/src/iki_protect/core/strategies/masking/__init__.py +1 -0
  51. ikiprotect-1.0.0/src/iki_protect/core/strategies/masking/redact.py +19 -0
  52. ikiprotect-1.0.0/src/iki_protect/core/strategies/masking/tokenize.py +26 -0
  53. ikiprotect-1.0.0/src/iki_protect/core/strategies/signing/__init__.py +1 -0
  54. ikiprotect-1.0.0/src/iki_protect/core/strategies/signing/asymmetric_sign.py +123 -0
  55. ikiprotect-1.0.0/src/iki_protect/facade.py +524 -0
  56. ikiprotect-1.0.0/src/iki_protect/version.py +1 -0
  57. ikiprotect-1.0.0/tests/__init__.py +1 -0
  58. ikiprotect-1.0.0/tests/conftest.py +9 -0
  59. ikiprotect-1.0.0/tests/security/test_cli_encryption.py +237 -0
  60. ikiprotect-1.0.0/tests/security/test_cli_hashing.py +200 -0
  61. ikiprotect-1.0.0/tests/security/test_cli_key_generation.py +65 -0
  62. ikiprotect-1.0.0/tests/security/test_hashing.py +34 -0
  63. ikiprotect-1.0.0/tests/security/test_jwt_and_signing.py +162 -0
  64. ikiprotect-1.0.0/tests/security/test_key_generation.py +44 -0
  65. ikiprotect-1.0.0/tests/security/test_symmetric_roundtrip.py +84 -0
  66. ikiprotect-1.0.0/tests/unit/test_detectors.py +124 -0
  67. ikiprotect-1.0.0/tests/unit/test_hpke_and_chunked.py +34 -0
  68. ikiprotect-1.0.0/tests/unit/test_kms_local.py +31 -0
  69. ikiprotect-1.0.0/tests/unit/test_sss_fallback.py +17 -0
@@ -0,0 +1,30 @@
1
+ name: Python package
2
+
3
+ on:
4
+ push:
5
+ branches: [main, master]
6
+ pull_request:
7
+ branches: [main, master]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ python-version: [3.11, 3.12, 3.14]
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ - name: Set up Python
18
+ uses: actions/setup-python@v5
19
+ with:
20
+ python-version: ${{ matrix.python-version }}
21
+ - name: Install dependencies
22
+ run: |
23
+ python -m pip install --upgrade pip
24
+ pip install -e .[dev]
25
+ - name: Run ruff
26
+ run: python -m ruff check src tests
27
+ - name: Run mypy
28
+ run: python -m mypy src tests
29
+ - name: Run pytest
30
+ run: python -m pytest -q
@@ -0,0 +1,13 @@
1
+ **/__pycache__/
2
+ logs/
3
+ bin/
4
+ dist/
5
+ data/
6
+ structure.py
7
+ .pypirc
8
+ .pytest_cache/
9
+ .mypy_cache/
10
+ .ruff_cache/
11
+ .venv/
12
+ .vscode/
13
+ .env
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Franz Monzales
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,312 @@
1
+ Metadata-Version: 2.4
2
+ Name: ikiprotect
3
+ Version: 1.0.0
4
+ Summary: A portable Swiss Army knife for protecting a single piece of text or file: detect, mask, hash, encrypt, tokenize.
5
+ License: Apache-2.0
6
+ License-File: LICENSE
7
+ Keywords: cli,encryption,pii,privacy,secrets
8
+ Requires-Python: >=3.9
9
+ Requires-Dist: argon2-cffi>=23.0
10
+ Requires-Dist: blake3>=0.3
11
+ Requires-Dist: cryptography>=41.0
12
+ Requires-Dist: hpke>=0.6
13
+ Requires-Dist: pyyaml>=6.0
14
+ Requires-Dist: rich>=13.0
15
+ Requires-Dist: typer>=0.12
16
+ Provides-Extra: age
17
+ Requires-Dist: pyrage>=1.1; extra == 'age'
18
+ Provides-Extra: faker
19
+ Requires-Dist: faker>=24.0; extra == 'faker'
20
+ Provides-Extra: keyring
21
+ Requires-Dist: keyring>=25.0; extra == 'keyring'
22
+ Provides-Extra: kms-aws
23
+ Requires-Dist: boto3>=1.34; extra == 'kms-aws'
24
+ Provides-Extra: office
25
+ Requires-Dist: pypdf>=4.0; extra == 'office'
26
+ Requires-Dist: python-docx>=1.1; extra == 'office'
27
+ Provides-Extra: pqc
28
+ Requires-Dist: pqcrypto>=0.3; extra == 'pqc'
29
+ Description-Content-Type: text/markdown
30
+
31
+ # 🛡️ Iki-Protect
32
+
33
+ [![PyPI version](https://img.shields.io/pypi/v/iki-protect.svg)](https://pypi.org/project/iki-protect/)
34
+ [![License: Apache-2.0](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)
35
+
36
+ **One tool. Every data-protection primitive you'll ever need.**
37
+ Find PII and secrets, hide them, hash things, encrypt things, sign things, and issue JWTs — from a single CLI command or a single Python object. No servers, no accounts, no external services required.
38
+
39
+ ![Image_Cover](assets/image.png)
40
+
41
+ ```bash
42
+ pip install ikiprotect
43
+ ```
44
+
45
+ ```python
46
+ from iki_protect import IkiProtect
47
+ protect = IkiProtect()
48
+ ```
49
+
50
+ That's it — everything below is one method call or one CLI command away.
51
+
52
+ ---
53
+
54
+ ## 🚀 Why people reach for this
55
+
56
+ - **🔍 Finds what shouldn't be there** — emails, credit cards, IBANs, SSNs, IP addresses, and 12 different flavors of leaked API key/secret, in any text or file.
57
+ - **🙈 Hides it your way** — full redaction, partial masking (`j***e@example.com`), or deterministic tokenization that stays consistent every time.
58
+ - **🔐 Locks it down** — 6 modern AEAD ciphers, layered/chained encryption, envelope (DEK/KEK) encryption with key rotation, chunked encryption for huge files, and public-key encryption (Hybrid KEM / HPKE).
59
+ - **#️⃣ Hashes anything** — fast digests for checksums, keyed HMACs for integrity, and slow Argon2/PBKDF2 KDFs for passwords — done right by default.
60
+ - **✍️ Proves authenticity** — Ed25519, RSA-PSS, and ECDSA signatures; full JWT encode/decode/verify across 11 algorithms.
61
+ - **🔑 Manages your keys** — generate keypairs, derive keys from passphrases, resolve keys from env vars/files, split a secret into shares and recombine it later.
62
+ - **🖥️ CLI or 🐍 Python — your choice** — every capability works as a terminal command _and_ as a plain Python method call through the `IkiProtect` facade.
63
+
64
+ ---
65
+
66
+ ## 🧩 The complete feature set
67
+
68
+ ### 🔍 Find sensitive data — `detect`
69
+
70
+ Scans a string, file, or an entire folder and tells you exactly what it found and where.
71
+
72
+ | Category | What it catches |
73
+ | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
74
+ | **PII** | Emails, phone numbers, US Social Security numbers, IPv4 addresses, credit card numbers, IBANs |
75
+ | **Secrets** | AWS keys, GCP keys, GitHub tokens (classic + fine-grained), GitLab tokens, Slack tokens, Stripe keys, OpenAI keys, Twilio keys, NPM tokens, PEM private-key blocks, JWTs |
76
+
77
+ - Group findings with easy shorthands: `--types pii`, `--types secrets`, or both.
78
+ - Overlapping matches are automatically de-duplicated so you don't get double hits on the same text.
79
+ - Scan a whole repo with `--recursive`, respect a `.ikiprotectignore` file, and fail your CI pipeline with `--fail-on` if anything's found.
80
+ - Extendable with your own detectors via a plugin system.
81
+
82
+ ```bash
83
+ ikiprotect detect notes.txt --format json
84
+ ```
85
+
86
+ ```python
87
+ findings = protect.detect("email me at a@b.com", types="pii,secrets")
88
+ ```
89
+
90
+ ### 🙈 Hide sensitive data — `mask`
91
+
92
+ Once something's found, replace it in place or write a cleaned copy.
93
+
94
+ | Strategy | Example | Best for |
95
+ | ------------ | ----------------------------------------- | ------------------------------------------------------------------- |
96
+ | **redact** | `john@example.com` → `[REDACTED]` | Logs, tickets, anything shared externally |
97
+ | **partial** | `john@example.com` → `j****************m` | Support screenshots, debugging |
98
+ | **tokenize** | `john@example.com` → `V-ntuFR9wvlZhRp-` | Analytics/pseudonymization — same input always gives the same token |
99
+
100
+ ```bash
101
+ ikiprotect mask notes.txt --types pii,secrets --strategy partial
102
+ ikiprotect mask foo.txt --strategy tokenize --key-ref file:./token_key.bin
103
+ ```
104
+
105
+ ### #️⃣ Hash anything — `hash`
106
+
107
+ One command covers everything from "checksum a file" to "store a password correctly."
108
+
109
+ - **General-purpose digests:** SHA-256, SHA-512, SHA3-256, SHA3-512, BLAKE2b, BLAKE2s, BLAKE3 (plus keyed and extendable-output BLAKE3 modes), CRC32
110
+ - **Keyed MACs (integrity/authenticity):** HMAC-SHA256, HMAC-SHA512
111
+ - **Password-grade KDFs (slow & salted on purpose):** Argon2id, Argon2i, Argon2d, PBKDF2-SHA256, PBKDF2-SHA512 — with Argon2's cost parameters tunable via environment variables for production hardening
112
+ - Verifying a password hash auto-detects which algorithm produced it, so you don't have to remember or store that separately
113
+
114
+ ```bash
115
+ echo -n "correct horse battery staple" | ikiprotect hash --algo argon2id
116
+ ```
117
+
118
+ ```python
119
+ pw_hash = protect.hash_password("correct horse battery staple")
120
+ protect.verify_password(pw_hash, "correct horse battery staple")
121
+ ```
122
+
123
+ ### 🔐 Encrypt anything — `encrypt` / `decrypt`
124
+
125
+ From a quick one-off secret to a full key-management pipeline.
126
+
127
+ - **6 authenticated ciphers:** AES-256-GCM, AES-192-GCM, AES-128-GCM, AES-256-GCM-SIV, ChaCha20-Poly1305, XChaCha20-Poly1305
128
+ - **Self-describing ciphertext** — the algorithm and nonce length travel with the ciphertext, so `decrypt` just works without extra bookkeeping
129
+ - **Layered encryption** — chain multiple algorithms together for defense-in-depth
130
+ - **Envelope encryption (DEK/KEK)** — generate a fresh data key per message, wrap it under a master key, and **rotate the master key later without re-encrypting the payload**
131
+ - **Chunked/streaming encryption** — handles multi-gigabyte files in fixed-size, independently-authenticated chunks
132
+ - **Public-key encryption** — Hybrid KEM (X25519) and a minimal HPKE-compatible mode, so you can encrypt _to someone's public key_ with no shared secret needed
133
+ - **Built-in KMS simulator** — generate and unwrap data keys the same way you would with AWS KMS, entirely offline (with a placeholder ready for a real AWS KMS integration)
134
+
135
+ ```bash
136
+ ikiprotect encrypt secret.txt --key-ref env:MY_KEY -o secret.enc
137
+ ikiprotect encrypt secret.txt --envelope --key-ref env:MY_KEK -o secret.enc
138
+ ikiprotect encrypt rewrap secret.enc --old-key-ref env:OLD_KEK --new-key-ref env:NEW_KEK -o secret.rewrapped
139
+ ```
140
+
141
+ ```python
142
+ ciphertext = protect.encrypt(b"secret data", key)
143
+ envelope = protect.envelope_encrypt(kek, b"secret data", ["aes-256-gcm"])
144
+ encap, shared_key = protect.hybrid_encapsulate(recipient_public_key)
145
+ ```
146
+
147
+ ### ✍️ Prove authenticity — `sign` / `verify-signature`, `jwt`
148
+
149
+ - **Digital signatures:** Ed25519, RSA-PSS, ECDSA (P-256, P-384, P-521) — sign a release artifact, verify it came from you
150
+ - **JWTs:** encode, decode, and verify across HS256/384/512, RS256/384/512, PS256/384/512, ES256/384/512, and EdDSA, with issuer/audience/leeway checks built in
151
+
152
+ ```bash
153
+ ikiprotect generate-keypair --algo ed25519 -o ./keys
154
+ ikiprotect sign release.tar.gz --algo ed25519 --private-key ./keys/ed25519_private.key -o release.sig
155
+ ikiprotect jwt encode claims.json --algo HS256 --key-ref env:JWT_SECRET
156
+ ```
157
+
158
+ ```python
159
+ priv, pub = protect.generate_keypair("ed25519")
160
+ signature = protect.sign(b"message", priv)
161
+ token = protect.jwt_encode({"sub": "1234"}, b"hs256-secret", "HS256")
162
+ ```
163
+
164
+ ### 🔑 Manage your keys
165
+
166
+ - Generate keypairs (Ed25519, RSA, ECDSA P-256/384/521) with one command
167
+ - Derive an encryption key from a human passphrase (SHA-256, PBKDF2, or Argon2id)
168
+ - Resolve keys from `env:VAR_NAME`, `file:path`, or a raw path — with file-permission checks so you don't accidentally use a world-readable key
169
+ - **Split a secret into N shares with a K-of-N recovery threshold**, then recombine them later (true Shamir secret sharing, or an XOR fallback)
170
+
171
+ ```bash
172
+ ikiprotect keys split secret.bin --n 5 --k 3 -o shares.json
173
+ ikiprotect keys combine shares.json -o recovered.bin
174
+ ```
175
+
176
+ ```python
177
+ shares = protect.split_secret(secret_bytes, n=5, k=3)
178
+ recovered = protect.combine_shares(shares)
179
+ ```
180
+
181
+ ### 📄 Works with structured files, too
182
+
183
+ Beyond plain text/log files, Iki-Protect can target a single field inside one JSON or YAML config file by dot-path (e.g. `database.password`) instead of scanning/replacing the whole document.
184
+
185
+ ---
186
+
187
+ ## 🖥️ CLI or 🐍 Python — everything, either way
188
+
189
+ Every feature above works two ways:
190
+
191
+ 1. **From the terminal**, via the `ikiprotect` command (see the command table and examples above).
192
+ 2. **From Python**, via one object: `IkiProtect` from `iki_protect.facade`. No need to know which internal class implements `"aes-256-gcm"` or `"argon2id"` — just call the method.
193
+
194
+ ```python
195
+ from iki_protect.facade import IkiProtect
196
+
197
+ protect = IkiProtect()
198
+
199
+ # Detect & mask
200
+ findings = protect.detect("email me at a@b.com", types="pii,secrets")
201
+ masked = protect.mask("email me at a@b.com")
202
+
203
+ # Hashing
204
+ digest = protect.hash(b"data", algorithm="sha256")
205
+ pw_hash = protect.hash_password("correct horse battery staple")
206
+ protect.verify_password(pw_hash, "correct horse battery staple")
207
+
208
+ # Encryption
209
+ key = protect.derive_passphrase_key("my passphrase")
210
+ ciphertext = protect.encrypt(b"secret data", key)
211
+ plaintext = protect.decrypt(ciphertext, key)
212
+
213
+ # Keys, signing, JWT
214
+ priv, pub = protect.generate_keypair("ed25519")
215
+ signature = protect.sign(b"message", priv)
216
+ protect.verify_signature(signature, b"message", pub)
217
+
218
+ token = protect.jwt_encode({"sub": "1234"}, b"hs256-secret", "HS256")
219
+ claims = protect.jwt_verify(token, b"hs256-secret", "HS256")
220
+ ```
221
+
222
+ Want the underlying strategy classes instead of the facade? `iki_protect.api` re-exports every building block flat, for `from iki_protect.api import Aes256GcmStrategy` style imports. See `examples/example_usage.py` for a full end-to-end walkthrough of every single feature in one runnable script.
223
+
224
+ ---
225
+
226
+ ## 📦 Project layout
227
+
228
+ ```
229
+ src/iki_protect/
230
+ ├── cli/ # Typer-based CLI commands (detect, mask, hash, encrypt, decrypt, sign, jwt, keys)
231
+ ├── content/ # Plain text, JSON, YAML readers (one file at a time)
232
+ ├── core/
233
+ │ ├── detectors/ # Regex + checksum-based PII/secret detectors, plugin registry
234
+ │ ├── keys/ # Key resolution, generation (Ed25519/RSA/ECDSA), passphrase derivation, KMS, secret sharing
235
+ │ └── strategies/
236
+ │ ├── masking/ # Redact / partial-mask / tokenize transforms
237
+ │ ├── hashing/ # Fast hashes, HKDF, Argon2/PBKDF2 slow hashes
238
+ │ ├── encryption/ # AEAD ciphers, layered/envelope/chunked encryption, Hybrid KEM, HPKE
239
+ │ ├── signing/ # Ed25519 / RSA-PSS / ECDSA
240
+ │ └── jwt/ # JWT encode/decode/verify
241
+ ├── api.py # Flat re-export of every public symbol
242
+ └── facade.py # `IkiProtect` — one object, name-driven method for every feature
243
+ examples/example_usage.py # Runnable end-to-end demo of the whole feature set
244
+ tests/ # Unit + security test suites
245
+ ```
246
+
247
+ ## 🛠️ Installation
248
+
249
+ ```bash
250
+ pip install ikiprotect
251
+ ```
252
+
253
+ Requires Python ≥ 3.9. Core dependencies (installed automatically): `typer`, `rich`, `cryptography`, `blake3`, `argon2-cffi`, `PyYAML`.
254
+
255
+ Working on the source directly instead of installing from PyPI:
256
+
257
+ ```bash
258
+ git clone <this-repo>
259
+ cd iki-protect
260
+ pip install -e ".[dev]"
261
+ ```
262
+
263
+ ## ⚡ Quick examples
264
+
265
+ ```bash
266
+ # Detect and mask PII/secrets in a file
267
+ ikiprotect detect notes.txt --format json
268
+ ikiprotect mask notes.txt --types pii,secrets --strategy partial
269
+
270
+ # Hash a value with Argon2id (password-grade)
271
+ echo -n "correct horse battery staple" | ikiprotect hash --algo argon2id
272
+
273
+ # Encrypt/decrypt a file (key-ref based)
274
+ ikiprotect encrypt secret.txt --key-ref env:MY_KEY -o secret.enc
275
+ ikiprotect decrypt secret.enc --key-ref env:MY_KEY -o secret.txt
276
+
277
+ # Envelope mode (DEK/KEK): generate a random DEK, wrap under KEK
278
+ ikiprotect encrypt secret.txt --envelope --key-ref env:MY_KEK -o secret.enc
279
+ # Rotate the KEK that wraps the DEK without re-encrypting payload
280
+ ikiprotect encrypt rewrap secret.enc --old-key-ref env:OLD_KEK --new-key-ref env:NEW_KEK -o secret.rewrapped
281
+
282
+ # Recursive scan with CI gate
283
+ ikiprotect detect . --recursive --format ndjson --fail-on 1
284
+
285
+ # Tokenize values deterministically (requires keyed strategy)
286
+ ikiprotect mask foo.txt --strategy tokenize --key-ref file:./token_key.bin
287
+
288
+ # Secret sharing (split/combine)
289
+ ikiprotect keys split secret.bin --n 5 --k 3 -o shares.json
290
+ ikiprotect keys combine shares.json -o recovered.bin
291
+
292
+ # Sign and verify a release artifact
293
+ ikiprotect generate-keypair --algo ed25519 -o ./keys
294
+ ikiprotect sign release.tar.gz --algo ed25519 --private-key ./keys/ed25519_private.key -o release.sig
295
+ ikiprotect verify-signature release.tar.gz release.sig --algo ed25519 --public-key ./keys/ed25519_public.key
296
+
297
+ # JWT
298
+ ikiprotect jwt encode claims.json --algo HS256 --key-ref env:JWT_SECRET
299
+ ikiprotect jwt verify "<token>" --algo HS256 --key-ref env:JWT_SECRET
300
+ ```
301
+
302
+ > **Before using `--passphrase`/`sha256` defaults for anything real, read `AUDIT.md` — item C1/C2 covers weak defaults you should override (`--kdf argon2id` and a real `--salt`).**
303
+
304
+ ## 🧠 Design principles
305
+
306
+ - Every command operates on **one** value/file at a time — this is not a dataset/batch tool.
307
+ - Ciphertext is **self-describing**: a version byte + implied nonce length means `decrypt` never needs the nonce or algorithm re-supplied separately.
308
+ - Two distinct key-loading paths exist on purpose: `KeyManager.resolve()` normalizes any input to a 32-byte key; `KeyManager.load_raw()` returns exact bytes for algorithms that need precise key material.
309
+
310
+ ## License
311
+
312
+ MIT
@@ -0,0 +1,282 @@
1
+ # 🛡️ Iki-Protect
2
+
3
+ [![PyPI version](https://img.shields.io/pypi/v/iki-protect.svg)](https://pypi.org/project/iki-protect/)
4
+ [![License: Apache-2.0](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)
5
+
6
+ **One tool. Every data-protection primitive you'll ever need.**
7
+ Find PII and secrets, hide them, hash things, encrypt things, sign things, and issue JWTs — from a single CLI command or a single Python object. No servers, no accounts, no external services required.
8
+
9
+ ![Image_Cover](assets/image.png)
10
+
11
+ ```bash
12
+ pip install ikiprotect
13
+ ```
14
+
15
+ ```python
16
+ from iki_protect import IkiProtect
17
+ protect = IkiProtect()
18
+ ```
19
+
20
+ That's it — everything below is one method call or one CLI command away.
21
+
22
+ ---
23
+
24
+ ## 🚀 Why people reach for this
25
+
26
+ - **🔍 Finds what shouldn't be there** — emails, credit cards, IBANs, SSNs, IP addresses, and 12 different flavors of leaked API key/secret, in any text or file.
27
+ - **🙈 Hides it your way** — full redaction, partial masking (`j***e@example.com`), or deterministic tokenization that stays consistent every time.
28
+ - **🔐 Locks it down** — 6 modern AEAD ciphers, layered/chained encryption, envelope (DEK/KEK) encryption with key rotation, chunked encryption for huge files, and public-key encryption (Hybrid KEM / HPKE).
29
+ - **#️⃣ Hashes anything** — fast digests for checksums, keyed HMACs for integrity, and slow Argon2/PBKDF2 KDFs for passwords — done right by default.
30
+ - **✍️ Proves authenticity** — Ed25519, RSA-PSS, and ECDSA signatures; full JWT encode/decode/verify across 11 algorithms.
31
+ - **🔑 Manages your keys** — generate keypairs, derive keys from passphrases, resolve keys from env vars/files, split a secret into shares and recombine it later.
32
+ - **🖥️ CLI or 🐍 Python — your choice** — every capability works as a terminal command _and_ as a plain Python method call through the `IkiProtect` facade.
33
+
34
+ ---
35
+
36
+ ## 🧩 The complete feature set
37
+
38
+ ### 🔍 Find sensitive data — `detect`
39
+
40
+ Scans a string, file, or an entire folder and tells you exactly what it found and where.
41
+
42
+ | Category | What it catches |
43
+ | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
44
+ | **PII** | Emails, phone numbers, US Social Security numbers, IPv4 addresses, credit card numbers, IBANs |
45
+ | **Secrets** | AWS keys, GCP keys, GitHub tokens (classic + fine-grained), GitLab tokens, Slack tokens, Stripe keys, OpenAI keys, Twilio keys, NPM tokens, PEM private-key blocks, JWTs |
46
+
47
+ - Group findings with easy shorthands: `--types pii`, `--types secrets`, or both.
48
+ - Overlapping matches are automatically de-duplicated so you don't get double hits on the same text.
49
+ - Scan a whole repo with `--recursive`, respect a `.ikiprotectignore` file, and fail your CI pipeline with `--fail-on` if anything's found.
50
+ - Extendable with your own detectors via a plugin system.
51
+
52
+ ```bash
53
+ ikiprotect detect notes.txt --format json
54
+ ```
55
+
56
+ ```python
57
+ findings = protect.detect("email me at a@b.com", types="pii,secrets")
58
+ ```
59
+
60
+ ### 🙈 Hide sensitive data — `mask`
61
+
62
+ Once something's found, replace it in place or write a cleaned copy.
63
+
64
+ | Strategy | Example | Best for |
65
+ | ------------ | ----------------------------------------- | ------------------------------------------------------------------- |
66
+ | **redact** | `john@example.com` → `[REDACTED]` | Logs, tickets, anything shared externally |
67
+ | **partial** | `john@example.com` → `j****************m` | Support screenshots, debugging |
68
+ | **tokenize** | `john@example.com` → `V-ntuFR9wvlZhRp-` | Analytics/pseudonymization — same input always gives the same token |
69
+
70
+ ```bash
71
+ ikiprotect mask notes.txt --types pii,secrets --strategy partial
72
+ ikiprotect mask foo.txt --strategy tokenize --key-ref file:./token_key.bin
73
+ ```
74
+
75
+ ### #️⃣ Hash anything — `hash`
76
+
77
+ One command covers everything from "checksum a file" to "store a password correctly."
78
+
79
+ - **General-purpose digests:** SHA-256, SHA-512, SHA3-256, SHA3-512, BLAKE2b, BLAKE2s, BLAKE3 (plus keyed and extendable-output BLAKE3 modes), CRC32
80
+ - **Keyed MACs (integrity/authenticity):** HMAC-SHA256, HMAC-SHA512
81
+ - **Password-grade KDFs (slow & salted on purpose):** Argon2id, Argon2i, Argon2d, PBKDF2-SHA256, PBKDF2-SHA512 — with Argon2's cost parameters tunable via environment variables for production hardening
82
+ - Verifying a password hash auto-detects which algorithm produced it, so you don't have to remember or store that separately
83
+
84
+ ```bash
85
+ echo -n "correct horse battery staple" | ikiprotect hash --algo argon2id
86
+ ```
87
+
88
+ ```python
89
+ pw_hash = protect.hash_password("correct horse battery staple")
90
+ protect.verify_password(pw_hash, "correct horse battery staple")
91
+ ```
92
+
93
+ ### 🔐 Encrypt anything — `encrypt` / `decrypt`
94
+
95
+ From a quick one-off secret to a full key-management pipeline.
96
+
97
+ - **6 authenticated ciphers:** AES-256-GCM, AES-192-GCM, AES-128-GCM, AES-256-GCM-SIV, ChaCha20-Poly1305, XChaCha20-Poly1305
98
+ - **Self-describing ciphertext** — the algorithm and nonce length travel with the ciphertext, so `decrypt` just works without extra bookkeeping
99
+ - **Layered encryption** — chain multiple algorithms together for defense-in-depth
100
+ - **Envelope encryption (DEK/KEK)** — generate a fresh data key per message, wrap it under a master key, and **rotate the master key later without re-encrypting the payload**
101
+ - **Chunked/streaming encryption** — handles multi-gigabyte files in fixed-size, independently-authenticated chunks
102
+ - **Public-key encryption** — Hybrid KEM (X25519) and a minimal HPKE-compatible mode, so you can encrypt _to someone's public key_ with no shared secret needed
103
+ - **Built-in KMS simulator** — generate and unwrap data keys the same way you would with AWS KMS, entirely offline (with a placeholder ready for a real AWS KMS integration)
104
+
105
+ ```bash
106
+ ikiprotect encrypt secret.txt --key-ref env:MY_KEY -o secret.enc
107
+ ikiprotect encrypt secret.txt --envelope --key-ref env:MY_KEK -o secret.enc
108
+ ikiprotect encrypt rewrap secret.enc --old-key-ref env:OLD_KEK --new-key-ref env:NEW_KEK -o secret.rewrapped
109
+ ```
110
+
111
+ ```python
112
+ ciphertext = protect.encrypt(b"secret data", key)
113
+ envelope = protect.envelope_encrypt(kek, b"secret data", ["aes-256-gcm"])
114
+ encap, shared_key = protect.hybrid_encapsulate(recipient_public_key)
115
+ ```
116
+
117
+ ### ✍️ Prove authenticity — `sign` / `verify-signature`, `jwt`
118
+
119
+ - **Digital signatures:** Ed25519, RSA-PSS, ECDSA (P-256, P-384, P-521) — sign a release artifact, verify it came from you
120
+ - **JWTs:** encode, decode, and verify across HS256/384/512, RS256/384/512, PS256/384/512, ES256/384/512, and EdDSA, with issuer/audience/leeway checks built in
121
+
122
+ ```bash
123
+ ikiprotect generate-keypair --algo ed25519 -o ./keys
124
+ ikiprotect sign release.tar.gz --algo ed25519 --private-key ./keys/ed25519_private.key -o release.sig
125
+ ikiprotect jwt encode claims.json --algo HS256 --key-ref env:JWT_SECRET
126
+ ```
127
+
128
+ ```python
129
+ priv, pub = protect.generate_keypair("ed25519")
130
+ signature = protect.sign(b"message", priv)
131
+ token = protect.jwt_encode({"sub": "1234"}, b"hs256-secret", "HS256")
132
+ ```
133
+
134
+ ### 🔑 Manage your keys
135
+
136
+ - Generate keypairs (Ed25519, RSA, ECDSA P-256/384/521) with one command
137
+ - Derive an encryption key from a human passphrase (SHA-256, PBKDF2, or Argon2id)
138
+ - Resolve keys from `env:VAR_NAME`, `file:path`, or a raw path — with file-permission checks so you don't accidentally use a world-readable key
139
+ - **Split a secret into N shares with a K-of-N recovery threshold**, then recombine them later (true Shamir secret sharing, or an XOR fallback)
140
+
141
+ ```bash
142
+ ikiprotect keys split secret.bin --n 5 --k 3 -o shares.json
143
+ ikiprotect keys combine shares.json -o recovered.bin
144
+ ```
145
+
146
+ ```python
147
+ shares = protect.split_secret(secret_bytes, n=5, k=3)
148
+ recovered = protect.combine_shares(shares)
149
+ ```
150
+
151
+ ### 📄 Works with structured files, too
152
+
153
+ Beyond plain text/log files, Iki-Protect can target a single field inside one JSON or YAML config file by dot-path (e.g. `database.password`) instead of scanning/replacing the whole document.
154
+
155
+ ---
156
+
157
+ ## 🖥️ CLI or 🐍 Python — everything, either way
158
+
159
+ Every feature above works two ways:
160
+
161
+ 1. **From the terminal**, via the `ikiprotect` command (see the command table and examples above).
162
+ 2. **From Python**, via one object: `IkiProtect` from `iki_protect.facade`. No need to know which internal class implements `"aes-256-gcm"` or `"argon2id"` — just call the method.
163
+
164
+ ```python
165
+ from iki_protect.facade import IkiProtect
166
+
167
+ protect = IkiProtect()
168
+
169
+ # Detect & mask
170
+ findings = protect.detect("email me at a@b.com", types="pii,secrets")
171
+ masked = protect.mask("email me at a@b.com")
172
+
173
+ # Hashing
174
+ digest = protect.hash(b"data", algorithm="sha256")
175
+ pw_hash = protect.hash_password("correct horse battery staple")
176
+ protect.verify_password(pw_hash, "correct horse battery staple")
177
+
178
+ # Encryption
179
+ key = protect.derive_passphrase_key("my passphrase")
180
+ ciphertext = protect.encrypt(b"secret data", key)
181
+ plaintext = protect.decrypt(ciphertext, key)
182
+
183
+ # Keys, signing, JWT
184
+ priv, pub = protect.generate_keypair("ed25519")
185
+ signature = protect.sign(b"message", priv)
186
+ protect.verify_signature(signature, b"message", pub)
187
+
188
+ token = protect.jwt_encode({"sub": "1234"}, b"hs256-secret", "HS256")
189
+ claims = protect.jwt_verify(token, b"hs256-secret", "HS256")
190
+ ```
191
+
192
+ Want the underlying strategy classes instead of the facade? `iki_protect.api` re-exports every building block flat, for `from iki_protect.api import Aes256GcmStrategy` style imports. See `examples/example_usage.py` for a full end-to-end walkthrough of every single feature in one runnable script.
193
+
194
+ ---
195
+
196
+ ## 📦 Project layout
197
+
198
+ ```
199
+ src/iki_protect/
200
+ ├── cli/ # Typer-based CLI commands (detect, mask, hash, encrypt, decrypt, sign, jwt, keys)
201
+ ├── content/ # Plain text, JSON, YAML readers (one file at a time)
202
+ ├── core/
203
+ │ ├── detectors/ # Regex + checksum-based PII/secret detectors, plugin registry
204
+ │ ├── keys/ # Key resolution, generation (Ed25519/RSA/ECDSA), passphrase derivation, KMS, secret sharing
205
+ │ └── strategies/
206
+ │ ├── masking/ # Redact / partial-mask / tokenize transforms
207
+ │ ├── hashing/ # Fast hashes, HKDF, Argon2/PBKDF2 slow hashes
208
+ │ ├── encryption/ # AEAD ciphers, layered/envelope/chunked encryption, Hybrid KEM, HPKE
209
+ │ ├── signing/ # Ed25519 / RSA-PSS / ECDSA
210
+ │ └── jwt/ # JWT encode/decode/verify
211
+ ├── api.py # Flat re-export of every public symbol
212
+ └── facade.py # `IkiProtect` — one object, name-driven method for every feature
213
+ examples/example_usage.py # Runnable end-to-end demo of the whole feature set
214
+ tests/ # Unit + security test suites
215
+ ```
216
+
217
+ ## 🛠️ Installation
218
+
219
+ ```bash
220
+ pip install ikiprotect
221
+ ```
222
+
223
+ Requires Python ≥ 3.9. Core dependencies (installed automatically): `typer`, `rich`, `cryptography`, `blake3`, `argon2-cffi`, `PyYAML`.
224
+
225
+ Working on the source directly instead of installing from PyPI:
226
+
227
+ ```bash
228
+ git clone <this-repo>
229
+ cd iki-protect
230
+ pip install -e ".[dev]"
231
+ ```
232
+
233
+ ## ⚡ Quick examples
234
+
235
+ ```bash
236
+ # Detect and mask PII/secrets in a file
237
+ ikiprotect detect notes.txt --format json
238
+ ikiprotect mask notes.txt --types pii,secrets --strategy partial
239
+
240
+ # Hash a value with Argon2id (password-grade)
241
+ echo -n "correct horse battery staple" | ikiprotect hash --algo argon2id
242
+
243
+ # Encrypt/decrypt a file (key-ref based)
244
+ ikiprotect encrypt secret.txt --key-ref env:MY_KEY -o secret.enc
245
+ ikiprotect decrypt secret.enc --key-ref env:MY_KEY -o secret.txt
246
+
247
+ # Envelope mode (DEK/KEK): generate a random DEK, wrap under KEK
248
+ ikiprotect encrypt secret.txt --envelope --key-ref env:MY_KEK -o secret.enc
249
+ # Rotate the KEK that wraps the DEK without re-encrypting payload
250
+ ikiprotect encrypt rewrap secret.enc --old-key-ref env:OLD_KEK --new-key-ref env:NEW_KEK -o secret.rewrapped
251
+
252
+ # Recursive scan with CI gate
253
+ ikiprotect detect . --recursive --format ndjson --fail-on 1
254
+
255
+ # Tokenize values deterministically (requires keyed strategy)
256
+ ikiprotect mask foo.txt --strategy tokenize --key-ref file:./token_key.bin
257
+
258
+ # Secret sharing (split/combine)
259
+ ikiprotect keys split secret.bin --n 5 --k 3 -o shares.json
260
+ ikiprotect keys combine shares.json -o recovered.bin
261
+
262
+ # Sign and verify a release artifact
263
+ ikiprotect generate-keypair --algo ed25519 -o ./keys
264
+ ikiprotect sign release.tar.gz --algo ed25519 --private-key ./keys/ed25519_private.key -o release.sig
265
+ ikiprotect verify-signature release.tar.gz release.sig --algo ed25519 --public-key ./keys/ed25519_public.key
266
+
267
+ # JWT
268
+ ikiprotect jwt encode claims.json --algo HS256 --key-ref env:JWT_SECRET
269
+ ikiprotect jwt verify "<token>" --algo HS256 --key-ref env:JWT_SECRET
270
+ ```
271
+
272
+ > **Before using `--passphrase`/`sha256` defaults for anything real, read `AUDIT.md` — item C1/C2 covers weak defaults you should override (`--kdf argon2id` and a real `--salt`).**
273
+
274
+ ## 🧠 Design principles
275
+
276
+ - Every command operates on **one** value/file at a time — this is not a dataset/batch tool.
277
+ - Ciphertext is **self-describing**: a version byte + implied nonce length means `decrypt` never needs the nonce or algorithm re-supplied separately.
278
+ - Two distinct key-loading paths exist on purpose: `KeyManager.resolve()` normalizes any input to a 32-byte key; `KeyManager.load_raw()` returns exact bytes for algorithms that need precise key material.
279
+
280
+ ## License
281
+
282
+ MIT
Binary file