Skip to content

Licensing

Normal Framework devices require a license to operate. This page explains how licensing works, how to activate a device, and how to set up zero-touch auto-provisioning for enterprise deployments.

License Flow Overview

stateDiagram-v2
    [*] --> Unlicensed
    Unlicensed --> Activated : Admin creates license & activation
    Unlicensed --> Licensed : Auto-provision (enterprise)
    Unlicensed --> Licensed : Browser sign-in
    Activated --> Licensed : Device links activation code
    Licensed --> Licensed : Periodic renewal
    Licensed --> Unlicensed : License revoked or expired

There are three paths to get a device licensed:

  1. Browser sign-in -- the installer prints a short code, you sign in to the portal and approve it, and the device is licensed without any keys being copied by hand. This is the simplest path and the one used for free-tier sites.
  2. Manual activation -- an admin creates a license in the portal and the device links it using an activation code.
  3. Auto-provision -- enterprise tenants can generate a secret key that allows devices to self-register and obtain a license automatically.

Browser Sign-In

Browser sign-in uses a device authorization grant, the same pattern used to sign in to apps on a TV. A single sign-in authorizes both the container registry pull and the license, so there are no registry tokens or license keys to copy between the portal and the device.

sequenceDiagram
    participant User as User (browser)
    participant Portal as Online Service
    participant Device as NF Device

    Device->>Portal: StartDeviceProvision()
    Portal-->>Device: device_code + user_code + URL
    Note over Device: Displays code and link
    User->>Portal: Open /activate, sign in, approve
    Portal-->>User: Choose org, license, site details, accept terms
    Device->>Portal: PollDeviceProvision(device_code)
    Portal-->>Device: Registry pull credentials
    Note over Device: Pulls images and starts
    Device->>Portal: CompleteDeviceProvision(device_code, machine_id)
    Portal-->>Device: License JWT
    Note over Device: Device is now licensed
  1. The installer calls StartDeviceProvision and displays a short user code along with a link to the portal.
  2. You open the link, sign in, and approve the device. If you belong to more than one organization you pick which one the site should join, then name the site and accept the terms of service.
  3. Approval mints registry pull credentials, which the installer collects by polling PollDeviceProvision. The images are pulled and NF starts.
  4. Once NF is running it has a machine id, so the installer calls CompleteDeviceProvision -- authorized by the approved device code, with no second sign-in -- and receives the license JWT.

Note

The device is not created in the portal until the final step. If you approve a device that never finishes installing, no instance is left behind.

Free-tier sites

Approving a device without selecting an existing license mints a free-tier license. Each user may have one active free-tier site at a time, and the entitlement is portable: activating a new free site deactivates the previous one and moves the entitlement to the new device. The portal warns you before this happens.

To license a device against a subscription or enterprise license instead, select it from the list of un-activated licenses during approval.

Manual Activation

Manual activation uses a short-lived activation code to bind a license to a device.

sequenceDiagram
    participant Admin as Portal Admin
    participant Portal as Online Service
    participant Device as NF Device

    Admin->>Portal: Create License
    Admin->>Portal: Activate License (select instance)
    Portal-->>Admin: Activation code (8 characters, valid 15 min)
    Admin->>Device: Enter activation code
    Device->>Portal: LinkLicense(code, machine_id)
    Portal-->>Device: License JWT + acknowledge token
    Device->>Portal: AcknowledgeLicense(ack_token)
    Portal-->>Device: Confirmed
    Note over Device: Device is now licensed
  1. An admin creates a license in the Normal portal and activates it for a specific instance.
  2. The portal generates an activation code (8 characters, valid for 15 minutes).
  3. The admin enters the code on the device. The device calls LinkLicense, which returns a license JWT and an acknowledge token.
  4. The device confirms receipt by calling AcknowledgeLicense. This prevents the code from being rolled back.

Note

If the activation code expires or is not acknowledged within 15 minutes, the admin can regenerate it from the portal.

Auto-Provision (Enterprise)

Enterprise tenants can enable zero-touch provisioning so that new devices automatically register and obtain a license on first boot.

sequenceDiagram
    participant Admin as Portal Admin
    participant Portal as Online Service
    participant Device as NF Device

    Admin->>Portal: Generate auto-provision key
    Portal-->>Admin: Secret key
    Note over Admin,Device: Configure device with AUTO_PROVISION_KEY
    Device->>Portal: AutoProvision(key, machine_id)
    Portal-->>Device: License JWT + instance UUID
    Note over Device: Device is licensed and online

Setup

  1. In the Normal portal, navigate to your enterprise tenant and generate an auto-provision key.
  2. Set the AUTO_PROVISION_KEY environment variable on the device to the generated key.
  3. On startup, if the device has no license, it will automatically contact the portal and provision itself.

Behavior

  • On startup with no license, the device retries auto-provision with exponential backoff (up to 5 attempts).
  • If provisioning fails, the device retries every 15 minutes in the background.
  • If the portal returns a permanent error (invalid key, wrong tenant type), retries are disabled to avoid unnecessary traffic.
  • Auto-provision is idempotent -- if a device with the same hardware fingerprint already exists in the tenant, the portal re-issues the existing license rather than creating a duplicate.

Revoking

To stop new devices from auto-provisioning, revoke the key in the portal. Existing devices keep their licenses; only new registrations are blocked.

License Renewal

Once licensed, devices periodically renew their license JWT to keep it current.

stateDiagram-v2
    state "Licensed" as L
    state "Check Every 15 min" as C

    L --> C
    C --> L : Renewal successful
    C --> L : License still valid
    C --> Unlicensed : Portal says invalid
  • Every 15 minutes, the device checks its license status.
  • If the license is approaching expiration, the device calls ReIssueLicense to get a fresh JWT.
  • If the portal reports the license as invalid, the device clears its local license and stops licensed services.
  • Enterprise devices with an auto-provision key will automatically re-provision if they lose their license.

License Types

Type Expiration Grace Period Auto-Provision
Free tier 30 days, re-provision to renew None No
Subscription (GA) Set by subscription period 14 days after expiry No
Enterprise Renewed automatically N/A Yes
Demo Fixed expiration None No
  • Free tier licenses are minted by browser sign-in and last 30 days. One per user at a time, and activating a new free site moves the entitlement off the old one.
  • Subscription licenses are tied to a Stripe subscription. When the subscription ends, the license enters a 14-day grace period before services are de-provisioned.
  • Enterprise licenses are perpetual as long as the tenant is active. The JWT is refreshed periodically but the license itself does not expire.
  • Demo licenses have a fixed expiration and cannot be renewed.

Environment Variables

Variable Default Description
LICENSE /var/nf/license.jwt Path to the license JWT file
AUTO_PROVISION_KEY (empty) Enterprise auto-provision secret key