Package: passcode
Overviewpasscodeprovides a simple way to encrypt python modules on a development machine, pass the protected code through a
public repository, pull the protected code into production, automatically decrypt the protected code at runtime on the
production machine, and reference the protected code from other components at runtime. Do all of that with just two
lines of code!passcodemakes it possible to include secrets (such as a login password or some proprietary code) directly in your
code without others being able to read it in a push-to-deploy repository.passcodeis written in pure Python 3.X, has no dependencies, and requires two lines of code to implement. You can
easily inspect and verify the operation ofpasscodeto see what it does.InstallInstallationInstall with pip:pip install passcodeor clone the repository into your own project from GitHub:git clone https://github.com/KenYounge/passcode.gitUsageimport passcode
passcode.execute('secrets', locals(), '~/mypasscode.key', '/private/mypasscode.key')InstructionsInstall passcode.pip install passcodeCreate a passphrase.First option is to generate an ASCII passphrase manually and to thebn save it into a file, such aspasscode.keySecond option is to leave thekey_devparameter blank, andpasscodewill prompt you for a passcode.You can use different keys for different code modules, thereby enforcing differential access-control.Import passcode and private modules:The following code uses thepasscode.update()function to encrypt, decrypt, and import code modules.The original source code is imported into local scope and you can reference variables and functions as normal.import passcode 
passcode.execute('secrets1', locals(), '~/passphrase1.key', '/private/passphrase1.key')
passcode.execute('secrets1', locals(), '~/passphrase2.key', '/private/passphrase2.key')Exclude the original plaintext files (that you want to secure) from the repository.You do not want the passphrase file(s, or the unencrypted module(s) that you want to protect, to appear in your
git repository as plaintext. Therefore do notgit addthose file(s) to the repository.Alternatively, you can list those files for exclusion in the.gitignorefile.Include only the encrypted versions of the protected modules in the repository:git add *.rc4Re-runpasscode.execute()each time you change a passcode protected module.passcode.execute()will refresh the encrypted copy of a module each time it is executed.Therefore re-runexecute()each time you change a protected source fie.Push your project to the repository.Configure.gitignoreto exclude your secret module(s) and your secret password key(s) from the repository.And/or make sure that you do not add those files to the repository in the first place.Deploy keys independently (and privately) to production.You need to distribute your private keys to production by another, more-protected approach:move the password key(s) to a more secure git repository with limited access by others;install the password key(s) into a protected directory in a Docker Container or a VM Image;manually copy the password key(s) to the production machine.OPTIONAL: Enable code completion for the development IDE.IDEs will autocomplete and check for some errors when they can reference original code declarations.The IDE cannot do that, however, if it cannot find a normal Python import statement to reference.The following code will enable code completion & inspection on the dev-side IDE.Note that the code will raise an error on a production machine (because the imports will be missing),
so you must catch each error (independently) for each import.try: from private_code import *   
except: pass   

try: from another_module import *   
except: passOPTIONAL: Recover an original source file from an rc4 file.Your original source code is still backed up and protected in the git repository - just not in plain text.You can recover the original source code (*.py) file from an encrypted *.rc4 file if you have the original key.Runpasscode.recover()to recover the original, unencrypted file.DisclaimerUSE THIS CODE AT YOUR OWN RISK. I provideno guaranteeabout it's security, safety, reliability, or any other
potential risk or harm.DemonstrationSee the filedemonstration.pyfor an example of how to usepasscode.Tech notesThe production environmentThe purpose ofpasscodeis to protect secrets while in transit through a git repository. It does NOT protect secrets
in the production environment. Although you can save passcode keys in an access-protected directory of the production
environment (i.e., separate from the running code) that others cannot access, it may be possible for others to access
the decryopted code during runtime by re-writing the application to stop, inspect, and dump out the secret code
(although they also would have to have permission to change the runtime code in the production environment). This is a
limitation of this apporoach. We are open to suggestions from others about ways to strength the last-stage of security
with other "bring your own encryption key" steps that could be combined withpasscode.RC4 EncryptionEncryption is implemented with the "alleged" RC4 algorithm. Although RC4 is not as secure as AES, it is simple, it is
fast, it is implemented in pure python, and it has no imports. Another advantage of RC4 is that you can easily inspect
our code and confirm what it does. A more advanced algorithm would require dependencies and a more complicated
installation/distribution. You can implementpasscodeby doing nothing more than just copyingpasscode.pyinto
your project.There is some concern that RC4 is breakable through a 'man-in-the-middle' attack over a very large volume of encrypted
traffic. We presume, however, that you will usepasscodeto encrypt only a handful of python files, and that those
files change infrequently. As such, you should not generate the millions (or billions) of examples that are needed for
a statistical attack.Set your own passphraseBe sure to set your own passphrase in your own password files. In general, it is better to NOT use the file namepasscode.key(the default assumed bypasscode.update()), but rather generate and name your own file. A
random file name for your key would also seem to reduce the chance of mistakenly using a key file from somone else.Version HistoryVersion 0.1.5  -  2021.02.17Moved implementation into a__init__.pyfile so user an import it directly as a directory.
Changed naming of the implementation methods.
Fixed bug in RC4 which would break on some unicode characters.Version 0.1.2  -  2021.02.11Renamed the example files.Version 0.1.1  -  2021.02.10Improved the ReadMe.Version 0.1.0  -  2021.02.09First distribution to PyPi.OPEN BUG REPORTSTerminate modules (that you aim to encrypt) with at least one newline character. This helps python to distinguish
complete vs. incomplete statements in the code module.There are reports of the pythoncompile()function failing to parse some types of code due to whitespace in it.
This is being investigated.There are reports of the our encrypt/decrypt sequence, plus the pythoncompile()function, dropping an apostrophe
(i.e., the ' character) - switching to double quotes seemd to fix the problem for some reason in the known case.This is being investigated.