Unicode Plane 14 steganographic obfuscation toolkit
Project description
⬡ BlindTag
Unicode Plane 14 Steganographic Obfuscation Toolkit
A Polymath open-source project.
BlindTag embeds invisible payloads inside ordinary Unicode text using characters from the Tags block (U+E0000–U+E007F) in Unicode Plane 14. The result is visually indistinguishable from the original string and survives NFC / NFD / NFKC / NFKD normalization intact.
As of 2026-05-31, BlindTag also ships a bounded local-only retained reporting substrate under .blindtag/generated/reporting/ for API operation records, read-only queries, and controlled evidence exports.
Architecture
blindtag/
├── blindtag/
│ ├── __init__.py Public API surface
│ ├── core.py Codec engine — encode / decode / strip_plane14
│ ├── api.py FastAPI local transport layer
│ ├── reporting.py Retained JSONL event store + export helpers
│ ├── widget.py Desktop observer widget (PySide6)
│ └── exceptions.py Domain exception hierarchy
├── assets/ Runtime/documentation assets
├── installer_app/ Windows installer UI + .exe builder tooling
├── tests/ Pytest contract coverage
├── run_api.py API server launcher
├── run_widget.py Desktop widget launcher
├── pyproject.toml Package metadata & entry points
└── requirements.txt Runtime dependencies
Mathematical basis
The Tags block occupies 128 codepoints in Plane 14, mirroring the ASCII table shifted by a fixed offset of 0xE0000 (917,504 decimal):
Encode: ord(ascii_char) + 0xE0000 -> Plane 14 tag codepoint
Decode: plane14_codepoint - 0xE0000 -> ord(ascii_char)
| ASCII character | Codepoint | Plane 14 tag |
|---|---|---|
A |
U+0041 | U+E0041 |
z |
U+007A | U+E007A |
! |
U+0021 | U+E0021 |
~ |
U+007E | U+E007E |
Every payload is terminated by U+E007F (TAG CANCEL) — the only Plane 14 character outside the printable ASCII mirror. The decoder uses it as an end-of-stream sentinel.
[ anchor text ][ U+E0020…U+E007E payload chars ][ U+E007F TAG_CANCEL ]
Installation
From source
git clone https://github.com/joediggidyyy/blindtag.git
cd blindtag
# Runtime only
pip install -e .
# Runtime + dev/testing tools
pip install -e ".[dev]"
Explicit runtime requirements
pip install -r requirements.txt
Python requirement: 3.11 or later.
Windows installer surfaces
BlindTag now includes a Windows installer application source surface and a one-file installer builder:
# Validate the installer contract (Default/Advanced + required options)
python installer_app/windows_installer.py --validate-contract
# Print the resolved install plan without changing the machine
python installer_app/windows_installer.py --dry-run-install
# Build the Windows .exe installer from an audited wheel
python installer_app/build_windows_installer.py
Installer contract highlights:
- Default (Recommended) — aimed at recreational/everyday BlindTag use
- Advanced — custom setup path with explicit cautionary language
- The installer automatically satisfies the Python/runtime prerequisite lane when needed and only asks Windows for elevation when that setup truly requires it
- The release installer verifies the bundled wheel/README/icon payload hashes before installation and fails closed if the packaged payload no longer matches the installer security manifest
- Downloaded Python bootstrap installers are trust-checked before execution
- Required options:
Create shortcutEnable quick launchDisplay README.md after install
For ordinary Windows users, the target experience is intentionally low-burden: click through the installer, let BlindTag handle dependency/runtime setup, and launch from the installed widget shortcut.
Build note: the .exe builder requires a locally built BlindTag wheel and PyInstaller in the build environment.
Linux clipboard support
PySide6 uses Qt's native clipboard API. No xclip or xsel is required on Linux. A running display server (X11 or Wayland via XWayland) is required.
Quick start
Python API
from blindtag import decode, encode, strip_plane14
# Embed a hidden payload
tagged = encode(
anchor="Meeting notes from Monday sync.",
hidden_message="CONFIDENTIAL:REF-INV-7821",
)
# Extract the payload
secret = decode(tagged)
print(secret)
# -> "CONFIDENTIAL:REF-INV-7821"
# Recover clean anchor text
clean = strip_plane14(tagged)
print(clean)
# -> "Meeting notes from Monday sync."
Error handling
from blindtag import encode
from blindtag.exceptions import InvalidPayloadError
try:
encode("cover", "café")
except InvalidPayloadError as exc:
print(exc)
API server
python run_api.py
python run_api.py --port 9000
python run_api.py --reload
python run_api.py --log-level debug
Interactive docs: http://127.0.0.1:8000/docs
Core endpoints
POST /v1/encodePOST /v1/decodeGET /healthGET /v1/logPOST /v1/log/export
GET /v1/log
Read-only query surface for the retained BlindTag operation ledger.
| Parameter | Meaning |
|---|---|
request_id |
Filter by the API request id emitted in X-Request-Id |
operation |
Filter by operation name (encode, decode, log_query, log_export) |
level |
Filter by severity (debug, info, warning, error, critical) |
policy_mode |
Filter by retained policy posture (operational, security, forensic) |
action_phase |
Filter by provenance handoff phase (received, verified, exported, blocked, quarantined, unpacked, released) |
limit |
Maximum records returned |
POST /v1/log/export
Controlled export surface for retained evidence packets. The export root is path-contained under .blindtag/generated/reporting/exports/.
operationalmode preserves the Pass J baseline and may use the shared-key gate (BLINDTAG_EXPORT_SIGNING_KEY)security/forensicmode use verifier-friendly Ed25519 request verification and detached artifact signing (BLINDTAG_FORENSIC_SIGNING_*)- elevated export bundles include provenance summaries, chain verification, segment-seal summaries, and a sandbox-simulated handoff assessment packet that validates output content and final handoff-completion posture
Payload size policy
| Field | Maximum |
|---|---|
anchor |
10,000 chars |
hidden_message |
1,000 chars |
raw_text |
50,000 chars |
Requests exceeding these limits receive HTTP 422 before any codec logic runs.
Desktop widget
blindtag-widget
Launch surfaces
| Surface | Intended use | Terminal behavior |
|---|---|---|
blindtag-widget / blindtag-widget.exe |
Required widget launch surface | No terminal — this is the required widget behavior |
blindtag widget |
Supported CLI compatibility launcher | Hands off to the dedicated widget surface and should return the calling CLI promptly in installed environments |
python run_widget.py |
Direct source-tree developer launch | Keeps a terminal attached; useful for development/debug only |
Hotkeys
| Shortcut | Action |
|---|---|
Ctrl+E |
Switch to Encode panel |
Ctrl+D |
Switch to Decode panel |
Ctrl+W |
Toggle Clipboard Watcher |
Ctrl+Return |
Execute active panel primary action |
Escape |
Close widget |
Clipboard watcher
When enabled, BlindTag listens to Qt clipboard change events on the GUI thread. If new clipboard content contains a Plane 14 payload, the widget:
- switches to the Decode panel automatically
- populates raw input and extracted payload fields
- shows an inline detection banner when the window is already foregrounded
- when hidden in background posture, shows a persistent corner relaunch notification on hide and replaces that anchor with the latest hidden payload notification until dismissed or replaced
No data leaves the local machine. Clipboard detection stays inside the Qt event loop and shuts down with the widget.
Running tests
Tests are orchestrated via Calamum — the Polymath test runner.
![]()
# All tests
pytest
# Core engine only
pytest tests/test_core.py -v
# API integration only
pytest tests/test_api.py -v
# With coverage report
pytest --cov=blindtag --cov-report=term-missing
Validation highlights
| Class | Requirement |
|---|---|
TestRoundTrip |
Encode/decode fidelity across payload types |
TestValidationBoundaries |
InvalidPayloadError for every out-of-range char |
TestDecodeNoPayload |
None return on clean strings |
TestReportingEndpoints |
Retained API query/export coverage and trust gating |
TestRetainedExport |
JSONL export family, checksums, and optional signing |
TestHighTrustProvenance |
Elevated provenance modes, chain/seal verification, sandbox handoff posture |
TestWindowsInstallerContract |
Installer mode/option contract validation |
Security notes
- Localhost only. The API server binds to
127.0.0.1by default. Never expose it on0.0.0.0in untrusted network environments. - Input sanitization. The Pydantic validation layer rejects oversized and malformed payloads at the HTTP boundary before any codec code executes.
- Local-only retained reporting. BlindTag may persist structured API operation records and export packets under
.blindtag/generated/reporting/. This data never leaves the local machine unless the operator intentionally copies or publishes it. - Elevated provenance modes. BlindTag supports
securityandforensicretained-evidence modes with provenance fields, deny-by-default executable handoff scope rules, tamper-evident record chaining, segment seals, and sandbox-simulated handoff assessment. - Platform clipboard. The clipboard watcher reads only from the local system clipboard (via Qt's native clipboard API). It does not transmit data over any network.
Reporting validation evidence
Pass J baseline reporting and Pass R elevated provenance hardening were validated under Calamum on 2026-05-31:
20260531T230143Z-blindtag-reporting20260531T230200Z-blindtag-api20260531T230620Z-blindtag-cli20260531T230637Z-blindtag-all20260531T233221Z-blindtag-forensic20260531T233239Z-blindtag-reporting20260531T233256Z-blindtag-api20260531T233314Z-blindtag-all
License
MIT — see LICENSE for details.
BlindTag is developed and maintained by Polymath Global.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file blindtag-1.0.0.tar.gz.
File metadata
- Download URL: blindtag-1.0.0.tar.gz
- Upload date:
- Size: 5.2 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a56179cefa9b41214531eae7c24a32782b1935f46199e5dadf6a9bf6238b6826
|
|
| MD5 |
09a28cfe28202ac32f7825ce1f7e4d4e
|
|
| BLAKE2b-256 |
a21c3e4d5590b0227fb0e2a3b78084ce1184feb82a916b43b2291af3b482838e
|
File details
Details for the file blindtag-1.0.0-py3-none-any.whl.
File metadata
- Download URL: blindtag-1.0.0-py3-none-any.whl
- Upload date:
- Size: 5.0 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2f7531a02146f7811dc6a56c6c09a0b7a9b435f40619a711b26a62cc07a5f25e
|
|
| MD5 |
92281f04a40fde868ceabe69b83e6239
|
|
| BLAKE2b-256 |
b8461a084fa0d6f0fd8421738f6b6663482fe79660f87ad25a92e4ded1e07c60
|