codesig
v0.2.0
Published
Provable authorship for source files via invisible ed25519-signed watermarks, plus per-project animated editor backgrounds.
Downloads
24
Maintainers
Readme
codesig
Provable authorship for source code, plus a per-project editor background. Zero runtime dependencies. Single binary. Works offline.
What it does
Every source file in your project gets an invisible, cryptographically signed watermark embedded in a single-line comment. The watermark is made of zero-width Unicode characters, so it renders as nothing in any editor — but carries an ed25519 signature that proves who authored the file and detects tampering.
$ codesig sign src/auth.js
✓ Signed src/auth.js as abraham
$ cat src/auth.js | head -1
// codesig⟨invisible⟩
$ codesig verify src/auth.js
✓ src/auth.js: abraham @ 2026-04-16T14:22:10.000ZIf someone copies your code and claims it as their own, you can prove authorship by verifying the watermark against the public key committed to .codesig.json. They cannot forge a new watermark without your private key (stored only at ~/.codesig/keys/).
It also writes a .vscode/settings.json giving your project a consistent editor background across machines and teammates — not enforcable (editors always respect user overrides), but convenient. Backgrounds can be a bundled animated preset (aurora, nebula, midnight, terminal, paper), a solid hex color, or a path to your own CSS file.
Install
npm install -g codesigRequires Node >= 18.
Quickstart
cd my-project
codesig init # aurora preset (animated), keypair, editor settings, git hook
codesig sign --all # sign every source file
git add . && git commit -m init # pre-commit hook signs staged files on every commitPick a different background:
codesig bg list # see all presets
codesig bg nebula # switch to the nebula preset
codesig bg "#2d1b69" # use a solid hex color instead
codesig bg ./my-gradient.css # bring your own CSS
codesig bg reset # back to the default (aurora)Another teammate joining the project:
git pull
codesig enroll # generate their keypair, add public key to .codesig.jsonCommands
| Command | What it does |
| --- | --- |
| codesig init [--bg <value>] [--no-hook] | Create .codesig.json, generate your keypair, write editor settings, install pre-commit hook |
| codesig enroll | Add your public key to an existing project |
| codesig bg | Show current background + list presets |
| codesig bg list | Print presets with descriptions |
| codesig bg <preset\|#hex\|path.css> | Set background (auto-detected by shape) |
| codesig bg reset | Reset to the default preset (aurora) |
| codesig sign <file>... | Sign one or more files |
| codesig sign --all | Sign every source file |
| codesig verify <file>... | Verify one or more files |
| codesig verify --all | Verify the whole project |
| codesig unsign <file> | Remove the watermark |
| codesig status | Show config, authors, hook state |
Backgrounds
codesig always writes a solid-color palette to .vscode/settings.json — that works in any VS Code install, no extra tooling. So every teammate sees a themed editor out of the box.
For the animated presets (aurora, nebula, midnight, terminal, paper), we additionally write a pure-CSS animation file to .codesig/backgrounds/active.css. VS Code by itself cannot run CSS on its workbench, so this file is applied by a companion extension — one-time setup:
code --install-extension be5invis.vscode-custom-css
# Then: Cmd/Ctrl-Shift-P -> "Enable Custom CSS and JS" -> restart VS CodeAfter that, the CSS loads automatically on every VS Code launch — codesig wires vscode_custom_css.imports in your workspace settings to point at active.css. When you run codesig bg <preset>, the CSS is regenerated in place, so a simple VS Code reload picks up the new look.
Teammates who don't install the extension still get the solid-color palette — they just don't see the animation. No one is blocked.
Bring-your-own CSS
codesig bg ./my-background.cssYour CSS can target the workbench selector directly. For a richer solid-color fallback, add a magic comment:
/* codesig:solid=#2d1b69 */
.monaco-workbench .part.editor > .content {
background: radial-gradient(circle at 30% 30%, #6a4bff, #1a0b3d) !important;
}The codesig:solid=... value is used as the fallback color injected into workbench.colorCustomizations for users without the CSS extension.
How the watermark works
Each signed file carries one line at the top:
// codesig<ZWSP/ZWNJ sequence>The zero-width sequence encodes <payload>.<signature> (base64url). The payload is JSON:
{ "v": 1, "a": "<username>", "t": <unix_ms>, "h": "<sha256 of bare content>" }It is signed with your ed25519 private key. Verification checks:
- Zero-width blob decodes to a valid token.
- Payload author exists in
.codesig.json. - Signature validates against that author's public key.
- SHA-256 of the file's content (with the watermark line and any zero-width chars removed) matches
hin the payload.
Any tampering — editing the code, swapping the author, forging a signature — fails at least one check.
What this does NOT do
Be honest about limits:
- It does not prevent anyone from editing the file. Anyone can run
codesig unsignor a regex to strip zero-width chars. It proves authorship after the fact; it does not lock code down. - It does not force a background on anyone who clones your repo. Editors always respect user preferences.
.vscode/settings.jsonis a suggestion, not a policy. The animated CSS only shows for teammates who install theCustom CSS and JS Loaderextension. - Aggressive reformatters (Prettier, Black, etc.) typically preserve comment text and therefore preserve the watermark. But a tool that explicitly strips comments will destroy it.
- Base64 or minification steps will also strip the watermark. Sign source files, not build output.
The realistic use case is: you have a public repo or you shared your code with someone, and later you need to prove you wrote it. The watermark is a tripwire + attribution proof, not DRM.
Programmatic API
const codesig = require('codesig');
codesig.init({ root: process.cwd(), background: '#1a1a2e', installHook: false });
codesig.signFile({ root: process.cwd(), file: 'src/index.js' });
const r = codesig.verifyFile({ root: process.cwd(), file: 'src/index.js' });Testing
npm testNo test-runner dependency — uses Node's built-in node:test.
License
MIT.
