Skip to main content

Official Python client for the SDKey license authentication protocol

Project description

sdkey

Official Python client for SDKey license authentication.

Implements the sealed session protocol: Ed25519-verified handshake, HKDF session keys, and AES-256-GCM validate envelopes, plus plaintext client auth (register / login / upgrade). See PROTOCOL.md.

Install

pip install sdkey

Requires Python 3.10+.

Quick start

Embed these values from the SDKey dashboard when you ship your app. app_version must exactly match the application version configured on the server (clientVersion); mismatch returns APP_OUTDATED.

from sdkey import SdkeyClient, SdkeyError

client = SdkeyClient(
    api_base_url="https://api.sdkey.dev",
    app_id="YOUR_APP_ID",
    app_version="1.0.0",
    app_public_key_b64="YOUR_APP_PUBLIC_KEY_BASE64",
)

try:
    # hwid is optional (omit for web clients — server skips HWID checks)
    result = client.validate("SDKY-XXXX-XXXX-XXXX-XXXX", "machine-hwid")
    if result.success:
        print("licensed", result.status, result.expires_at, result.subscription_tier)
        print("message", result.message)
    else:
        print("denied", result.code, result.message)
except SdkeyError as err:
    # Init / transport failures use `error` text from the server when present
    print(err.code, err.message)
    raise

validate calls init() automatically when no session exists. Sessions last ~15 minutes server-side; on SESSION_EXPIRED the client clears local state so the next call re-handshakes.

Client auth (plaintext JSON)

reg = client.register(
    username="player1",
    password="••••••••",
    license_key="SDKY-XXXX-XXXX-XXXX-XXXX",
    hwid="machine-hwid",  # optional
)
if not reg.success:
    print(reg.code, reg.error)
else:
    print(reg.session_token, reg.user, reg.license)

login = client.login(username="player1", password="••••••••")
upgrade = client.upgrade(username="player1", license_key="SDKY-HIGHER-TIER-KEY")

upgrade takes username + license key only (no password). The new key’s subscriptionTier must be strictly greater than the user’s current tier.

Where message vs error appears

Per-app responseMessages may customize many strings. The SDK surfaces whatever the server returns.

Surface Success text field Failure text field
Session init (none) error (raised as SdkeyError.message)
Sealed validate message message
Client register / login / upgrade (none) error on ClientAuthResult

Example JSON shapes

Init failure (plaintext):

{ "success": false, "error": "Client version outdated", "code": "APP_OUTDATED" }

Sealed validate success (message):

{
  "success": true,
  "code": "OK",
  "message": "validated",
  "status": "active",
  "expiresAt": "2026-01-01T00:00:00.000Z",
  "subscriptionTier": 0,
  "sessionId": "...",
  "timestamp": 1720000001,
  "v": 1
}

Sealed validate failure (still message, not error):

{
  "success": false,
  "code": "HWID_MISMATCH",
  "message": "Hardware ID mismatch",
  "status": null,
  "expiresAt": null,
  "sessionId": "...",
  "timestamp": 1720000001,
  "v": 1
}

Client auth failure (error):

{
  "success": false,
  "error": "License tier must be higher than the current tier",
  "code": "TIER_NOT_HIGHER"
}

API

SdkeyClient(options)

Option Type Description
api_base_url str API origin (no trailing slash)
app_id str Application UUID
app_version str Exact app version → sent as clientVersion
app_public_key_b64 str Raw Ed25519 public key (32 bytes), base64
http_post callable Optional HTTP POST override (tests / custom transport)

Methods

  • init() — challenge handshake; verifies the signed hello; derives the AES session key; sends clientVersion
  • validate(license_key, hwid=None) — sealed validate; omits hwid JSON key when not provided; always decrypts then verifies the Ed25519 signature before trusting success
  • register(...) / login(...) / upgrade(...) — plaintext POST /api/v1/client/*
  • get_session() / clear_session() — inspect or drop the local session

Errors

Protocol / transport failures raise SdkeyError with a code and message (server error text when the API provides one):

INIT_FAILED · APP_OUTDATED · HELLO_SIGNATURE_INVALID · VALIDATE_RESPONSE_INVALID · RESPONSE_SIGNATURE_INVALID · SESSION_MISMATCH · CLOCK_SKEW · NETWORK

License denials (banned, HWID mismatch, etc.) return a normal ValidateResult with success=False — they are not raised. Auth denials return ClientAuthResult(success=False, code=..., error=...).

This package does not include developer tooling / Bearer (sdk_live_…) management APIs.

Security notes

  • Never ship app private keys in a client.
  • Do not skip signature verification — that is the anti-spoof binding.
  • This package is open source; the SDKey server remains a separate product.

Development

python -m pip install -e ".[dev]"
pytest

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sdkey-0.2.0.tar.gz (14.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sdkey-0.2.0-py3-none-any.whl (12.7 kB view details)

Uploaded Python 3

File details

Details for the file sdkey-0.2.0.tar.gz.

File metadata

  • Download URL: sdkey-0.2.0.tar.gz
  • Upload date:
  • Size: 14.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for sdkey-0.2.0.tar.gz
Algorithm Hash digest
SHA256 69a97c1eba5cfcc5c501e12d7eec6af2d501be3a84943896ff8cf23ae0039ec0
MD5 17404e89ab7bdb45fa955f42ffa9a1ea
BLAKE2b-256 0b36d6b38d160621d921c57f32f38e960eb1bdd6bb7a2c0bbfc7ef87f5230bf2

See more details on using hashes here.

Provenance

The following attestation bundles were made for sdkey-0.2.0.tar.gz:

Publisher: publish.yml on SDKeyDev/sdkey-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file sdkey-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: sdkey-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 12.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for sdkey-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4f645392c93ac4cdbc8452e7625ff84460fadd31d777f26c4296770657c7f601
MD5 a67ca77f7bf5c7c7337412e4ef7ecdb1
BLAKE2b-256 47ec123300cc7a661a03da0837f936500847e87da78b4069f22345482f61f1f2

See more details on using hashes here.

Provenance

The following attestation bundles were made for sdkey-0.2.0-py3-none-any.whl:

Publisher: publish.yml on SDKeyDev/sdkey-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page