> For the complete documentation index, see [llms.txt](https://docs.licensespring.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.licensespring.com/license-entitlements/license-activation-types/tpm-licensing.md).

# TPM Licensing

In the LicenseSpring platform, you can generate and customize licenses that require a **TPM** (Trusted Platform Module). A TPM-required license can only be activated and used on a device with a hardware-protected key store. Every subsequent request must be signed by that device's key.

{% hint style="warning" %}
TPM licensing is an add-on feature in LicenseSpring. Contact sales to enable it on your account.
{% endhint %}

Unlike [Hardware Key Licensing](/license-entitlements/license-activation-types/hardware-key-licensing.md), TPM licensing needs no external dongle and no provisioning step. The key is created inside the hardware the end user already has:

| Platform    | Key store                                                                       |
| ----------- | ------------------------------------------------------------------------------- |
| Windows     | TPM 2.0, via the Platform Crypto Provider (per-user key, no elevation required) |
| Linux       | TPM 2.0, via `/dev/tpmrm0`                                                      |
| macOS / iOS | Secure Enclave                                                                  |

The key is a P-256 (ECDSA) key pair generated inside the security module that **never leaves it**. LicenseSpring only ever receives the public half and uses it to verify every request signature from that device.

To start using TPM licensing, you need to:

{% stepper %}
{% step %}

#### Create TPM-required licenses

* Issue licenses from LicenseSpring with the desired entitlements (max activations, features, validity period, etc.)
* Ensure `Require TPM` is ticked
  {% endstep %}

{% step %}

#### Enable TPM licensing in your application

Turn on TPM licensing in the SDK configuration and ship the hardware ID generator library alongside your application.
{% endstep %}
{% endstepper %}

### Create TPM-required licenses

`Require TPM` can be set in three places in the vendor platform:

* **License Policy** (Products → your product → License Policies) - every license issued from that policy inherits the setting
* **Create Order** - in the `License usage` section of the product configuration step
* **Edit License** - on an existing license

Click Next and Create Order.

{% hint style="info" %}
The setting can be changed on an already-issued license. Turning `Require TPM` on for an activated license means existing devices have no enrolled key. They must reactivate before checking in again.
{% endhint %}

{% hint style="warning" %}
Do not enable `Require TPM` and `Require Hardware Key` on the same license. Both are checked at activation, so the end user needs a TPM **and** a plugged-in hardware key. After activation, only the TPM signature is verified - the hardware key is no longer enforced. Pick one.
{% endhint %}

You can also read, filter and set the flag through the Management API:

* `is_tpm_auth` on License and License Policy (readable, patchable, and filterable with `?is_tpm_auth=true`)
* `tpm_public_key` on Device - the enrolled public key, empty when the device has not enrolled one
* `is_tpm_auth` is included in the license CSV export

### Enable TPM licensing in your application

TPM licensing is currently supported in the **C++ SDK**. It is disabled by default and has to be enabled explicitly in the configuration:

```cpp
auto options = LicenseSpring::ExtendedOptions();
options.enableTpmLicensing( true );

auto config = LicenseSpring::Configuration::Create(
    "your_api_key", "your_shared_key", "your_product_code", "1.0.0",
    options );
```

Requirements:

* **LicenseSpring C++ SDK** - version `8.5.0` or later
* **LicenseSpring Hardware ID Generator** - version `1.6.0` or later, deployed next to your application binary (`hardware_id_generator.dll` / `libhardware_id_generator.so` / `libhardware_id_generator.dylib`). The SDK loads it at runtime to communicate with the TPM. Older versions do not export the key store functions, and the SDK raises a `TpmException` that tells you to upgrade.

{% hint style="warning" %}
On macOS and iOS, persisting a Secure Enclave key requires the **host application process** to be code-signed with a `keychain-access-groups` entitlement backed by an embedded provisioning profile. Applications that are not signed and provisioned this way cannot use TPM licensing on Apple platforms.
{% endhint %}

### How it works

#### Enrollment happens at activation

Activation is the only point at which a TPM key is enrolled. When TPM licensing is enabled, the SDK asks the hardware ID generator for the device's public key (creating the key pair on first use) and sends it in the activation request as `tpm_enrollment.signing_public_key`, together with a `licensespring-tpm-signature` header proving the device holds the matching private key.

* If the license requires TPM and the request contains no `tpm_enrollment`, activation is rejected.
* If the request contains `tpm_enrollment` but the license does not require TPM, activation is rejected.
* The enrolled key **replaces** whatever was stored for that device on every activation. Reactivating on the same device after a TPM reset or OS reinstall simply enrolls the new key.

#### Every request afterwards is signed

Once enrolled, the SDK signs every request to LicenseSpring with the device's TPM key and sends the signature in a `licensespring-tpm-signature` header (`algorithm="ES256"`). The platform verifies it against the key enrolled for that license and device. This covers:

* License and bundle checks
* Consumption and feature consumption
* Floating license and floating feature register / release / borrow
* Device variables (send and get)
* Deactivation

A request that arrives without a valid signature is rejected, so a copied license file alone is not enough to keep a license alive on a different machine.

#### Offline activation

Offline activation is supported. Because an offline request file carries no HTTP headers, the same two values are written into the request file itself:

* `tpm_enrollment.signing_public_key` - the device's public key
* `licensespring-tpm-signature` - the signature over the request's `signature` field

Offline deactivation works the same way. No extra steps are required from the end user — the SDK writes these fields into the `.req` file automatically when TPM licensing is enabled.

{% hint style="warning" %}
**Air-gapped licenses do not support TPM.** Air-gapped activation uses its own confirmation-code exchange in the vendor platform and never carries a TPM enrollment or signature, so a license cannot be both air-gapped and TPM-required. Use regular offline activation, described above, if you need TPM enforcement without a network connection on the end user's machine.
{% endhint %}

#### Bundles

For bundle activations, sublicenses do not have to agree on TPM. Enrollment is applied to licenses that require TPM and skipped for those that do not. A mixed bundle remains activatable.

### Checking enrollment in the platform

* The **Licenses** list has an optional `Is TPM` column showing which licenses require TPM.
* On a TPM-required license, the **Devices** tab shows a `TPM enrolled` column, ticked for every device that has a key enrolled.

### Error reference

| Error code                | Meaning                                                                            |
| ------------------------- | ---------------------------------------------------------------------------------- |
| `tpm_enrollment_required` | The license requires TPM but the activation request contained no `tpm_enrollment`. |
| `tpm_not_enabled`         | The request contained `tpm_enrollment` but the license does not require TPM.       |
| `tpm_signature_required`  | The `licensespring-tpm-signature` header is missing on a TPM-required license.     |
| `tpm_signature_mismatch`  | The signature could not be verified against the enrolled public key.               |
| `tpm_invalid_public_key`  | The enrolled `signing_public_key` is not a valid P-256 public key.                 |

In the C++ SDK, all of these surface as a `TpmException`. A device with no usable TPM or Secure Enclave - or a process not entitled to use it - raises a `TpmException` with error code `eTpmKeyStoreUnavailable` before any request is sent.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.licensespring.com/license-entitlements/license-activation-types/tpm-licensing.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
