Let's protect that CLI Python script I needed a way to make a CLI based script a bit secure. So, I thought of the following workflow:


the client will get the MAC of the user, sha256 it and put it in a file at a specific location
then in my program, I'm also doing the same thing, check to see if the sha256 of the MAC is present in the file (and if it matches) then let the user use the script.
more, that text file will have multiple lines in it (but the only one that maters is the first one)


I'm aware that this might not be the best option for securing a script, but the client said ("do this to make it a bit harder for somebody else to use it").

import hashlib
import sys

from uuid import getnode


def get_mac():
    """return the MAC address of a specific machine"""
    return bytes(str(getnode()), 'utf-8')


def hash_mac():
    """hash the MAC using sha256 algorithm"""
    return hashlib.sha256(get_mac()).hexdigest()


def main():
    with open('uid_file.cfg') as uid_file:
        first_line = uid_file.readline().replace('\n', '')

        if str(hash_mac()) in first_line and len(str(hash_mac())) == len(first_line):
            print('Match MAC and execute program here\n')
        else:
            print('MAC does not match! Exiting...')
            sys.exit(0)


if __name__ == '__main__':
    main()


Any advice on what could go wrong or alternatives / good practices are welcome.
hexdigest returns a string

So you don't need to str(hash_mac()) each time. Even if it didn't, you would probably want to put the str call within that hash_mac function.
You're not using get_mac for any other purpose than hashing it.

You might thus want to encapsulate this functionality into hash_mac:

from uuid import getnode as get_mac

def hash_mac():
    """hash the MAC Address using sha256 algorithm"""
    mac = str(get_mac()).encode()
    return hashlib.sha256(mac).hexdigest()

You don't need to get a file open for that long.

You can close it as soon as you read its first line. As a bonus, you can also directly compare strings:

def main():
    with open('uid_file.cfg') as uid_file:
        first_line = uid_file.readline().strip()

    if hash_mac() == first_line:
        print('Match MAC and execute program here\n')
    else:
        print('MAC does not match! Exiting...')
        sys.exit(0)

You can feed error messages to sys.exit:

sys.exit('Mac does not match! Exiting...')


will print Mac does not match! Exiting... to stderr and exit the program with a status code of 1. Note that usually, a status code of 0 means success.
If you want to use it as a form of security, you should avoid giving hints of what to do to unauthorized persons:


if uid_file.cfg does not exist, a traceback saying it tried to open it will be printed
if content of the file mismatch, a hint is given such that it should contain a MAC address


You can try to avoid that with a generic error message such as Access denied:

def main():
    try:
        with open('uid_file.cfg') as uid_file:
            first_line = uid_file.readline().strip()
    except OSError:
        sys.exit('Access denied')

    if hash_mac() != first_line:
        sys.exit('Access denied')

    print('Match MAC and execute program here\n')





Lastly, it might be interesting to define this function as a check that you can easily disable while developping/testing:

import sys
import hashlib
from uuid import getnode as get_mac


def hash_mac():
    """hash the MAC Address using sha256 algorithm"""
    mac = str(get_mac()).encode()
    return hashlib.sha256(mac).hexdigest()


def check_secure_user():
    try:
        with open('uid_file.cfg') as uid_file:
            first_line = uid_file.readline().strip()
    except OSError:
        sys.exit('Access denied')

    if hash_mac() != first_line:
        sys.exit('Access denied')


def main():
    print('Match MAC and execute program here\n')


if __name__ == '__main__':
    check_secure_user()  # deactivate while developping
    main()