コードの暗号化

protect と run、有効期限、そして 5 つの保護レベル — 自由に配布できる鍵なし成果物から、マシンロック付き二要素の金庫まで。

magiclock protect は、コンパイラを使わず、ソースコードをどこにもアップロードすることなく、.py ファイルを .pya — 暗号化されゲートで保護されたコンテナ — に変換します。magiclock run はそれを実行します。

基本的な使い方

shell
# First run: signs you in and activates this machine, then encrypts.
# Every encrypt after that is instant and non-interactive.
magiclock protect app.py            # -> app.pya
magiclock run app.pya

# Point at a directory to protect a whole project tree recursively
# (.venv/venv/__pycache__/.git/dist/build are skipped automatically).
magiclock protect src/

.pya ファイルは普通のファイルであり、すでに使っている方法でコミット・コピー・出荷できます — 暗号化はファイルと一緒に移動します。デフォルトでは、成果物はポータブルかつ鍵なしです:実行側にアカウントもパスフレーズもマシンロックも要求せず、magiclock がインストールされた任意のマシンで透過的に復号できます。つまりデフォルトは利便性・難読化レベルの保護です — ソースが平文のまま出荷されることはありませんが、ファイルとランタイムを持っていれば誰でも実行できます。本当のアクセス制御が必要な場合は、以下のより強力なレベルを選んでください。

保護レベルの選択

レベルフラグ復号できる相手
鍵なしポータブル (デフォルト)(なし)magiclock をインストールした人なら誰でも — 利便性・難読化相当。
パスフレーズ・ポータブル--passphraseパスフレーズを知っている人なら、どのマシンでも。
キー・ポータブル--emit-key生成されたキーを持っている人なら、どのマシンでも。
マシンロック--bind-machineこの有効化済みマシンのみ — エクスポート不能なマシンキーとライセンスゲートによる、単一要素として最強のレベル。
マシン+パスフレーズ--bind-machine --passphraseこの有効化済みマシンかつパスフレーズ — 二要素。

仕組み

.pya は、暗号化されたエンベロープを包む、小さなバージョン管理付きコンテナです。magiclock run app.pya はそれをメモリ上で復号し、インポートするものすべてに対してインポートフックをインストールしてから実行します — 平文としてディスクに書き戻されることは一切ありません。内部の marshal 化されたバイトコードは、暗号化を行った CPython のバージョンに紐づいているため、Python 3.12 でビルドした .pya は 3.13 では読み込めません。インタプリタをアップグレードした場合は protect を再実行してください。

平文の削除

shell
magiclock protect app.py --remove   # encrypt, then delete app.py

有効期限:時限式・自己消去型の成果物

以下のフラグは、ライセンスとは独立して、暗号化された成果物そのものに有効期限を刻印します。期限を過ぎると復号を拒否するようになります。

shell
magiclock protect app.py --expires-in 30d        # stops decrypting in 30 days
magiclock protect app.py --expires-at 2026-12-31  # stops decrypting on a date
magiclock protect app.py --trial                  # fixed 48-hour self-destruct — for demos and evaluations

--trial--expires-in--expires-at は互いに排他的です — ファイルごとにいずれか 1 つを選んでください。

ポータブル+シークレット:パスフレーズまたはキー

鍵なしのデフォルトは、成果物を実行する側に何も要求しません。ポータブル性を保ったままアクセス用のシークレットを追加するには、2 つのポータブルモードのどちらかを選びます。

shell
# Passphrase-protected, still runs on any machine:
magiclock protect app.py --passphrase
magiclock run app.pya --passphrase

# Or hand out a generated key instead of a passphrase:
magiclock protect app.py --emit-key
magiclock run app.pya --key <the-printed-key>

--passphrase--emit-key は互いに排他的です — 成果物ごとに選べるシークレットは 1 つだけです。

最強:マシンロック(--bind-machine

成果物を自分のマシンから一切持ち出させたくない場合は、この有効化済みマシンに紐づけます — 復号にはこのマシンのエクスポート不能なボールトキーが必要になり、ライセンスゲートの通過も要求されるため、ファイルは他のどこでも役に立ちません。

shell
magiclock protect app.py --bind-machine
magiclock run app.pya            # only works on the machine that encrypted it

さらにパスフレーズを重ねれば二要素ロックになります — 正しいマシンかつシークレットが必要です。

shell
magiclock protect app.py --bind-machine --passphrase
# prompts for a passphrase (or reads $MAGICLOCK_PASSPHRASE non-interactively)

magiclock run app.pya --passphrase

--emit-key はポータブル専用で、--bind-machine とは互いに排他的です — マシンロックされた成果物のキーはマシンの外に出ないため、配れる鍵がそもそも存在しません。

CI やスクリプトからの実行では、プロンプトの代わりに環境変数からパスフレーズやポータブルキーを渡すこともできます。

shell
export MAGICLOCK_PASSPHRASE=...     # for --passphrase artifacts (portable or two-factor)
export MAGICLOCK_DECRYPT_KEY=...    # alternative to `run --key` for --emit-key artifacts
magiclock run app.pya

次に読むべきもの