Download the PHP package cleaniquecoders/pii-protection without Composer
On this page you can find all versions of the php package cleaniquecoders/pii-protection. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download cleaniquecoders/pii-protection
More information about cleaniquecoders/pii-protection
Files in cleaniquecoders/pii-protection
Package pii-protection
Short Description Pure-PHP PII protection: field-level encryption at rest + masking of sensitive fields in audit/log payloads. No framework, no global state — plain classes with explicit inputs and outputs, usable anywhere.
License MIT
Homepage https://github.com/cleaniquecoders/pii-protection
Informations about the package pii-protection
PII Protection
Pure-PHP PII protection: field-level encryption at rest + masking of sensitive fields in audit/log payloads. No framework, no global state — plain classes with explicit inputs and outputs, usable anywhere.
A small library of portable primitives every app handling personal data (SOC 2 / PDPA / GDPR) needs:
- Encryption — reversible encrypt/decrypt of PII for storage at rest (AES-256-GCM).
- Masking — render a value partially or fully hidden for display or logs.
- Redaction — walk a key/value payload (e.g. change-log old/new values) and mask listed fields before it is persisted.
Everything is constructor-injected. No service container, no boot conventions, no static facades — so it drops into Laravel, Symfony, Slim, a CLI tool, a queue worker, or plain PHP unchanged.
Requirements
- PHP
^8.4 ext-opensslext-mbstring
Installation
You can install the package via composer:
Usage
Quick start
Masking strategies
Each strategy implements MaskStrategy::mask(string $value): string.
| Strategy | Behaviour | Reversible |
|---|---|---|
TailStrategy |
Keep last N chars, mask the rest (******6789) |
No |
FullStrategy |
Mask every char (**********) |
No |
EmailStrategy |
Mask local-part, keep domain (****@acme.com) |
No |
HashStrategy |
Replace with a one-way sha256 digest |
No |
CreditCardStrategy |
Keep last 4 digits, preserve grouping (**** **** **** 1111) |
No |
IpStrategy |
Mask the last octet/group (192.168.1.**) |
No |
NameStrategy |
Keep each word's initial (J*** D**) |
No |
NricStrategy |
Mask MyKad digits, keep dashes (******-**-****) |
No |
RedactedStrategy |
Replace with a fixed placeholder ([redacted]) — hides the length too |
No |
Every strategy takes an optional maskChar (default *) so you can render with
•, x, or any character:
Encryption at rest
OpenSslEncrypter uses AES-256-GCM. The key is injected via the constructor —
the library never reads env/config. Each message uses a random IV and a random
HKDF salt, so encrypting the same value twice yields different ciphertext.
Ciphertext is written in a self-describing, versioned format
(v2.<keyId>.<payload>). Ciphertext produced by 1.0/1.1 still decrypts
unchanged — upgrades are seamless.
Context binding (AAD) — bind ciphertext to a context (user id, column name) so it cannot be moved between rows/columns. The same context is required to decrypt:
Key rotation — give it a KeyRing with multiple keys: new ciphertext uses
the current key, while older ciphertext keeps decrypting with whichever key its
id points to. No big-bang re-encryption needed.
Searchable lookups (blind index)
Encryption is non-deterministic, so you cannot query an encrypted column. Store
a deterministic HmacBlindIndex alongside the ciphertext and query that instead
— it is one-way and only confirms a match, never reveals the value.
Scrubbing free text
PiiScrubber masks PII patterns inside free text (log lines, messages), not
just named fields — with built-in detectors for email, credit card, Malaysian
NRIC, IPv4 and phone numbers.
Or mask any custom pattern with RegexStrategy:
Scrubbing secrets
SecretScrubber is the sibling of PiiScrubber for machine credentials —
keys, tokens and passwords rather than personal data. The two detector sets are
deliberately disjoint: scrubbing every IP address and email out of an
infrastructure log removes exactly the detail needed to debug it.
Note what survives. Which variable leaked, and which host it pointed at, is most of the value of the log line — only the credential is removed.
Detectors: private_key (PEM blocks), url_credentials, jwt,
aws_access_key_id, authorization (Bearer/Basic), assignment
(SECRET_KEY=…, "api_token": …).
When you already hold the secrets, LiteralScrubber masks them by exact match
— certain where a pattern is a guess:
It sorts longest-first so a short secret nested inside a longer one cannot
corrupt it, skips values under 6 characters, and skips pure digits so ports and
counts stay readable. prepare() shows what survived those rules.
Use both: patterns catch secrets you never issued, literals catch the ones with no distinctive shape.
Redaction of payloads
ArrayRedactor generalises change-log masking: given a payload (e.g. with
old_values / new_values, or any nested key/value map) and a list of
sensitive fields, it applies the chosen MaskStrategy to each listed field —
recursing into nested arrays and JSON-decoded structures — and leaves every
other field untouched.
Per-field strategies — map each field to its own strategy in a single pass (plain field names still use the redactor's default strategy):
Dot-path & wildcard targeting — target a precise location instead of any key
with that name; * matches any key at that level:
Redacting objects / DTOs
Tag properties with #[Pii] and let ObjectRedactor mask them into an array.
A tag can name its own strategy; otherwise the redactor's default is used.
Tokenization
Swap a PII value for an opaque, random token and keep the mapping in a Vault.
An in-memory ArrayVault ships with the package; implement Vault to persist
tokens elsewhere.
Errors
Encryption/decryption failures throw a typed exception under
CleaniqueCoders\PiiProtection\Exceptions\: EncryptionException and
DecryptionException, both extending PiiException (itself a RuntimeException,
so existing catch blocks keep working).
Guardrail — never encrypt lookup values
Never query on an encrypted column. Ciphertext is non-deterministic (random IV + salt per call) and will not match across rows or queries. To support equality lookups, store an
HmacBlindIndexalongside the ciphertext and query that — ormask/hashthe value if you don't need to reverse it.
Architecture
Design notes
- Single responsibility per class. Strategies, encrypter, redactor, and the wrapper are independent and swappable; consumers depend on the contracts, not the concretions.
- Configurable visible tail.
TailStrategy(visible: N)— default 4. - Nested / JSON PII.
ArrayRedactorrecurses, so structured columns are covered, not just flat scalars. - Key handling is the caller's job.
OpenSslEncryptertakes a key (or aKeyRing) in its constructor; the library never reads env/config. Rotation is supported via the ring, but loading/storing keys is up to you.
Documentation
Full documentation lives in docs/:
- Architecture — primitives, contracts, design decisions.
- Usage — masking, encryption & key rotation, redaction, detection, tokenization.
- Development — testing, quality tooling, releases.
- API Reference — every public class and method.
Testing
Changelog
Please see CHANGELOG for more information on what has changed recently.
Contributing
Please see CONTRIBUTING for details.
Security Vulnerabilities
Please review our security policy on how to report security vulnerabilities.
Credits
- Nasrul Hazim Bin Mohamad
- All Contributors
License
The MIT License (MIT). Please see License File for more information.
All versions of pii-protection with dependencies
ext-mbstring Version *
ext-openssl Version *