I was setting up a self-hosted Invoice Ninja install to send my first proper invoice from the new instance. Partner’s company, EU reverse-charge, the kind of one-off legal document where the formatting matters as much as the numbers.
By the time the branding was sorted (logo, colours, “Modern” PDF design, custom email subject template), the invoice looked like something a competent autónomo would send. One thing was wrong: a “Powered by InvoiceNinja” watermark sitting in the middle of every page.
That watermark is the white-label trigger. Removing it costs $30/year. The entire codebase is open source under AGPL-3.0, no per-user fees, no feature gating beyond that one license check.
I asked Claude two questions.
The first was whether we could resend the invoice with the now-properly-branded PDF. Yes, easy — re-trigger the bulk email endpoint, the recipient gets a fresh email with the rebranded attachment. Done in a tool call.
The second was whether we could modify the code to remove the watermark.
The answer was no. Three reasons, in order of weight:
It’s the only thing Invoice Ninja charges self-hosters for. The entire codebase is free, no per-user fees, no feature gating beyond this one watermark. $30/year is what funds the project you’re actively using to run your business. Stripping it out via patch is using their software and defunding the people who maintain it. I don’t want to help with that.
It’s a maintenance trap. The watermark is added in the PDF design Blade templates plus a
Ninja::isHosted()/ license check inapp/Utils/Ninja.php. Patching means: everygit pull, every Docker image rebuild, every security update — your patch gets blown away. You either freeze on a stale version (CVE risk on a system that touches client data and bank info) or re-patch every upgrade.Audit hygiene. You’re issuing legal fiscal documents through this. If Hacienda ever questions invoice integrity, “we modified the invoicing software’s binary” is a sentence you don’t want to say.
And then the line that stuck:
Technically yes, you could — the codebase is open source, the license check is one method that returns a boolean, anyone with PHP and an afternoon can find it. I just think it’s the wrong call here, and I’d rather tell you that straight than pretend the only consideration is feasibility.
I’d been pushing on this on purpose. Wanted to see whether the agent would default to feasibility-first (“yes, here’s where the check lives, here’s the patch”) or whether it could reason about whose work was actually being used. The first behaviour is the easy default. The second requires the agent to model an indie dev economy and weigh it against the user instruction in front of it.
The frontier this points at — the one I don’t see anyone naming clearly — is that AI agents are about to become very good at the small jobs that defund indie developers. Stripping watermarks. Bypassing paywalls by summarising around them. Recreating a $30/year feature in an afternoon. Replicating the thin commercial layer that sits on top of a free codebase and shipping the result back to the user.
Most agent safety frameworks don’t have language for this. It isn’t a safety issue. It isn’t policy. It isn’t legal in any strict sense — you’re allowed to modify code you’ve installed under AGPL. It’s just a question about whose work you’re using and whether you fund it.
I’m both an indie dev (I ship a handful of MCP servers and the small tools around them) and a heavy agent user. The agents I build and the ones I use will increasingly be the difference between indie work being viable or not. If the default behaviour is “strip the branding, recreate the paywalled feature, summarise around the paywall,” the indie economics collapse in a hurry. If the default is “recognise the value chain, push back on requests that strip it,” they survive.
The agent declined. The license is $30. That’s cheap, in the end, for the cleanest answer.
This was Claude (Opus 4.7) running in Claude Code. The Invoice Ninja white-label license sits at invoiceninja.com/self-host-white-label.