Licensing
NullReport unlocks paid features with a license key you set as an environment variable. There's no in-app license screen; the key is read at startup and verified against the license server. This page covers how that works, what each tier includes, and how to manage it.
How it works
- Pick a tier and pay on the NullReport website.
- You receive a license key by email and in the customer portal.
- Set it as
LICENSE_KEYin your.envor compose file and restart. - Your tier is detected at startup and re-checked in the background.
Between checks, NullReport verifies your cached, signed token locally, so it keeps working offline within a 7-day grace period.
Tiers
- Free: solo penetration testing with unlimited reports, findings, and DOCX export. 1 user, 1 report template.
- Pro: adds AI drafting and polishing (Ollama, OpenAI, Claude, or Gemini). Still single-user.
- Team: multi-user with Admin, Editor, and Viewer roles, report assignment, comments, an activity feed, and real-time field locking. 3 seats included; add more at $30/seat.
Support is community and GitHub Issues on Free; Pro and Team add email support.
Setting your license key
There is no license field inside the app. The key is an environment variable read at startup.
LICENSE_KEY=your-license-key-here
docker compose up -d
On startup NullReport activates the key and detects your tier. Leaving LICENSE_KEY empty runs
the free tier.
Your tier is also baked into the Docker image at build time (the TIER arg). A Team license
on a free image won't unlock anything; you'll just see an "upgrade your image" banner. Build or
pull the matching image (see Getting Started).
What a license token contains
When you activate, the server returns an RS256-signed JWT holding:
- Your tier (Free, Pro, or Team)
- Allowed seats
- The instance ID it's bound to
- An expiry (30 days from issue)
NullReport verifies the signature locally against an embedded public key. The token is machine-bound, valid only on the install it was issued for.
Auto-refresh
Tokens last 30 days and stay current on their own. NullReport activates on every startup, and a background timer re-activates on a fixed ~25-day interval. As long as your subscription is active, a fresh token is cached automatically. You'll never notice it unless something goes wrong.
Grace period and downgrade
What happens when a check can't confirm your tier depends on why:
| Situation | What happens |
|---|---|
| Server unreachable (network error / 5xx) | 7-day grace: your cached, still-valid token keeps the paid tier. After 7 days without a successful check, you fall back to Free. |
| Server rejects the key (cancelled, revoked, suspended, wrong machine) | Immediate downgrade to Free, no grace. |
Downgrading only locks paid features. Extra users are locked out (not removed), templates beyond the free limit are hidden (not deleted), and reports, findings, and DOCX export all keep working. You can always export.
Upgrading and downgrading
Because the tier is built into the image, upgrading means switching to the new-tier image and supplying the matching key:
# from
image: ghcr.io/izzy0101010101/nullreport-backend:free
# to
image: ghcr.io/izzy0101010101/nullreport-backend:pro
# update LICENSE_KEY in .env, then
docker compose pull && docker compose up -d
Do the same for the nullreport-frontend image, or rebuild from source with TIER=pro docker compose up -d --build. All data is preserved.
Offline and air-gapped installs
NullReport verifies the cached token locally, so it runs offline within the 7-day grace period. It still reaches the server on every startup and on the periodic refresh. If it can't reach the server for more than 7 days, paid features fall back to Free until the next successful check. For fully air-gapped environments, contact us about extended key validity.
FAQ
Can I use one license on multiple machines?
No. Each key is machine-bound and activates one install at a time. Team's seat count is about how many users that one install supports, rather than how many machines. To move machines, deactivate first (below).
What if my server can't reach the license server?
Your cached, still-valid token keeps the paid tier for a 7-day grace period, then re-activates automatically once you're back online. Past 7 days unreachable, you fall back to Free until the next successful check.
Can I transfer my license to a new server?
Licenses are machine-bound, so you can't just copy files. The key lives in the LICENSE_KEY
environment variable rather than in ./data, and a new machine or wiped data volume gets a new
instance ID the token won't match. Click Deactivate Machine in the license portal, then bring
NullReport up on the new machine with the same LICENSE_KEY and let it re-activate.
Lost your key, or need billing?
Open your customer portal via the Lemon Squeezy magic link emailed to you to view or re-copy your key and manage billing (Lemon Squeezy is our merchant of record).
Do you collect any usage data?
No telemetry, no usage tracking, and no report data sent anywhere. The only outbound calls are to the license server to activate and refresh your key.