Deep dive into protect-build.mjs β the IP protection pipeline.
You build a beautiful landing page. You ship it. A few weeks later, you find someone copied your design + code and claims it's theirs. What's your proof of original authorship?
Without this kit:
git logis private (proves nothing publicly)- Wayback Machine (slow indexing, may not capture in time)
- Site screenshots (forgeable)
With this kit:
- Cryptographic hash of your build, anchored on Bitcoin blockchain
- Invisible watermarks in HTML/JS/CSS that survive copy-paste
- Versioned
.otsproof file β open it in any OpenTimestamps client to verify - Manifest with build UUID, date, author, file hashes β court-admissible
sequenceDiagram
participant Build as npm run build
participant PB as protect-build.mjs
participant FS as File System
participant OTS as OpenTimestamps Server
participant BTC as Bitcoin Blockchain
Build->>FS: Generates dist/
FS->>PB: Reads all files
PB->>PB: Generate UUID v4
PB->>FS: Inject watermarks (HTML/JS/CSS)
PB->>PB: Calculate SHA-256 per file
PB->>FS: Write protection-manifest.json
PB->>OTS: Submit hash via npx opentimestamps stamp
OTS-->>PB: Returns .ots proof file (Merkle tree path)
PB->>FS: Save .ots in timestamps/<project>/
Note over OTS,BTC: 3-6 hours later (async)
OTS->>BTC: Aggregates with other hashes, submits to Bitcoin
BTC-->>OTS: Anchored in block #N
Note over PB,BTC: User runs `npx opentimestamps upgrade <.ots>`
PB->>OTS: Request upgrade
OTS->>BTC: Get block proof
BTC-->>OTS: Block #N hash + path
OTS-->>PB: Upgraded .ots with Bitcoin proof
Injected immediately after <head>:
<head>
<!-- TDB-AUTHENTICITY: a3f9c2e18b740b3f -->
<meta name="x-author" content="Your Name">
<meta name="x-author-id" content="a3f9c2e1-9b04-4c3d-bf21-1234567890ab">
<meta name="x-built-at" content="2026-05-06T22:30:00.000Z">
<meta name="x-canonical-source" content="yourdomain.com">
...Survives: view-source copy, file download, automated cloners. Stripped by: intentional dev removal (visible in HTML), aggressive minifiers (rare for meta tags).
Appended to every .js/.mjs:
;(function(){try{window.__TDB__=atob("WW91ciBOYW1lfDIwMjYtMDUtMDZ8YTNmOWMyZTE=");}catch(e){}})();Survives: minification (the string survives), basic obfuscation, copy-paste. Stripped by: dead-code elimination tools that detect unused expressions, intentional removal.
Prepended to every .css:
/* Β© Your Name Β· 2026-05-06 Β· uuid:a3f9c2e1 Β· yourdomain.com */
.your-styles { ... }Survives: minification (most minifiers preserve /*! legal comments β adjust if needed).
Stripped by: aggressive CSS minifiers (cssnano with default config strips comments).
protection-manifest.json (placed in dist/):
{
"schema": "thidebrito-security/protection-manifest/1.0.0",
"project": "my-landing-page",
"build_uuid": "a3f9c2e1-9b04-4c3d-bf21-1234567890ab",
"built_at": "2026-05-06T22:30:00.000Z",
"author": "Your Name",
"canonical_source": "yourdomain.com",
"files_count": 12,
"files_total_bytes": 1234567,
"aggregate_sha256": "9f8d7e6c5b4a3e2f1d0c9b8a7f6e5d4c3b2a1f0e9d8c7b6a5f4e3d2c1b0a9f8e",
"watermarks": {
"html_meta": true,
"js_base64": true,
"css_comment": true
},
"files": [
{ "path": "index.html", "bytes": 24890, "sha256": "..." },
{ "path": "assets/main.js", "bytes": 145234, "sha256": "..." },
...
],
"ots_proof": "timestamps/my-landing-page/2026-05-06_2230_a3f9c2e1.json.ots"
}The aggregate_sha256 is the hash that gets stamped on the blockchain. If anyone modifies even one byte of any file, this hash changes.
OpenTimestamps is a free, decentralized timestamping protocol that anchors hashes to Bitcoin's blockchain.
Why Bitcoin?
- Immutable: rewriting history requires majority of global mining power (impossible practically)
- Public: anyone can verify
- Free: aggregation makes per-stamp cost ~0
Process:
- Your hash is submitted to a calendar server (e.g.,
calendar.opentimestamps.org) - The server aggregates hashes from many submitters into a Merkle tree
- The Merkle root is included in a Bitcoin transaction
- Within 3-6 hours, the transaction is confirmed in a Bitcoin block
Verifying a stamp:
# Anyone can run this β only needs the .ots file + original file
npx opentimestamps verify protection-manifest.jsonOutput:
Calendar https://...: success!
Bitcoin block 825234 attests existence as of 2026-05-06 14:30 UTC
This is your proof. Cryptographically tied to Bitcoin block 825234.
For Vite-based projects, add to vite.config.ts:
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import tdbProtect from '~/PROJETOS/claude-code-security-kit/scripts/vite-plugin-tdb-protect.mjs';
export default defineConfig({
plugins: [
react(),
tdbProtect({
enabled: process.env.NODE_ENV === 'production',
skipTimestamp: false, // set true in dev/CI
distDir: 'dist',
verbose: false,
}),
],
});The plugin runs in Vite's closeBundle hook (after build completes). On dev (vite dev), it's bypassed.
For plain HTML/CSS/JS projects:
# Manual:
node ~/PROJETOS/claude-code-security-kit/scripts/protect-build.mjs ./
# Or via wrapper (recommended for `vercel.json`):
"buildCommand": "bash $HOME/PROJETOS/claude-code-security-kit/scripts/pre-deploy.sh"If you find someone has copied your project:
- Identify the suspect site β note URL
- Inspect their HTML β look for your
x-author-idmeta tag (often forgotten) - Get your
.otsproof β~/PROJETOS/claude-code-security-kit/timestamps/<project>/<date>_<uuid>.json.ots - Verify your stamp:
npx opentimestamps verify protection-manifest.json
- Document the comparison β your manifest's
built_atvs suspect's earliest WHOIS/Wayback record - Consult legal counsel with the proof package
Total time to gather: <30 minutes if you ran protect-build.mjs before deploy.
- β Doesn't protect against design copying β only the implementation. If they redesign from scratch, watermarks won't survive.
- β Watermarks can be stripped β by determined attackers. They're deterrents, not barriers.
- β Bitcoin anchoring takes time β 3-6h for confirmation, ~6 confirmations (1h) recommended for high-stakes proof
- β Doesn't preserve old versions β only what you stamp at build time. Use Git for version history.
- β Legal jurisdiction matters β blockchain evidence acceptance varies by country. Consult lawyer.
| Project type | When to run protect-build |
|---|---|
| Production LP/blog | Every deploy |
| App/PWA | Every release |
| Internal tool | Not needed |
| Open source | Not needed (license is your protection) |
| Client work | Every deploy + give client the .ots |