edge 12 min read

LicenseValidator API Reference

Complete reference for LicenseValidator, LicenseInfo, LicenseStatus, DevModeValidator, environment variables, local vs remote validation, and trust anchor integration.

Published Jun 2, 2026

Overview

The Pyvorin Edge licensing system uses a cascading validation strategy: dev mode override, local file verification with Ed25519 signatures, remote server validation via HTTPS, and finally a fallback to invalid. The LicenseValidator class implements this cascade, while DevModeValidator provides a convenience subclass that always returns valid for development and CI environments.

LicenseStatus Enum


class LicenseStatus(Enum):
    VALID = "valid"
    EXPIRED = "expired"
    REVOKED = "revoked"
    INVALID = "invalid"
    NOT_FOUND = "not_found"
  

All validation results return one of these statuses. NOT_FOUND is currently reserved and not emitted by the production validator.

LicenseInfo Dataclass


@dataclass
class LicenseInfo:
    status: LicenseStatus
    device_id: str
    issued_at: datetime
    expires_at: datetime
    features: List[str] = field(default_factory=list)
  
FieldTypeDescription
statusLicenseStatusValidation result state.
device_idstrThe device fingerprint passed to validate().
issued_atdatetimeUTC timestamp when the license was issued.
expires_atdatetimeUTC timestamp when the license expires.
featuresList[str]List of enabled feature flags.

LicenseValidator

Constructor


class LicenseValidator:
    def __init__(self) -> None:
        ...
  

The constructor takes no arguments. All configuration is driven by environment variables and filesystem state.

validate(license_key, device_fingerprint)


def validate(self, license_key: str, device_fingerprint: str) -> LicenseInfo
  
ParameterTypeDescription
license_keystrThe license key string. Used for remote validation; ignored in dev mode and local file validation (which rely on file contents).
device_fingerprintstrA unique identifier for the device, typically derived from CPU serial, MAC address, or a hardware-bound UUID.

The validation cascade executes in this order:

  1. Dev mode: If PYVORIN_DEV_MODE=1, returns VALID immediately with default features and an expiry of 2099-12-31.
  2. Local file: If ~/.pyvorin/license.json exists, verify Ed25519 signature, check expiry, and validate device fingerprint binding. Returns VALID, EXPIRED, or INVALID.
  3. Remote server: If PYVORIN_LICENSE_URL is set, POST {license_key, device_fingerprint, version} to the URL. Returns the server's status mapping.
  4. Fallback: Returns INVALID with empty features and immediate expiry.

from pyvorin_edge.licensing.stub import LicenseValidator

validator = LicenseValidator()
info = validator.validate(
    license_key="PYV-LIVE-XXXX-XXXX",
    device_fingerprint="a1b2c3d4e5f6",
)
print(info.status)       # LicenseStatus.VALID
print(info.features)     # ['edge_runtime', 'bundle_signing', 'offline_mode', 'basic_telemetry']
print(info.expires_at)   # datetime(2099, 12, 31, 23, 59, 59, tzinfo=timezone.utc)
  

get_features()


def get_features(self) -> List[str]
  

Returns the default feature list. This does not perform validation; it is a static capability query.


print(validator.get_features())
# ['edge_runtime', 'bundle_signing', 'offline_mode', 'basic_telemetry']
  

is_feature_enabled(feature)


def is_feature_enabled(self, feature: str) -> bool
  

Checks whether a feature name is present in the default feature list. For runtime feature gating, validate the license first and check LicenseInfo.features instead.


assert validator.is_feature_enabled("edge_runtime")
assert not validator.is_feature_enabled("enterprise_analytics")
  

DevModeValidator


class DevModeValidator(LicenseValidator):
    def validate(self, license_key: str, device_fingerprint: str) -> LicenseInfo:
        return self._valid_info(device_fingerprint)
  

A subclass that bypasses all validation checks and always returns VALID. Useful for:

  • Local development
  • CI/CD pipelines
  • Integration tests that should not depend on license server availability

from pyvorin_edge.licensing.stub import DevModeValidator

validator = DevModeValidator()
info = validator.validate("any-key", "any-device")
assert info.status == LicenseStatus.VALID
  

Environment Variables

VariableEffect
PYVORIN_DEV_MODE=1Skips all validation and returns VALID with default features.
PYVORIN_LICENSE_URLHTTPS endpoint for remote license validation. If set and no local license exists, a POST request is sent here.

Local License File Format

The local license file at ~/.pyvorin/license.json must contain:


{
  "payload": {
    "device_id": "a1b2c3d4e5f6",
    "issued_at": "2024-01-15T10:00:00Z",
    "expires_at": "2025-01-15T10:00:00Z",
    "features": ["edge_runtime", "bundle_signing", "offline_mode", "basic_telemetry"]
  },
  "signature": "deadbeef...",
  "public_key": "cafebabe..."
}
  

The signature is an Ed25519 signature over the canonical JSON of the payload (sorted keys, no whitespace). The public key is the hex-encoded Ed25519 public key used to verify the signature.

Local vs Remote Validation

AspectLocal FileRemote Server
Network requiredNoYes
Revocation checkNo (file must be deleted)Yes (server returns REVOKED)
Device bindingYes (payload.device_id)Server-side logic
Latency~1 ms (file + crypto)~50-500 ms (HTTPS roundtrip)
Best forOffline edge devicesCloud-managed fleets

Trust Anchor Integration

The validator uses the cryptography library's Ed25519 implementation. The public key embedded in the license file acts as the trust anchor. There is no central certificate authority; instead, each license file is self-contained with its own verification key.

For enterprise deployments, you can pre-install a fleet-wide public key on devices and validate licenses signed with the corresponding private key. The private key should never leave your license-management server.


from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
import json, base64

# Generate a fleet key pair (do this once on your license server)
priv = Ed25519PrivateKey.generate()
pub = priv.public_key()

pub_hex = pub.public_bytes(
    encoding=serialization.Encoding.Raw,
    format=serialization.PublicFormat.Raw
).hex()

# Sign a license payload
payload = {
    "device_id": "a1b2c3d4e5f6",
    "issued_at": "2024-01-15T10:00:00Z",
    "expires_at": "2025-01-15T10:00:00Z",
    "features": ["edge_runtime", "bundle_signing"],
}
canonical = json.dumps(payload, sort_keys=True, separators=(",", ":")).encode()
signature = priv.sign(canonical)

license_file = {
    "payload": payload,
    "signature": signature.hex(),
    "public_key": pub_hex,
}

import pathlib
pathlib.Path("~/.pyvorin/license.json").expanduser().write_text(
    json.dumps(license_file, indent=2)
)
  

Backward Compatibility

LicenseStub is an alias for DevModeValidator, maintained for existing tests and consumers:


from pyvorin_edge.licensing.stub import LicenseStub

# LicenseStub is DevModeValidator
assert LicenseStub is DevModeValidator
  

Complete Example: License Check on Startup


import os
import sys
from pyvorin_edge.licensing.stub import LicenseValidator, LicenseStatus

def check_license() -> bool:
    validator = LicenseValidator()
    fingerprint = os.environ.get("DEVICE_FINGERPRINT", "unknown")
    key = os.environ.get("PYVORIN_LICENSE_KEY", "")

    info = validator.validate(license_key=key, device_fingerprint=fingerprint)

    if info.status == LicenseStatus.VALID:
        print(f"License valid until {info.expires_at}")
        print(f"Features: {info.features}")
        return True
    elif info.status == LicenseStatus.EXPIRED:
        print("License expired. Renew at https://pyvorin.com/account")
        return False
    else:
        print(f"License validation failed: {info.status.value}")
        return False

if __name__ == "__main__":
    if not check_license():
        sys.exit(1)
    # Continue with normal startup...