Search code examples
pythonclasssecurity

How should secrets be securely stored in Python variables so that they can't be read by unauthorized parties?


Unlike most languages, Python doesn't have private member variables, and so cannot force other code to interact with its member variables via class methods. How are secure python programs written to prevent unauthenticated reading of variables containing secrets and such?

I read this Stack Exchange thread stating that there are no private member variables in python, but none of the answers explained what one should do in place of a private member variable.

This Stack Exchange thread states that restricting access to member variables is only a pretense of security, not actually secure, and I don't understand what one is meant to do instead.


Solution

  • This is not possible in pure Python.

    Environment variables

    Common way to store some secrets like tokens/api keys is using environment variables. For example:

    pip install python-dotenv
    
    ############## .env file ##############
    
    MY_SECRET_TOKEN='0932jr92309rj9g43fgh94hf'
    
    ############## main.py file ##############
    
    import os
    from dotenv import load_dotenv
    
    load_dotenv()
    
    my_secret_token = os.environ.get("MY_SECRET_TOKEN")
    

    Security vs private fields

    You mentioned another languages. They don't provide such security too. Private variables are not for security, they are for code safety (to prevent programmers from making stupid mistakes). Other languages don't check authentication and prevent unauthorized access. And if you really want, you can gain access to them (for example, reflection in Java).

    If you want some real security (to make your secrets readable for only authorized users or sth like that), you should use some external storages or something like that. Doing this in python is a tough task. But ask yourself - do you really need it? You will have to think about authentication/authorization, role model (who will have access to each variable?) or something like that. In many cases, it can be redundant.

    Common cases

    In most applications, you don't have to reinvent the wheel.

    • If you have a variable related to class state or some another private, but not really secret information - put it into private variable and don't think about security.
    • If you want to store some API keys/access tokens/your login+password/some another auth information - put them into environment variables. Set those variables in ci/cd pipeline and read in python. This would be enough.
    • If you want to store users' passwords - don't put them into variables in python, store their hashes in external database.

    TLDR

    So, question about private variables/methods in Python/another languages and question about secutity are two different questions. If you want private field - make it start from double underscope like __my_private_field = 123 (like in threads you mentioned in description). If you want security - private fields won't help you (neither in Python or another languages)