Skip to main content

SitrTech — Source Code Encryption & Licensing for Python & PHP

PyPI CLI Runtime Frameworks Platforms

Encrypt and license-lock your Python or PHP project, then ship it as code that runs at native speed — while your source stays unreadable, license-bound, and optionally locked to a machine, network, or time window. One command, in your CI or on your laptop.

Nine frameworks, one tool — Odoo · Frappe · Django · Flask · FastAPI · Tornado · WordPress · Laravel · plain PHP.

pipx install sitrtech        # recommended for CLI tools
sitr encrypt my_module.zip --framework odoo --secret sk-...   # Python
sitr encrypt ./my-plugin    --framework wordpress --secret sk-...  # PHP

Why SitrTech

  • Real encryption, not obfuscation. Each Python .py becomes a .pye (and each PHP file its encrypted counterpart) sealed with AES-256-GCM under a per-file key. There is no de-obfuscator to reverse — without the key, the bytes are ciphertext.
  • Python and PHP. One CLI protects 6 Python frameworks and 3 PHP stacks (WordPress, Laravel, plain PHP) — each with a matching native runtime loader.
  • A compiled native loader does the unwrapping. Decryption keys live only inside a compiled C extension, never in readable Python. The master secret is never present in this package or on your machine.
  • Zero runtime tax. Modules are decrypted once at import time, then execute as normal CPython bytecode. No per-call overhead.
  • License binding built in. Lock code to an expiry date, start date, IP/CIDR, MAC, machine ID, hostname, disk serial, Odoo database, or domain — combinable with AND logic, enforced at import.
  • Local mode. Encrypt entirely on your own machine: your source is never uploaded. Only signed, tamper-proof line counts are exchanged for metering.
  • Built for CI. Incremental, parallel batch encryption of hundreds of modules, plus an offline mode for air-gapped or maintenance windows.

Supported frameworks

Pass the framework with -f/--framework. SitrTech detects the project by its entry-point file and applies the right runtime loader.

Python — encrypted to .pye, decrypted by a compiled C-extension loader:

Framework --framework Detected by
Odoo odoo __manifest__.py
Frappe / ERPNext frappe hooks.py
Django django manage.py
Flask flask app.py / wsgi.py / application.py
FastAPI fastapi main.py / asgi.py
Tornado tornado main.py / server.py

PHP — encrypted and served through the SitrTech PHP loader:

Framework --framework Detected by
WordPress (plugins & themes) wordpress wp-config.php / style.css
Laravel laravel artisan / composer.json
Any PHP app php index.php / composer.json

Don't see your stack? Plain python-style projects and generic php are covered by the catch-all loaders — talk to us about anything else.


Installation

# pipx — best for CLI tools; isolated, works on Ubuntu/Debian/macOS without conflicts
pipx install sitrtech
pipx upgrade sitrtech

# pip — standard package manager
pip install sitrtech            # latest stable
pip install --upgrade sitrtech
pip install "sitrtech==1.3.2"   # pin a version

Ubuntu / Debian: if you hit externally-managed-environment, use pipx install sitrtech.

Compatibility

Component Supported
CLI (this package) Python 3.8 – 3.14 · Linux, macOS, Windows
Encrypted runtime (where your protected app runs) Python 3.7 – 3.14 · Linux (manylinux/musllinux, x86-64 & aarch64), macOS (Intel & Apple Silicon), Windows (x64/x86)

The right native loader for the deployment machine is selected automatically — no manual setup on your servers.


Quick start

Get an API secret key from sitrtech.com/api-keys, then export it once:

export SITR_SECRET=sk-your-key-here
# Encrypt an Odoo addon
sitr encrypt hr_module.zip --framework odoo

# Encrypt a Django project, expiring end of 2026, limited to one network
sitr encrypt backend.zip -f django --expiry 2026-12-31 --network 10.0.0.0/24

# Encrypt on your own machine — source never leaves it
sitr encrypt api.zip -f fastapi --local

# Encrypt a WordPress plugin or a Laravel app (PHP — pass a directory)
sitr encrypt ./wp-content/plugins/my-plugin -f wordpress
sitr encrypt ./my-laravel-app -f laravel

# Check your token balance
sitr balance

Commands

Command Purpose
sitr encrypt <PATH> Encrypt one project — a Python .zip or a PHP directory
sitr encrypt-dir <DIR> Encrypt many modules — incremental, parallel
sitr offline fetch | sync | status Work without live platform access
sitr balance Show tokens, plan, and per-line rate
sitr info List frameworks and required project layout
sitr version Print the CLI version

Run sitr <command> --help for full options.

sitr encrypt

sitr encrypt <PATH> [OPTIONS]     # PATH = Python project .zip, or a PHP directory

  -f, --framework TEXT   odoo | frappe | django | flask | fastapi | tornado
                         | wordpress | laravel | php                 [default: odoo]
  -v, --version TEXT     Framework version (e.g. 17.0 for Odoo)
  -o, --output PATH      Output file  [default: <input>_encrypted.zip]
      --local            Encrypt locally — source is never uploaded
  -s, --secret TEXT      API secret key            [env: SITR_SECRET]
  -b, --base URL         Override API base URL      [env: SITR_BASE]

  Binding (all optional, combinable):
  -e, --expiry DATE       stop working after this date/time
      --start DATE        not valid before this date/time
  -n, --network CIDR      allowed IP / CIDR / range        (repeatable)
      --mac MAC           allowed MAC address              (repeatable)
      --machine-id ID     machine fingerprint              (repeatable)
      --hostname HOST     allowed hostname                 (repeatable)
      --disk-serial SN    allowed disk / volume serial     (repeatable)
      --odoo-db DB        allowed Odoo database name       (repeatable)
      --domain DOMAIN     allowed domain / base URL        (repeatable)

sitr encrypt-dir — batch, incremental, parallel

Built for teams shipping dozens of modules across many projects, daily. No manual zipping; source never leaves your machine; only changed modules are re-encrypted each run (state tracked in <output>/.sitr_state.json).

# Encrypt every Odoo module under ./addons — locally, in parallel, incrementally
sitr encrypt-dir ./addons --framework odoo

# With binding + expiry, into a custom output directory
sitr encrypt-dir ./addons -f odoo -o ./dist \
  --expiry 2026-12-31 --network 10.0.0.0/24 --mac 00:1a:2b:3c:4d:5e

sitr encrypt-dir ./addons --full        # force a full re-encryption
Option Meaning
-o, --output DIR output directory (default <source>_encrypted)
-j, --jobs N parallel workers (default: CPU count)
--full ignore incremental state; re-encrypt everything
all binding flags --expiry --start --network --mac --machine-id --hostname --disk-serial --odoo-db --domain

Local mode — your source never leaves your machine

Add --local to encrypt entirely on your own hardware. Your code is read, encrypted, and written on the spot; the platform only ever sees what it needs to meter usage.

sitr encrypt my_addon.zip --framework odoo --local

How it stays honest without seeing your code

  1. Authorize — the CLI reserves tokens and receives a signed, one-time job key.
  2. Encrypt locally — every file is sealed with AES-256-GCM using that key.
  3. Attest & commit — the compiled loader (the only local component that can) signs a proof of the actual line count over the encrypted output. The platform verifies that signature before charging, so counts can be neither over- nor under-reported.

No valid authorization ⇒ nothing is encrypted. The master secret is never on your machine.


Binding & protection

Lock encrypted code to a place, machine, or time window. Rules combine with AND — every rule present must pass at import time. Works in both normal and --local modes.

Option Binds the code to…
-e, --expiry DATE stops working after this date/time
--start DATE not valid before this date/time
-n, --network CIDR allowed IPs / CIDR / ranges
--mac MAC allowed MAC address(es)
--machine-id ID machine fingerprint (Linux machine-id / Windows MachineGuid)
--hostname HOST allowed hostname(s)
--disk-serial SN allowed disk / volume serial(s)
--odoo-db DB allowed Odoo database name(s)
--domain DOMAIN allowed domain / base URL(s)
# Bind to one machine + network, expiring end of 2026
sitr encrypt hr_module.zip -f odoo --local \
  --expiry 2026-12-31 \
  --network 10.0.0.0/24 \
  --mac 00:1a:2b:3c:4d:5e \
  --machine-id "$(cat /etc/machine-id)"

PHP projects support the time and location rules — --expiry, --start, --network, and --domain. Hardware bindings (MAC, machine ID, disk serial) are Python-runtime features.


Offline mode

Pre-authorize work so encryption keeps running when the platform is unreachable (maintenance, air-gapped build hosts). Quota is reserved up front and reconciled later.

sitr offline fetch --quota 200000 --days 14   # pre-authorize while online
sitr encrypt-dir ./addons -f odoo             # ...later, encrypt with no connectivity
sitr offline sync                             # reconcile real usage once back online
sitr offline status                           # show the cached grant and remaining quota

Packaging your project

Each framework is detected by its entry-point file (see Supported frameworks). What you pass to sitr encrypt depends on the language:

Python — pass a zip of the root folder (or use sitr encrypt-dir for a tree of modules). Always zip the folder, not its contents:

# Correct ✓                          # Wrong ✗
zip -r my_addon.zip my_addon/        cd my_addon && zip -r ../my_addon.zip .

PHP — pass the project directory directly; no zipping needed:

sitr encrypt ./my-plugin -f wordpress

Bootstrap/config files a framework reads directly (e.g. manage.py, wp-config.php, artisan, composer.json) are intentionally kept in plaintext so the app still starts; everything else is encrypted.


CI/CD

GitHub Actions — daily encryption of all modules

name: Encrypt & deploy addons
on:
  schedule: [{ cron: "0 2 * * *" }]   # daily at 02:00
  workflow_dispatch:
jobs:
  encrypt:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with: { python-version: "3.12" }
      # cache incremental state so only changed modules re-encrypt
      - uses: actions/cache@v4
        with: { path: dist/.sitr_state.json, key: sitr-state-${{ github.ref }} }
      - run: pipx install sitrtech
      - name: Encrypt all modules (source never leaves the runner)
        env: { SITR_SECRET: ${{ secrets.SITR_SECRET }} }
        run: sitr encrypt-dir ./addons -f odoo -o ./dist --expiry 2026-12-31
      - name: Deploy encrypted modules
        run: rsync -az ./dist/ user@server:/opt/odoo/addons/

GitLab CI

encrypt:
  image: python:3.12
  cache: { paths: [dist/.sitr_state.json] }
  variables: { SITR_SECRET: $SITR_SECRET }
  script:
    - pip install sitrtech
    - sitr encrypt-dir ./addons -f odoo -o ./dist

Docker one-liner

docker run --rm -e SITR_SECRET -v "$PWD/addons:/src:ro" -v "$PWD/dist:/out" \
  python:3.12-slim sh -c "pip install -q sitrtech && sitr encrypt-dir /src -f odoo -o /out"

Environment variables

Variable Description
SITR_SECRET API secret key (so you don't pass --secret each time)
SITR_BASE Override the API base URL (default: https://sitrtech.com)

How it works

  1. Per-file sealing. Each source file is encrypted with a fresh AES-256-GCM key; that file key is itself wrapped under a one-time, per-job key.
  2. Native loader. A compiled C extension is placed alongside your code. At import it unwraps the job key and decrypts modules in memory — key material never exists as readable source, and the platform master secret is never distributed.
  3. License gate. If you set any binding, the loader validates every rule (expiry, start, network, MAC, machine ID, hostname, disk serial, Odoo DB, domain) before a module runs.
  4. Metered fairly. Billing is per line of code. In local mode the loader cryptographically attests the real line count, so metering is trustworthy without the platform ever seeing your source.

Links

© SitrTech. Proprietary. All rights reserved.

Download files

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

Source Distribution

sitrtech-1.4.0.tar.gz (38.4 kB view details)

Uploaded Source

Built Distribution

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

sitrtech-1.4.0-py3-none-any.whl (35.5 kB view details)

Uploaded Python 3

File details

Details for the file sitrtech-1.4.0.tar.gz.

File metadata

  • Download URL: sitrtech-1.4.0.tar.gz
  • Upload date:
  • Size: 38.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for sitrtech-1.4.0.tar.gz
Algorithm Hash digest
SHA256 739579a5b1e5b9f1be2f4abe2c08a64462c2f36a99a93c24668e28bd0602d9dc
MD5 129458060fb425beed2c1bd2f7d7f133
BLAKE2b-256 e611d19f6fc11184053345ef2370181015378f7fa62992be05353a7617f6486e

See more details on using hashes here.

File details

Details for the file sitrtech-1.4.0-py3-none-any.whl.

File metadata

  • Download URL: sitrtech-1.4.0-py3-none-any.whl
  • Upload date:
  • Size: 35.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for sitrtech-1.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c9e690b92dfcc47c5db301e221932ed8feccb2b8ad1964a25df2a91b2c5576bd
MD5 7211def307f32869851db1d45fb3253d
BLAKE2b-256 f10663cae760ee1f6fa347353036b73383ec8b5508e40387e3bba05809326ed9

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

1.4.0 This release

2 files

1.3.2

2 files

1.3.1

2 files

1.3.0

2 files

1.2.5

2 files

1.2.4

2 files

1.2.3

2 files

1.2.0

2 files

1.0.2

2 files

1.0.1

2 files

1.0.0

2 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