iotta / docs / commercialization.md
📖 commercialization.md

iotta — Commercialization Model

How iotta is licensed, packaged, and (eventually) monetized. This is the business-model companion to product.md. The cross-cutting decision behind it is D4 in decisions.md.

Status: licensing settled (dual-licensed — see below); the device cap, the license-key entitlement, and the commercial-tier features described here remain roadmap as code — see readiness-roadmap.md. This document is the plan of record.


Posture in one paragraph

iotta is self-host-first and open-core: the source is open to read, run, and modify, and the core always runs with no required cloud dependency. A free Community edition covers demos, solo use, and evaluation; a commercial license unlocks operating a real fleet and the team/operations features around it. Enforcement is soft and honest — a visible, license-backed gate, not hard DRM.

Licensing — settled (dual-licensed open-core)

  • Core source: Functional Source License 1.1, ALv2 (FSL-1.1-ALv2). Free to read, use, modify, and self-host for any Permitted Purpose — including internal and non-competing commercial use. It prohibits Competing Use (offering iotta itself as a competing product/service) and auto-converts to Apache-2.0 two years after each release.
  • Paid edition: a separate commercial license, activated by a license key. It governs operating beyond the built-in device cap and using the commercial-only features, and adds a no-circumvention clause.
  • Why this split: FSL keeps the core maximally open and adoption-friendly; the commercial license carries the paid terms. Note that FSL by itself permits internal commercial use at any scale — so the device cap is not enforced by the FSL. The cap is a contractual + key-activated boundary under the commercial license (honor-system + key + audit), not a hard DRM lock. That is the deliberate trade for a simple, open core.

The open-core boundary

The entire development platform stays free — that's the adoption engine and the part a single engineer or a CEO doing a demo should never hit a wall on. Only scale and team/operations capabilities sit behind the commercial line.

Capability Community (free) Commercial
Voice runtime (ASR/LLM/TTS, tools, interruption)
Software device client + (roadmap) web simulator
Tracing, replay, eval runner
Tool & prompt registry (versioning + promotion)
Device registry, provisioning, safe OTA + rollback
Operator UI, iotta-doctor, backup/restore, TLS
Active device count capped (e.g. 10) unlimited / licensed tier
Multi-user accounts, roles (RBAC), audit log
Advanced rollout automation (policy scheduler at scale)
Long-retention analytics / history export
SSO / directory integration ✅ (enterprise)

The boundary is drawn so commercialization is a packaging decision, not a refactor — each gated capability lives behind a clean module seam (D4).

The device cap — model and enforcement

The free tier is gated on active device count because it is the one metric that is honest, self-evident, and structurally easy to enforce in this codebase.

Can a cap be enforced in source-available software? Not as unbreakable DRM — anyone can edit open source. But a device cap is unusually well-suited to a soft, license-backed gate here, for three reasons:

  1. One chokepoint. Every device joins the fleet through a single code path — DeviceRegistry.register / build_provision_response in server/src/iotta/devices.py. One quota check covers the whole product; there is no scattered gating to maintain.
  2. A first-class metric. "Active devices" is already a counted concept in the registry. Unlike abstract feature flags, the count is obvious and meaningful to everyone.
  3. The commercial license backs the gate. The cap is visible in the FSL'd source (FSL permits internal modification, so it is not a hard lock); the right to operate beyond it is granted only by the separate commercial license, which forbids circumventing the device-cap / license-key checks. The technical gate enforces honesty; the commercial license enforces legality. This is the GitLab/Sentry-style open-core-with-usage-limit model.

Proposed mechanism (roadmap — matches D4 "soft entitlement, no hard DRM")

  • A new clean module seam, server/src/iotta/entitlement.py, exposing a single check_device_quota() call invoked at the provisioning chokepoint.
  • A signed license key — an Ed25519-signed JSON document {tier, max_devices, expiry, licensee} verified at startup against a public key embedded in the build. No phone-home, no network call.
  • No key → Community tier, capped at N active devices (default 10). A commercial key raises or removes the cap.
  • Enforcement is visible and soft: provisioning the (N+1)th active device is refused with a clear upgrade message; the operator UI shows an over-limit banner; iotta-doctor reports entitlement status. Demos and tinkering never hit a wall inside the cap.
  • Honest framing: this stops casual over-use and keeps commercial users licensed; it does not (and is not meant to) stop someone who edits and rebuilds the source. That is the right trade for "demo / solo / commercial-evaluation → license."

Pricing & packaging (sketch — not final)

Edition Who Devices Notable
Community Solo devs, demos, evaluation Up to ~10 active Full dev platform, self-hosted, free
Pro / Commercial A team shipping a product Licensed (per-fleet / per-device-band) Removes cap; multi-user RBAC + audit; support
Enterprise Larger orgs Negotiated SSO/directory, long-retention analytics/export, priority support

Pricing levels are intentionally unspecified here — the structure (free core + device-cap + team tier) is the decision; the numbers are a go-to-market exercise.

Build status

Piece State
Open-core posture, boundary, clean seams Decided (D4)
LICENSE (FSL-1.1-ALv2) + LICENSE-COMMERCIAL.md ✅ Settled
entitlement.py + device-cap enforcement Roadmap (Tier 2)
License-key signing/verification Roadmap (Tier 2)
Multi-user RBAC + audit (commercial tier) Roadmap (Tier 3 / Phase 8)

See readiness-roadmap.md for sequencing and decisions.md (D4) for the underlying decision.