cd ..
inkan(1)Mizuchi Labs Manualinkan(1)
mizuchi:~$man inkan

NAME

inkan

A ledger for offline license keys, with Stripe subscriptions turned into keys.

★ 0 · last pushed 2026-10-17

DESCRIPTION

Inkan holds the signing key of each product you sell, issues license keys by hand, shows the paid licenses of your Stripe subscriptions, and tells you what a pasted key really is.

A key is a signed string that your app verifies offline with a public key built into it. It needs no network and no secret. Packages for Go, TypeScript and Python verify, hold and renew keys, and a documented format with test vectors covers every other language.

The dashboard is one binary with SQLite and a web UI, and it stays private. A small worker is the public side of one product. It reads Stripe, signs the keys of the paid licenses, mails them to customers and renews them for apps that are online. Keys issued by hand need no worker.

FEATURES

  • License keys that work offline, a plain string to paste or set as an env
  • Issue keys by hand, or let Stripe subscriptions and one time purchases become licenses
  • A worker that reads Stripe, mails keys and renews them, on Cloudflare Workers, Scaleway Functions or anywhere Node runs
  • Go, TypeScript and Python packages that verify, hold and renew keys
  • Keys can be bound to one machine with a fingerprint
  • Paste any key to see what is inside
  • Daily history of active licenses per product and plan
  • One binary with SQLite and a web UI, Docker-ready

QUICK START

Docker
docker run -d \
   -p 127.0.0.1:3000:3000 \
   -v $(pwd)/data:/data \
   -e INKAN_ADDR=:3000 \
   -e INKAN_DATA_DIR=/data \
   -e INKAN_PASSWORD=change-me \
   ghcr.io/mizuchilabs/inkan:latest
Docker Compose
services:
  inkan:
    image: ghcr.io/mizuchilabs/inkan:latest
    container_name: inkan
    ports:
      - "127.0.0.1:3000:3000"
    volumes:
      - ./data:/data
    environment:
      - INKAN_ADDR=:3000
      - INKAN_DATA_DIR=/data
      - INKAN_PASSWORD=change-me
    restart: unless-stopped
Verify in Go
import "github.com/mizuchilabs/inkan/license"

// The public key from the Products page. It is no secret.
const publicKey = "03a107bf…"

lic := license.NewKeeper("MYAPP", publicKey, "")
_, err := lic.Set(os.Getenv("MYAPP_LICENSE_KEY"))

ok := lic.Valid()             // is there a license right now
Backups
inkan keys              # prefix and signing key of every product
inkan backup            # a copy of the database, next to it

CONFIGURATION

NameDescription
INKAN_ADDRAddress to listen on. Also --addr. Default: 127.0.0.1:3000.
INKAN_DATA_DIRDirectory for the database. Also --data-dir. Default: data.
INKAN_PASSWORDPassword for the UI. Also --password. Without one Inkan only answers on localhost.
INKAN_API_TOKENBearer token for scripts. Also --api-token. The API is described at /docs.
INKAN_DEBUGEnable debug logging. Also --debug. Default: false.

RELATED

LINKS

GitHub[github]https://github.com/mizuchilabs/inkan
SELF-HOSTED VS COMMERCIAL

Self-hosting inkan is free under the Apache-2.0 license. Run it on your own iron. Commercial licensing, support, and managed offerings for businesses are on the business page.