Open source · Apache 2.0 / BSL 1.1

You don’t have to build your own license server.

BeanGuard issues, encrypts, and verifies licences for Java and Spring Boot applications — every limit and feature you sell can be enforced by a signed, tamper-proof token, instead of a string compared in an if statement.

$ docker compose up -d · mvn install · dev.beanguard

beanguard-server · POST /licences/issue

eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMjU2R0NNIn0.k3Jd9Qm2vB7…Zx8pL4wN.9fq2X_rT.a1F7cE0kQmZs…v6Yb3Lp9Rw2Tn

✓ signature verified · RS256

{
  "type": "STANDARD",
  "expiration": "2027-01-01",
  "claims": {
    "seats": "25",
    "advanced-reports": "true"
  }
}

The problem

Every vendor rebuilds this — and it rarely goes well.

Hand-rolled licence keys that are hard to audit, rotate, or revoke.

No self-serve way for a customer to buy and activate a licence.

Feature gating scattered across if-statements instead of enforced in one place.

BeanGuard can replace all three with infrastructure you run yourself — self-hosted, source-available, and truly yours.

Who it’s for

Built for the vendor, not the enterprise buyer.

If you sell software with limits — seats, projects, features, tiers — BeanGuard can be the layer between “we agreed on a contract” and “the app actually enforces it.”

Indie developers
Selling a Spring Boot backend, a plugin, or a self-hosted product and tired of writing licensing code instead of product code.
Agencies
Licensing white-label software per client, with different feature sets and limits for each deployment.
B2B vendors
Shipping on-prem or self-hosted deployments where you can't rely on a SaaS control plane to enforce anything.

How it works

Four modules. One licence, start to finish.

01

Issue

beanguard-server

Signs and encrypts a licence, stores the keys, exposes the REST API.

02

Configure

beanguard-admin

Manage templates, limits, orders, and customers from a panel.

03

Sell

beanguard-shop

Customers buy and activate their own licence, no manual step.

04

Enforce

beanguard-client

Your app checks it with one annotation. That's the whole integration.

Client library

One annotation, not a licensing system.

TeamService.java
@RequiresValidLicence
@IncreasesLicenceLimit("seats")
@DecreasesLicenceLimit("seats")
public User inviteTeamMember(TeamId team) {
    // your code — licence already checked
    ...
}

beanguard-client fetches, decrypts, and caches the licence on startup and refreshes it hourly — your code just asks.

Under the hood

SignedJWS · RS256

Every licence is signed with an RSA key pair — tampering breaks the signature.

EncryptedJWE · AES-256-GCM

The signed licence is then encrypted, so its claims aren't readable in transit or at rest.

Key stays put

The RSA private key never leaves the server's database. Nothing to leak from a client binary.

Open core
Apache 2.0beanguard-api, beanguard-client
BSL 1.1server, admin, shop, docs

BSL converts to Apache 2.0 four years after each release. Self-hosting to licence your own product is free, permanently.

Maven Central
dev.beanguard

You can issue your first licence this afternoon.

One docker compose up gets the server, admin panel, and shop running locally, and you can add the client library when you’re ready to start enforcing licences.