ARCHERGATE / SDK
BLENDER ADDON LICENSING

Stop your Blender addon from being shared.

Archergate wraps your Python addon with a REST validation call on startup. Keys are machine-bound. A buyer on one workstation cannot hand the key to a colleague on another.

Why most Blender addon licensing fails

Most Blender addon developers either ship without protection or rely on obfuscation. Python bytecode (.pyc) is trivially decompiled. String obfuscation survives maybe an hour of determined analysis. Network checks that validate "is this email registered" can be spoofed with a local DNS redirect.

Archergate's validation server checks the license key against a SHA-256 hardware fingerprint computed from the user's CPU and OS installation ID. The fingerprint cannot be spoofed by changing DNS or editing a hosts file. Each seat activates once per machine. The server enforces the seat count.

Blender addons run as Python inside the Blender process. Archergate provides a Python REST client that calls your self-hosted validation server. No native library linking required for Blender integration.

Python integration

Add this block to your addon's __init__.py register() function. The Archergate Python client ships as a single-file module you include with your addon.

__init__.py — validate on registration
# bl_info = { ... }
import bpy
from . import archergate  # bundled single-file client

_VALIDATED = False

def register():
    global _VALIDATED
    key = bpy.context.preferences.addons[__name__].preferences.license_key

    result = archergate.validate(
        api_key="your-api-key",
        app_id="com.you.addon_name",
        license_key=key
    )

    if not result.valid:
        raise Exception(f"License invalid: {result.error}")

    _VALIDATED = True
    # register panels, operators, etc.
    bpy.utils.register_class(MyPanel)

def unregister():
    bpy.utils.unregister_class(MyPanel)
AddonPreferences — license key UI
class MyAddonPrefs(bpy.types.AddonPreferences):
    bl_idname = __name__

    license_key: bpy.props.StringProperty(
        name="License Key",
        description="Enter your Archergate license key",
        default=""
    )

    def draw(self, context):
        layout = self.layout
        layout.prop(self, "license_key")
        if not _VALIDATED:
            layout.label(text="License required", icon="ERROR")
archergate.py — bundled with your addon (no external deps)
import urllib.request, json, hashlib, platform, subprocess

class _Result:
    def __init__(self, valid, error=None):
        self.valid = valid; self.error = error

def _fingerprint():
    cpu = platform.processor() or platform.machine()
    try:
        if platform.system() == "Windows":
            out = subprocess.check_output(
                ["wmic", "csproduct", "get", "uuid"], text=True)
            install_id = out.strip().split("\\n")[-1].strip()
        elif platform.system() == "Darwin":
            out = subprocess.check_output(
                ["ioreg", "-rd1", "-c", "IOPlatformExpertDevice"], text=True)
            install_id = [l for l in out.splitlines()
                         if "IOPlatformUUID" in l][0].split('"')[-2]
        else:
            install_id = open("/etc/machine-id").read().strip()
    except Exception:
        install_id = "unknown"
    return hashlib.sha256((cpu + install_id).encode()).hexdigest()

def validate(api_key, app_id, license_key,
              server="https://license.archergate.io"):
    payload = json.dumps({
        "api_key": api_key, "app_id": app_id,
        "license_key": license_key, "fingerprint": _fingerprint()
    }).encode()
    try:
        req = urllib.request.Request(
            server + "/validate",
            data=payload,
            headers={"Content-Type": "application/json"}
        )
        resp = json.loads(urllib.request.urlopen(req, timeout=8).read())
        return _Result(resp.get("valid", False), resp.get("error"))
    except Exception as e:
        return _Result(False, str(e))

What ships in the SDK

PYTHON CLIENT

Single-file archergate.py. Bundle it with your addon. No pip install, no external deps.

MACHINE BINDING

SHA-256 fingerprint from CPU + OS install ID. Seat locked to hardware, not email.

OFFLINE GRACE

Local signed cache valid for 30 days. Works in studios with restricted internet.

YOUR SERVER

Self-host the validation server or use managed hosting at $7/month flat.

SDK DOWNLOADS AND DOCS