How krishnansg/codeenigma works
1. What this repo is
CodeEnigma is a Python source-obfuscation tool. Its architecture is a build-time pipeline: it takes a Python package/module as input, transforms the code into encrypted payloads, and emits a distributable package that depends on a compiled runtime to decrypt and execute the protected code.
2. Primary entrypoints
The user-facing surface is the CLI in codeenigma/cli.py. That CLI feeds into codeenigma/orchestrator.py, which appears to coordinate the full obfuscation flow. The CLI is the only direct interactive boundary; everything else is internal build machinery.
3. Core orchestration flow
The orchestration layer ties together four phases:
- inspect and bundle the target module,
- transform each source file into an obfuscated payload,
- generate runtime/loading code,
- compile the runtime into a native Python extension via Cython.
This makes the architecture a source-to-artifact pipeline rather than a long-running application.
4. Bundling subsystem
codeenigma/bundler/ contains the logic for collecting source files from a project layout. The presence of standard.py and poetry.py suggests two supported project shapes: a generic Python package layout and Poetry-managed projects. This subsystem is responsible for discovering the module boundary and preparing files for transformation.
5. Obfuscation strategy layer
codeenigma/strategies/ defines how code is transformed. The concrete implementation in encryption.py matches the README pipeline: compile Python source to bytecode, compress it, encode it, and encrypt it. The base.py module likely defines the abstraction that lets orchestration swap or extend transformation strategies.
6. Encryption runtime contract
The obfuscated payload is useless without the companion runtime. codeenigma/strategies/encryption_runtime.py.template and codeenigma/executor.py.template indicate that CodeEnigma generates a loader/executor that knows how to decrypt payloads and execute them at import/runtime. This is a clear boundary: build-time encryption lives in Python code, while execution-time decryption is embedded into generated runtime code.
7. Compiled runtime subsystem
codeenigma/runtime/ is the runtime generation and build layer. The cython/ subpackage contains templates for init.py, setup.py, and pyproject.toml, plus a builder.py, indicating the project compiles the runtime into a Cython extension module. This compiled boundary is important: the protected app ships with a native extension that performs decryption/loading logic instead of plain Python source.
8. Extensions subsystem
codeenigma/extensions/ adds optional cross-cutting features to the obfuscation output. The concrete expiry.py module and its expiry_code.py.template show that the repository supports injecting expiration behavior into the generated runtime, so protected code can be made time-limited. This is an augmentation layer rather than the main encryption mechanism.
9. Secret material and generated state
codeenigma/private.py is the likely home for generated secret key material or runtime constants used during obfuscation. The README explicitly says an AES-256 key is generated and set in private.py, so this file is part of the internal trust boundary and should not be treated as regular source code in the final distribution.
10. Templates as code-generation assets
Several .template files are central to the architecture: they are used to stamp out the runtime loader, Cython packaging files, and expiry logic. This indicates CodeEnigma is a code generator as much as an obfuscator; it synthesizes a new package structure around the protected payload rather than mutating the original project in place.
11. Test and fixture architecture
tests/example_module/ is a representative sample project used to validate end-to-end behavior. tests/test_e2e.py likely exercises the full pipeline from input module to generated artifact, while tests/test_version.py covers package metadata/versioning. The tests reinforce that the repo’s main contract is “input project in, obfuscated distributable out.”
12. External dependencies that shape the design
The architecture depends on cryptography for AES-GCM encryption and Cython for building the runtime extension. Poetry support is also first-class, both for project detection and packaging. These tools are not incidental; they define the artifact boundary and the way the obfuscated output is packaged for distribution.
13. Resulting system boundary
From an architecture-diagram perspective, CodeEnigma sits between a Python source tree and a compiled distributable wheel/package. The input side is plain Python modules; the output side is an obfuscated package plus a native runtime extension. The critical internal flow is: discover files → transform and encrypt → generate runtime templates → compile runtime → emit distribution artifacts.
Main entry points: orchestrator.py Orchestrator · builder.py Cython builder · base.py Bundle API · encryption.py Encryption
Components 19
Entry
User-facing command entrypoint and orchestration boundary.
- CLI · User-facing interface for invoking obfuscation runs.
codeenigma/cli.py - Orchestrator · Coordinates the full build-time obfuscation flow.
codeenigma/orchestrator.py
Bundling
Project discovery and source collection for supported layouts.
- Bundle API · Shared interface for project discovery and file collection.
codeenigma/bundler/base.py - Standard bundler · Handles generic Python package/module layouts.
codeenigma/bundler/standard.py - Poetry bundler · Handles Poetry-managed project layouts.
codeenigma/bundler/poetry.py
Transform
Code obfuscation and payload generation pipeline.
- Strategy API · Defines the interface for source transformation strategies.
codeenigma/strategies/base.py - Encryption · Compiles, compresses, encodes, and encrypts Python source into payloads.
codeenigma/strategies/encryption.py - Runtime tpl · Template for generating the decrypt-and-execute runtime contract.
codeenigma/strategies/encryption_runtime.py.template - Private state · Generated keys and internal constants used during obfuscation.
codeenigma/private.py
Runtime
Generated loader and compiled execution runtime.
- Runtime API · Shared runtime generation and build interface.
codeenigma/runtime/base.py - Cython builder · Builds the runtime extension from generated sources and templates.
codeenigma/runtime/cython/builder.py - Init tpl · Template for the runtime package initializer.
codeenigma/runtime/cython/init.py.template - Setup tpl · Template for the Cython packaging setup file.
codeenigma/runtime/cython/setup.py.template - Pyproject tpl · Template for the Cython build configuration.
codeenigma/runtime/cython/pyproject.toml.template - Executor tpl · Template for the generated executor that runs protected code.
codeenigma/executor.py.template
Extensions
Optional cross-cutting features injected into generated output.
- Expiry · Injects time-limited behavior into the generated runtime.
codeenigma/extensions/expiry.py - Expiry tpl · Template for generating expiry enforcement code.
codeenigma/extensions/expiry_code.py.template
Tests
End-to-end validation and sample input project.
- Sample app · Representative target project used for end-to-end validation.
tests/example_module - E2E test · Exercises the full obfuscation pipeline on the sample project.
tests/test_e2e.py
Connections 19
- CLI → Orchestrator: invokes · CLI hands control to the build pipeline coordinator.
- Orchestrator → Bundle API: selects · Orchestration starts by choosing a bundling strategy.
- Bundle API → Standard bundler: implements · Standard project layout is one supported bundler.
- Bundle API → Poetry bundler: implements · Poetry project layout is another supported bundler.
- Orchestrator → Strategy API: uses · Orchestration depends on a transformation strategy abstraction.
- Strategy API → Encryption: implements · Encryption is the concrete obfuscation strategy.
- Encryption → Runtime tpl: generates · Encryption strategy emits runtime loader code.
- Encryption → Private state: reads/writes · Strategy uses generated secrets and internal constants.
- Orchestrator → Runtime API: builds · Orchestration hands off runtime generation and compilation.
- Runtime API → Cython builder: implements · Cython builder is the concrete runtime build path.
- Cython builder → Init tpl: renders · Builder stamps out runtime package initialization code.
- Cython builder → Setup tpl: renders · Builder stamps out packaging setup metadata.
- Cython builder → Pyproject tpl: renders · Builder stamps out Cython build configuration.
- Cython builder → Executor tpl: embeds · Generated runtime includes the executor loader contract.
- Orchestrator → Expiry: optional · Expiry is an optional augmentation applied to output.
- Expiry → Expiry tpl: renders · Expiry feature injects generated enforcement code.
- Orchestrator → Sample app: validates on · Sample project represents the supported input shape.
- Sample app → E2E test: exercised by · End-to-end test runs the full pipeline against the fixture.
- Orchestrator → E2E test: verified by · Integration tests cover the end-to-end pipeline contract.