npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@aikdna/kdna-activation-server

v0.2.1

Published

Self-hostable KDNA entitlement service for license activation, synchronization, revocation, and signed status records.

Readme

@aikdna/kdna-activation-server

Experimental self-hostable HTTP activation server for KDNA licensed assets.

KDNA makes judgment portable across models and runtimes. This repository is an experimental entitlement reference implementation, not a marketplace, billing service, or AIKDNA-hosted activation platform.

This package implements the legacy license-key and signed-receipt profile. It is not an RFC-0019 account/device external-key-grant issuer. Implementations must not present one profile as the other.

The registry package at 0.2.0 is the published baseline. Repository 0.2.1 is an unreleased source candidate containing the secret-input and verifier-at-rest corrections below; it is not npm latest and a checkout is not evidence of publication.

This server answers one question:

Is this user / device / organisation currently entitled to use this asset?

It implements the four endpoints in specs/kdna-entitlement-api.md and the self-hosting invariant from docs/REMOTE_MODE.md.

The responsibility routes documented below are the only public HTTP contract. In particular, Remote 0.4.1 and later send entitlement refreshes to /entitlements/sync; deploy Activation 0.2.0 before Remote 0.4.1 or later. The server validates every entitlement domain against the authoritative asset_id grammar shipped by KDNA Core 0.21.0.


Self-hosting is the default

The KDNA protocol MUST NOT assume a single official KDNA server. Any asset creator can run their own activation server. No AIKDNA-hosted activation service is part of the current public baseline.

This server is the deployer's own. The protocol does not hardcode any KDNA Inc. URL. The admin token is deployer- controlled. License records are deployer-controlled. The server's signing keypair is generated on first start and stored locally.


Quick start (self-hosting)

# 1. Start from a trusted exact 0.2.1 source checkout on Node 18+.
npm ci
npm test
npm pack
npm install -g ./aikdna-kdna-activation-server-0.2.1.tgz

# 2. Create private input files without placing secrets in shell arguments.
install -m 600 /dev/null ./license-request.json
${EDITOR:?Set EDITOR} ./license-request.json
kdna-activation-server --create-license-file ./license-request.json
rm ./license-request.json

install -m 600 /dev/null ./admin-token
${EDITOR:?Set EDITOR} ./admin-token

# 3. Start the server. The token file must remain private.
kdna-activation-server --port 3001 --admin-token-file ./admin-token

# 4. Test. Create the request body with a private editor, not inline argv.
curl http://localhost:3001/healthz
install -m 600 /dev/null ./activation-request.json
${EDITOR:?Set EDITOR} ./activation-request.json
curl -X POST http://localhost:3001/entitlements/activate \
  -H 'Content-Type: application/json' \
  --data-binary @./activation-request.json
rm ./activation-request.json

That's it. No registration, no phone-home, no KDNA Inc. URL. Do not replace a placeholder with a real secret inside a command argument. --create-license-stdin and --admin-token-stdin are available when a deployer's secret provider can pipe bounded strict UTF-8 directly. The CLI rejects unknown options, unexpected positional values, duplicate options, cross-mode combinations, and values attached to boolean stdin flags; these errors never echo the rejected token.


HTTP API

GET /healthz

Health check. Returns 200 with server metadata.

GET /server/identity

Returns the server's Ed25519 public key (PEM, hex, and fingerprint). Clients use this to verify that an entitlement record was really signed by this server.

POST /entitlements/activate

Activates a license. Returns a signed entitlement record (cryptographically verifiable against /server/identity).

Request body:

{
  "domain": "kdna:yourname:your-asset",
  "license_key": "<license-secret>",
  "machine_fingerprint": "<sha256>"
}

Optional: client, client_version, agent, account_id, device_label.

machine_fingerprint is required when the license was created with require_machine_binding: true (the default). Its canonical wire format is exactly 64 lowercase hexadecimal characters: the SHA-256 digest produced by the client. Uppercase, prefixed, whitespace-padded, non-ASCII, short, and long forms are rejected rather than normalized into aliases.

Response (200): the signed entitlement record (see specs/kdna-entitlement-api.md §5). The response and its signed body never contain license_key; clients only send that secret in activation and sync request bodies.

domain is the entitlement contract field for the Core manifest asset_id. Its value must satisfy the canonical asset identity grammar from Core 0.21.0's published manifest.schema.json. No alternate package-name syntax is accepted as a second identity format.

Errors:

  • INVALID_LICENSE_KEY (404) — key does not match the domain
  • LICENSE_REVOKED (403) — license has been revoked
  • LICENSE_EXPIRED (403) — expires_at is in the past
  • MISSING_MACHINE_FINGERPRINT (400) — a bound license omitted its fingerprint
  • INVALID_MACHINE_FINGERPRINT (400) — the fingerprint is not canonical
  • MACHINE_MISMATCH (403) — the license is bound to another machine or has not yet been activated on this machine

POST /entitlements/sync

Refreshes the entitlement state (updates last_checked_at and offline_valid_until). domain and license_key are required; license_id is optional but, when present, must identify that same license. Machine-bound licenses must already have been activated and must send the same canonical machine_fingerprint. Returns the signed record. Same errors as /activate.

POST /entitlements/revoke (admin)

Revokes a license. Requires an Authorization: Bearer <admin-token> header. The admin token is set at server startup.

Request body:

{
  "license_id": "lic_abc123",
  "domain": "kdna:yourname:your-asset",
  "reason": "payment_failed",
  "revoked_by": "billing-system"
}

GET /entitlements/status?domain=...&license_id=...&machine_fingerprint=...

Introspection. Returns public entitlement metadata (unsigned, for introspection only) and does not include license_key. Both the canonical scoped domain and license_id are required. The status endpoint rejects license_key entirely so the secret cannot appear in URLs or access logs; use /activate or /sync for signed entitlement records. For machine-bound licenses, status requires the already-bound canonical fingerprint and never creates a first binding. Error responses do not include license metadata, the submitted fingerprint, or the stored binding digest. Missing, malformed, mismatched, and not-yet-bound machine authorization all return the same NOT_FOUND response as an unknown record, so public license_id values cannot be used as a binding-enumeration oracle.


CLI

# Create a license (one-shot) from a private request body
kdna-activation-server --create-license-stdin < ./license-request.json
# or: kdna-activation-server --create-license-file ./license-request.json

# List all licenses
kdna-activation-server --list

# Revoke
kdna-activation-server --revoke lic_abc123 --reason "payment_failed"

# Start the server with one private token source
kdna-activation-server --port 3001 --admin-token-file ./admin-token
# or: kdna-activation-server --port 3001 --admin-token-stdin

The server keypair is auto-generated on first start and stored at ~/.kdna/activation-server/. The private key is mode 0600.


Security properties

  • No KDNA Inc. URL is hardcoded. The server has zero outbound network calls during normal operation.
  • The server keypair is local. The private key never leaves the deployer's machine.
  • The admin token is deployer-controlled. Set it at startup through bounded strict UTF-8 stdin or a private regular file, or omit it to disable /revoke over HTTP. Raw --admin-token argv is rejected.
  • The license_key is a request secret. It is accepted only in activation and sync JSON request bodies. The server does not return it in signed records, status responses, errors, or command output. Clients should not place it in URLs, argv, or logs. License creation reads private JSON through stdin or a private file; raw --create-license argv is rejected.
  • License secrets are verifier-only at rest. New records store an independently salted, bounded-parameter scrypt verifier, never the plaintext license_key. Verification is constant-time. A legacy plaintext record is atomically rewritten only after the caller supplies the exact old secret; failed verification or concurrent drift leaves the original bytes intact. Salt and verifier bytes are server-only and are not usable as a license key.
  • Records are signed. Every /activate and /sync response is signed with the server's Ed25519 key. Clients can verify against /server/identity.
  • Raw machine fingerprints are not stored by new activations. The server derives a purpose-separated HMAC key from its local private key and stores only the keyed binding digest. A matching request migrates an older raw fingerprint record in place; malformed legacy bindings fail closed.
  • License record filenames are collision-free. Each validated license identifier has one encoded storage path. Exact legacy records migrate on write, while a different identifier that shared an older sanitized filename is never treated as an alias. Directory scans only discover identifiers; activation, listing, and key lookup always re-read the authoritative path.
  • HTTP routing is origin-form only. Requests require one syntactically valid Host header, while route selection uses a fixed internal base rather than the supplied host. Absolute request targets and Host values containing credentials, paths, queries, or fragments are rejected.
  • JSON bodies are byte-bounded and strictly decoded. Activation, sync, and revocation accept at most 64 KiB of UTF-8 bytes. Oversized, malformed UTF-8, and malformed JSON inputs receive stable errors without parser details.

Local development

git clone https://github.com/aikdna/kdna-activation-server
cd kdna-activation-server
npm test

The tests spin up the server on an OS-assigned port. No external services are required.


License

Apache 2.0. See LICENSE.

This server is a license-management reference implementation. Trust is the consumer's decision, not the server's claim.