Skip to main content

LSY ODS License SDK

Python PyPI License: MIT

lsyods-license-sdk is the shared Python SDK for LSY ODS machine identity and offline product licensing. It provides stable machine fingerprints, installation IDs, Ed25519 license issuance, signature verification, and license status evaluation.

Features

  • Calculate a versioned, one-way machine fingerprint on Windows and Linux.
  • Generate product-specific installation IDs.
  • Issue Ed25519-signed offline license documents.
  • Verify signatures against an explicit trusted-public-key set.
  • Bind a license to a product, software version, product edition, installation ID, and machine fingerprint.
  • Evaluate subscription, perpetual, expired, and not-yet-valid states.
  • Keep renewal history through supersedes_license_id.

The product edition represents a commercial level such as basic or advanced. Individual feature/module decisions remain in the licensed product. A perpetual license has no expiry date, but it still applies only to the software version declared in its signed claims.

Installation

Install from PyPI:

pip install lsyods-license-sdk

Or with uv:

uv add lsyods-license-sdk

Python 3.10 or newer is required.

Generate Signing Keys

The SDK includes the lsyods-license-keygen command. By default it prompts for a password and encrypts the generated Ed25519 private key:

$env:LSYODS_LICENSE_KEY_PASSWORD = Read-Host "Key password" -MaskInput

lsyods-license-keygen `
  --private-key D:\secure\license-private.pem `
  --public-key D:\secure\license-public.pem

The command prints the public key_id and public_key_base64 used by licensed products. Only the controlled license issuer may access the private key. Never ship the private key or its password with a client or licensed product.

--no-password is available for protected automated environments, but the key file must then be secured with operating-system access controls.

Machine Fingerprint

from lsyods_license_sdk import calculate_machine_fingerprint

machine_fingerprint = calculate_machine_fingerprint()
print(machine_fingerprint)  # sha256:<64 lowercase hexadecimal characters>

The SDK hashes a stable operating-system machine identifier with a versioned domain separator. It does not return the raw Windows MachineGuid or Linux machine-id.

Issue a License

License issuance belongs in a controlled server environment:

from datetime import datetime, timedelta, timezone
from pathlib import Path

from lsyods_license_sdk import (
    generate_installation_id,
    issue_license,
    load_private_key,
)

now = datetime.now(timezone.utc).replace(microsecond=0)
private_key = load_private_key(
    Path("D:/secure/license-private.pem"),
    password="private-key-password",
)

claims = {
    "license_id": "L260819000001",
    "issuer": "LSY ODS",
    "customer": "Example Customer",
    "product": {
        "code": "example-product",
        "version": "V1.0",
        "edition": "advanced",
    },
    "installation": {
        "installation_id": generate_installation_id(),
        "machine_fingerprint": "sha256:" + "a" * 64,
    },
    "license_type": "subscription",
    "issued_at": now.isoformat(),
    "not_before": now.isoformat(),
    "expires_at": (now + timedelta(days=90)).isoformat(),
}

license_document = issue_license(claims, private_key)

For a perpetual license, use license_type="perpetual" and expires_at=None.

Verify a License

Licensed products contain only trusted public keys and verify the local license against the running product and installation:

from lsyods_license_sdk import calculate_machine_fingerprint, verify_license

trusted_keys = {
    "<key_id>": "<public_key_base64>",
}

result = verify_license(
    license_document,
    trusted_keys,
    expected_product="example-product",
    expected_installation_id=installation_id,
    expected_machine_fingerprint=calculate_machine_fingerprint(),
)

if not result["valid"]:
    raise RuntimeError(f"License is {result['status']}")

licensed_version = result["claims"]["product"]["version"]
licensed_edition = result["claims"]["product"]["edition"]

The product is responsible for comparing licensed_version and licensed_edition with its compatibility and feature rules.

Renewal

Renewal creates a new signed document while retaining the existing installation ID and machine fingerprint. The previous document remains unchanged and verifiable. The new claims may include:

{
  "supersedes_license_id": "L260819000001"
}

Security Model

  • Security depends on protecting the Ed25519 private key, not hiding this SDK.
  • Products must trust only explicitly configured public keys.
  • License documents must be treated as immutable after signing.
  • A machine fingerprint is an identifier, not an authentication secret.
  • Offline licensing cannot prevent a customer from patching an application they fully control; products should enforce licensing at appropriate trust boundaries.
  • Key rotation should add the new public key before issuing licenses with it.

Development

The project uses uv and the Aliyun PyPI mirror configured in pyproject.toml:

uv sync --locked
uv run pytest
uv run pyflakes src tests
uv build --no-sources

License

Copyright (c) 2026 成都领数云科技有限公司.

Released under the MIT License.

Release files for lsyods-license-sdk 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for lsyods-license-sdk 0.1.0
File Size Uploaded
lsyods_license_sdk-0.1.0.tar.gz 12.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for lsyods-license-sdk 0.1.0
File Interpreter ABI Platform
lsyods_license_sdk-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size:23.3 kB

Release files / lsyods_license_sdk-0.1.0.tar.gz

Download URL lsyods_license_sdk-0.1.0.tar.gz
Size 12.7 kB
Tags Source
SHA-256 checksum
How to use checksums
1011d9ce311532c68574c1ae8af7682df47527eabd997a9d2b0dbaa27cd701e8
BLAKE2b-256 checksum
How to use checksums
08c309dea7cf39db723ec88b1d04a1294d9089e51807b732e687be8564730d9e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / lsyods_license_sdk-0.1.0-py3-none-any.whl

Download URL lsyods_license_sdk-0.1.0-py3-none-any.whl
Size 10.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e6c180c1adadceff02c5a0ad7562af1a77958083722b0197ca0b7daba5bee563
BLAKE2b-256 checksum
How to use checksums
6cbbf33fb0dfefde9fa974f79840f4d9dd737fc05873645b0a11d8005bf6ebc1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

0.3.0

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page