코드 암호화

protect와 run, 유효 기간, 그리고 다섯 가지 보호 수준 — 자유롭게 배포할 수 있는 키 없는 산출물부터 머신 잠금 2단계 볼트까지.

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활성화된 이 머신 그리고 패스프레이즈 — 2단계.

동작 원리

.pya는 암호화된 봉투를 감싼 작은 버전 관리형 컨테이너입니다. magiclock run app.pya는 이를 메모리에서 복호화하고, 그 안에서 import되는 모든 것에 대해 import 훅을 설치한 뒤 실행합니다 — 평문이 디스크에 다시 기록되는 일은 결코 없습니다. 내부의 마셜링된 바이트코드는 암호화에 사용된 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는 서로 배타적입니다 — 파일마다 하나만 선택하세요.

비밀 값이 있는 포터블: 패스프레이즈 또는 키

키 없는 기본값은 산출물을 실행하는 사람에게 아무것도 요구하지 않습니다. 포터블함은 유지하면서 접근용 비밀 값을 추가하려면, 두 가지 포터블 모드 중 하나를 선택하세요.

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는 서로 배타적입니다 — 산출물마다 비밀 값 하나만 선택하세요.

가장 강력하게: 머신 잠금(--bind-machine)

산출물이 결코 여러분의 머신을 벗어나서는 안 될 때는 활성화된 이 머신에 바인딩하세요 — 그러면 복호화에 이 머신의 내보낼 수 없는 볼트 키가 필요하고 라이선스 게이트를 통과해야 하며, 그 파일은 다른 어디에서도 쓸모가 없습니다.

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

여기에 패스프레이즈를 더하면 2단계 잠금이 됩니다 — 올바른 머신 그리고 비밀 값이 모두 필요합니다.

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

다음으로 볼 문서

  • 모델 및 리소스 암호화에서는 코드가 아닌 자산에도 동일한 유효 기간 및 보호 수준 옵션을 적용합니다.
  • 계정 및 활성화에서는 오프라인 상태일 때나 기기가 취소되었을 때 어떤 일이 벌어지는지 다룹니다.
  • CLI 레퍼런스에는 protectrun의 모든 플래그가 한곳에 정리되어 있습니다.