Skip to main content
OnewaySWP Banner

ONEWAYSWP

Offline One-Way License Framework

Secure · Offline · Portable · Self-Contained


Version Python License Platform



OnewaySWP is a Python library for building one-way license verification systems without requiring a server.

Licenses are generated on the admin side, distributed to clients, and verified entirely offline.

The framework internally handles license generation, cryptographic signing, protected local state, and verification. Client applications only require a public key to validate licenses.

No internet connection. No license server. No backend infrastructure.

OnewaySWP is designed for developers who want a practical licensing solution that stays portable, self-contained, and independent.


✦ Features

Feature Description
◉ Offline Verification No internet connection or license server required
◉ Auto-Detection Automatically detects the current OS and architecture
◉ Cross-Platform Supports Windows, Linux, macOS, and Android
◉ Multi-Mode Supports Date, Credit, and Duration license types
◉ Session-Based Duration Duration licenses measured during active sessions
◉ Credit System Credit-based licenses with automatic decrement
◉ Cryptographic Protection License integrity and tamper detection
◉ Protected Local Storage Local license state protected with internal protection mechanisms
◉ Clock Rollback Protection Detects system clock manipulation
◉ Multi-License Support Multiple independent license states per application
◉ Session Context Manager Automatic start/stop for duration licenses
◉ State Export & Import Move license state between environments
◉ Retry on File Lock Automatic retry when state file is locked

Installation

Install directly from PyPI:

pip install onewayswp
Command Purpose
pip Python package installer
install Installs a package
onewayswp OnewaySWP package

Quick Start

01 — Admin Setup

Create an admin instance and generate the key pair.

from onewayswp import Admin

# Create admin instance
admin = Admin()

# Load existing key pair.
# If it does not exist yet, it will be generated automatically.
admin.load_keys(auto_generate=True)

# Display keys
print("Secret:", admin.secret_key)
print("Public:", admin.public_key)

Recommended: Always use load_keys(auto_generate=True) on the admin side.

Manual key generation via generate_keys() should only be used when you intentionally want to replace the existing key pair. Replacing the key pair will invalidate all previously issued licenses.

Important: The secret key is used to sign licenses and must remain private. The public key is distributed to client applications for verification.


02 — Create a License

Load the existing keys and create a license.

from onewayswp import Admin

admin = Admin()

# Load existing keys
admin.load_keys(auto_generate=True)

# Create a license
result = admin.create_license(
    type="date",
    expires="2027-12-31",
    additional_data={
        "client_name": "username123"
    }
)

print(result["token"])

03 — Client Verification

The client application only needs the public key.

from onewayswp import Client

# Create client instance
client = Client("data/license.swpb")

# Load public key
client.open_key("~/.owswp/public.key")

# Check whether a license is already active
if not client.is_active():

    token = input("Enter key: ")

    # Validate license
    result = client.validate_key(token)

    if not result["status"]:
        print(result["message"])
        exit(1)

# Verify protection state
protection = client.protection_verify()

if protection["status"]:
    print("Application running...")
else:
    print(protection["message"])

Basic Flow

┌─────────────────────┐
│        ADMIN        │
├─────────────────────┤
│ Load Key Pair   │
│         ↓           │
│ Create License      │
│         ↓           │
│ Distribute Token    │
└──────────┬──────────┘
           │
           ▼
┌─────────────────────┐
│       CLIENT        │
├─────────────────────┤
│ Public Key          │
│         ↓           │
│ Validate Token      │
│         ↓           │
│ Verify Local State  │
└─────────────────────┘

License Types

OnewaySWP provides three license modes.

Date License

A license that expires on a specific date.

result = admin.create_license(
    type="date",
    expires="2027-12-31"
)
Parameter Description
type "date"
expires Expiration date in YYYY-MM-DD format

Returns information such as:

  • token
  • type
  • expired
  • expires_at

Credit License

A license containing a credit balance that decreases when used.

result = admin.create_license(
    type="credit",
    credits=100
)
Parameter Description
type "credit"
credits Initial credit amount

Returns information such as:

  • token
  • type
  • credit_value

Duration License

A license valid for a fixed amount of active usage time.

result = admin.create_license(
    type="duration",
    hours=2
)
Parameter Description
type "duration"
hours Duration in hours
duration_seconds Alternative duration in seconds

Returns information such as:

  • token
  • type
  • duration_hours

API Reference

Admin

Method Parameters Returns Description
__init__ key_dir: str = None Admin Create admin instance
keys_exist key_dir: str = None bool Check if key files exist
generate_keys auto_save: bool = True, file_path: str = None tuple Generate key pair
save_keys target_dir: str = None None Save keys to disk
load_keys key_dir: str = None, validate: bool = True, auto_generate: bool = False tuple Load keys
set_keys secret_key: str, public_key: str, validate: bool = True None Set keys manually
validate_keys none bool Verify key pair
create_license type, expires, credits, duration_seconds, hours, additional_data dict Create license token
regenerate_keys key_dir: str = None tuple Generate new key pair
platform none dict Get OS and architecture
version none str Get library version

Client

Method Parameters Returns Description
__init__ data_path: str = None, extra_paths: List[str] = None Client Create client instance
open_key path: str None Load public key
set_public_key key: str None Set public key
is_active none bool Check active license
validate_key token: str dict Validate license
inspect_key token: str dict Inspect token without activation
protection_verify none dict Verify local protection state
use_credit amount: int = 1 dict Decrement credits
session none context Duration session context
export_state none dict Export license state
import_state data: dict or str dict Import license state
status none dict Get last status
state_path none str Get state file path
reset none None Delete local state
version none str Get library version

Info Object

The info object provides library information and supports both attribute-style and dictionary-style access.

Method Description
__getattr__ Access field as attribute
__getitem__ Access field by key
__contains__ Check whether field exists
__iter__ Iterate over field names
keys() Get field names
values() Get field values
items() Get field/value pairs
get() Get field with default
to_dict() Convert to dictionary

Response Format

Validation and operation methods use a consistent dictionary-based response format.

Success

{
    "status": True,
    "code": "SUCCESS",
    "message": "License valid and activated",
    "type": "credit",
    "credit_value": 100,
    "remaining_credits": 100,
    "created_at": "2026-10-03 12:00:00",
    "last_time": "2026-10-03 12:05:00",
    "additional_data": {
        "hardware_id": "1234567890"
    }
}

Failure

{
    "status": False,
    "code": "EXPIRED",
    "message": "Token expired"
}

Failure responses contain:

status
code
message

Data Dictionary

Common Fields

Field Type Description
status bool True when operation succeeds
code str Status or error code
message str Human-readable message
type str date, credit, or duration

Date License

Field Type Description
expired str Expiration date
expires_at int Unix expiration timestamp
remaining_days int Remaining days

Credit License

Field Type Description
credit_value int Initial credit
remaining_credits int Remaining credit
used int Credit used in last operation

Duration License

Field Type Description
duration_hours float Total duration
duration_seconds int Total duration in seconds
remaining_hours float Remaining duration
remaining_seconds int Remaining seconds
elapsed_seconds int Elapsed session time
started_at str Session start
stopped_at str Session stop

Session

Field Type Description
created_at str License creation timestamp
last_time str Last verification timestamp

Error Codes

Code Description
SUCCESS Operation completed successfully
INVALID_SIGNATURE Token signature is invalid
INVALID_MAGIC File format is invalid
INVALID_KEY_FORMAT Key format is invalid
UNSUPPORTED_VERSION File version is not supported
KEY_MISMATCH Key pair does not match
SECURITY_ERROR Security violation detected
EXPIRED Token has expired
CLOCK_ROLLBACK_DETECTED System clock rollback detected
CORRUPTED_FILE File is corrupted
INSUFFICIENT_CREDITS Credit balance is insufficient
FILE_LOCKED File is locked by another process
IO_ERROR Input/output error
CRYPTO_ERROR Cryptographic error
SERIALIZATION_ERROR Serialization error
FFI_ERROR Foreign function interface error
NO_STATE_FILE State file does not exist

Examples

Generate Keys

from onewayswp import Admin

admin = Admin(key_dir="./keys")

secret, public = admin.generate_keys(
    auto_save=True
)

print("Secret Key:", secret)
print("Public Key:", public)

Load Existing Keys

from onewayswp import Admin

admin = Admin()

secret, public = admin.load_keys(
    validate=True,
    auto_generate=True
)

print("Keys loaded successfully")

Load Keys with Auto-Generate

from onewayswp import Admin

admin = Admin()

secret, public = admin.load_keys(
    auto_generate=True
)

print("Keys ready")
print("Public:", public)

Create Date License

from onewayswp import Admin

admin = Admin()
admin.load_keys()

result = admin.create_license(
    type="date",
    expires="2027-12-31",
    additional_data={
        "client_name": "user12345",
        "plan": "pro"
    }
)

token = result["token"]

print("Token:", token)
print("Expires:", result["expired"])
print("Expires at:", result["expires_at"])

Create Credit License

from onewayswp import Admin

admin = Admin()
admin.load_keys()

result = admin.create_license(
    type="credit",
    credits=100,
    additional_data={
        "client_name": "user12345"
    }
)

print("Token:", result["token"])
print("Credits:", result["credit_value"])

Create Duration License

from onewayswp import Admin

admin = Admin()
admin.load_keys()

result = admin.create_license(
    type="duration",
    hours=2,
    additional_data={
        "client_name": "user12345"
    }
)

print("Token:", result["token"])
print("Duration:", result["duration_hours"], "hours")

Alternative using seconds:

result = admin.create_license(
    type="duration",
    duration_seconds=3600
)

print(
    "Duration:",
    result["duration_hours"],
    "hours"
)

Set Keys Manually

from onewayswp import Admin

admin = Admin()

admin.set_keys(
    secret_key="OWSWP-sec-...",
    public_key="OWSWP-pub-...",
    validate=True
)

print("Keys set")

Regenerate Keys

from onewayswp import Admin

admin = Admin()
admin.load_keys()

new_secret, new_public = admin.regenerate_keys()

print("New secret:", new_secret)
print("New public:", new_public)

Regenerating the key pair will cause previously issued tokens to become invalid.


Platform Information

from onewayswp import Admin

admin = Admin()

info = admin.platform()

print("OS:", info["os"])
print("Arch:", info["arch"])

Client Validation

from onewayswp import Client

client = Client(
    "data/license.swpb"
)

client.set_public_key(
    "OWSWP-pub-..."
)

if client.is_active():

    print("License already active")

else:

    token = input("Enter key: ")

    result = client.validate_key(token)

    if result["status"]:

        print("License activated")
        print("Type:", result["type"])

    else:

        print("Failed:", result["message"])

Use Credits

from onewayswp import Client

client = Client(
    "data/license.swpb"
)

client.open_key(
    "~/.owswp/public.key"
)

result = client.validate_key(
    "OWSWP-..."
)

if not result["status"]:
    print("Invalid license")
    exit(1)

result = client.use_credit(5)

if result["status"]:

    print("Used 5 credits")
    print(
        "Remaining:",
        result["remaining_credits"]
    )

else:

    print("Failed:", result["message"])

Duration Session

Duration licenses can measure usage during an active session.

from onewayswp import Client
import time

client = Client(
    "data/license.swpb"
)

client.open_key(
    "~/.owswp/public.key"
)

result = client.validate_key(
    "OWSWP-..."
)

if not result["status"]:
    print("Invalid license")
    exit(1)

with client.session():

    print("Application running...")

    time.sleep(10)

protection = client.protection_verify()

print(
    "Remaining:",
    protection["remaining_hours"],
    "hours"
)

Inspect License Without Activating

from onewayswp import Client

client = Client(
    "data/license.swpb"
)

client.set_public_key(
    "OWSWP-pub-..."
)

result = client.inspect_key(
    "OWSWP-..."
)

if result["status"]:

    print("Type:", result["type"])
    print("Is expired:", result["is_expired"])

    if result["type"] == "date":

        print(
            "Expires:",
            result["expired"]
        )

        print(
            "Remaining days:",
            result["remaining_days"]
        )

    elif result["type"] == "credit":

        print(
            "Credits:",
            result["credit_value"]
        )

    elif result["type"] == "duration":

        print(
            "Duration hours:",
            result["duration_hours"]
        )

Export & Import State

Export state:

from onewayswp import Client

client1 = Client(
    "data/license1.swpb"
)

client1.open_key(
    "~/.owswp/public.key"
)

exported = client1.export_state()

print(
    "Exported data:",
    exported["data"][:50],
    "..."
)

print(
    "Public key:",
    exported["public_key"]
)

Import state:

client2 = Client(
    "data/license2.swpb"
)

client2.set_public_key(
    exported["public_key"]
)

result = client2.import_state(
    exported
)

if result["status"]:

    print(
        "State imported successfully"
    )

Reset Client State

from onewayswp import Client

client = Client(
    "data/license.swpb"
)

client.set_public_key(
    "OWSWP-pub-..."
)

client.reset()

print("State reset")

After resetting, the next validation will require a new token.


Library Information

from onewayswp import info

print(info)

print("Author:", info.author)
print("Version:", info.oneway_version)
print("GitHub:", info.swp_github)

Dictionary-style access:

print("Author:", info["author"])

Convert to dictionary:

data = info.to_dict()

for key, value in data.items():
    print(f"{key}: {value}")

Error Handling

from onewayswp import (
    Client,
    OnewaySWPError,
    InvalidTokenError,
    ExpiredError,
    SecurityError,
)

client = Client(
    "data/license.swbp"
)

client.set_public_key(
    "OWSWP-pub-..."
)

try:

    result = client.validate_key(
        "OWSWP-..."
    )

    if not result["status"]:

        code = result["code"]
        message = result["message"]

        print(
            f"Error [{code}]: {message}"
        )

except InvalidTokenError as e:

    print(
        f"Invalid token: {e}"
    )

except ExpiredError as e:

    print(
        f"Token expired: {e}"
    )

except SecurityError as e:

    print(
        f"Security error: {e}"
    )

except OnewaySWPError as e:

    print(
        f"Error: {e}"
    )

Security Notes

OnewaySWP is designed to help developers create one-way license verification systems for applications that cannot rely on a server.

It is a licensing framework, not a replacement for application-level security.

The library applies internal cryptographic protection to help preserve license integrity, protect local license state, and detect unauthorized modification.

However, the overall security of an application still depends on how the framework is integrated by the developer.

Any bypass, modification, or direct interaction with the application code is outside the scope of this library.

Keep Your Secret Key Private

The secret key is used to sign licenses.

Never distribute it with client applications.

If the secret key is exposed, another party may be able to generate valid licenses.

Protect Your Key Pair

Store the secret key and public key safely.

Losing the key pair may prevent future licenses from being verified against previously issued tokens.

Public Key Distribution

Client applications only require the public key to validate licenses.

The secret key should remain on the administrative side.

Protect Local State

Treat the .swpb state file as protected application data.

Manual modification may invalidate the license state.

Integration Matters

OnewaySWP is a tool.

The way it is integrated into an application determines how effectively it contributes to the application's licensing protection.


Compatibility

OnewaySWP is designed for cross-platform usage:

Windows
Linux
macOS
Android

Platform and architecture information can be detected automatically:

from onewayswp import Admin

admin = Admin()

info = admin.platform()

print(info["os"])
print(info["arch"])

Project Information

Project OnewaySWP
Description Offline One-Way License Framework
Version 0.1.0
Author Juan Hulu
Organization SilentWolfProject
License MIT

Links


ONEWAYSWP

Offline licensing without the server.

Built by SilentWolfProject

v0.1.0 · MIT License

Metadata

Release files for onewayswp 0.1.0.post1

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

Source distribution (sdist)

Source distribution for onewayswp 0.1.0.post1
File Size Uploaded
onewayswp-0.1.0.post1.tar.gz 4.2 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for onewayswp 0.1.0.post1
File Interpreter ABI Platform
onewayswp-0.1.0.post1-py3-none-any.whl Python 3 none any Details

Total release size: 8.4 MB

Release files / onewayswp-0.1.0.post1.tar.gz

Download URL onewayswp-0.1.0.post1.tar.gz
Size 4.2 MB
Tags Source
SHA-256 checksum
How to use checksums
632188d44d4b3e03d4098c5b37a6429a2b776a5d267be4076506273b31eb9785
BLAKE2b-256 checksum
How to use checksums
928f561aa5a032720237c6f87c38a77d86244fc7cb2123bcb6fe847ace5cd4ab
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.10.8

Release files / onewayswp-0.1.0.post1-py3-none-any.whl

Download URL onewayswp-0.1.0.post1-py3-none-any.whl
Size 4.2 MB
Tags Python 3
SHA-256 checksum
How to use checksums
e56aa66b2a07f9a6ae6d0fa69b485dce9bfae8226b8c6f2ad2fda642af315a1f
BLAKE2b-256 checksum
How to use checksums
ee531229a78823f8aa67cb7eed21fa4965799829a8861aa7efe03d158d12e4be
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.10.8

Release history Release notifications | RSS feed

This release

0.1.0.post1 This release

2 release files

0.1.0

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