How it works

Build time on your side, run time on the customer’s.

Build time · vendor

Your app
Source or compiled build output
↓
cryptship pack
Random content key; AES-256-GCM into payload.enc
↓
cryptship issue
Ed25519-signed license that wraps the content key
↓
Container image
Loader + payload.enc + license + public key

Run time · customer

Loader starts
Verifies the license signature, expiry and revocation
↓
Key provider
offline · online license server · attested hardware
↓
Decrypt to tmpfs
Wrong license or machine means the AEAD tag fails
↓
exec your app
Runs with the license ID and customer as a watermark

The key idea

There is no “is the license valid?” check to patch out. The decryption key is derived from the license itself.

no "is valid?" boolean to patch
# the key is derived from the license, so a valid license and a successful decrypt are the same event
content_key = unwrap(license.wrapped_key, KEK = derive(machine_fingerprint, license_id))
plaintext   = aead_open(payload.enc, content_key)   # wrong key => AEAD tag fails

Deployment modes

Air-gapped, on-prem and cloud differ only in how the content key is obtained.

ModeProviderBindingRevocation
Air-gappedofflineMachine fingerprint, or noneExpiry only
On-prem / cloudonlinePer-license secret held by your serverReal: the server declines
ConfidentialattestedSEV-SNP / TDX attestation gates the keyReal, plus anti-tamper

Hardening

Compile before sealing
pack --transform-cmd runs your toolchain first, so a memory dump yields bytecode, not source
Runtime hardening
Non-dumpable loader, seccomp profile, non-root, dropped capabilities, read-only root and tmpfs
Per-license watermark
Each instance carries its license ID and customer, so a leak traces back to its licensee
Key rotation and revocation
Signing-key ring, and open, closed or grace revocation policies
Honest threat model
Code that runs on hardware the customer controls can never be fully extraction-proof. cryptship raises the bar: it makes casual copying impossible and serious reverse engineering cost more than a license. Against root on the host, only the confidential-compute (attested) path, or keeping critical logic server-side, prevents extraction.

Try the demo

Needs only Docker. The demo packs a small Python app, proves no layer contains the source, runs it, then tampers with the license to show the loader refuse.

cryptship
$ git clone https://github.com/AI2TH/cryptship && cd cryptship
$ bash scripts/demo.sh
  1. v0.1.0First release: offline, online and attested key providers, license server, hardening, demos