StatCan / aaw

Documentation for the Advanced Analytics Workspace Platform
https://statcan.github.io/aaw/
Other
69 stars 12 forks source link

Implement JWT alternative authentication #1283

Closed rohank07 closed 2 years ago

rohank07 commented 2 years ago

While Azure/Cns make efforts to enable the JWT endpoint on the cluster, we are temporarily using password file authentication. https://trino.io/docs/current/security/password-file.html Create a script to automate the entry of new profiles in password.db file and storing the password as a k8s secret in the user namespace. Manual steps needed:

  1. Run script 2. Paste updated password.db file (with new entries) into the trino coordinator configmap 3. Commit to source to control The password.db hot-load's the file (once synced in argo-cd) not having to restart trino-coordinator deployment.

Unable to use kubectl cp since trino coordinator pod is a read-only file-system

rohank07 commented 2 years ago

file-auth.sh

# Compiles a list of all profiles in the cluster
kubectl get profile -o json | jq -c '.items[] | (.metadata.name)' > profiles.txt
python file-auth.py

file-auth.py

import subprocess
from subprocess import call
import json

user_token_dict = {}
current_db_users=[]

# Create a token/api key for each user
def generate_user_token(user):
    token=subprocess.getoutput("openssl rand -base64 12")
    #print (token)
    user_token_dict[user]=token

# Add/Update the password.db file for new profiles    
def append_to_password_db(username, password):
    #print(password)
    call ('htpasswd -b -B -C 10 password.db ' + username + ' ' + password, shell=True)

def main():
    with open('password.db', "r+") as t:
        for line in  t:
            user= line.split(":", 1)
            current_db_users.append(user[0])
            # print(user[0])

    aaw_profiles=[]
    # All Profiles in AAW
    with open('profiles.txt',"r") as f:
        for line in f:
            profile=line.replace('"', "").strip()
            aaw_profiles.append(profile)
            #print (line)

    for u in aaw_profiles:
        if (u not in current_db_users): # Create new entries in password file for newly created Profiles
            print ("User " + u + " does not exist in password.db") 
            generate_user_token(u)
            append_to_password_db(u, user_token_dict[u])
            print (user_token_dict[u])
            # Create secrets in each namespace
            subprocess.run("kubectl create secret generic trino-auth --from-literal=password="+ user_token_dict[u] + " -n " + u)

    # Export Dictionary to file. Do not commit!
    with open('pw_dict.txt', 'w') as convert_file:
        convert_file.write(json.dumps(user_token_dict))

if __name__ == "__main__":
    main()

Updated trino-wrapper.sh

#!/bin/bash

# Get token from default service account
GET_TOKEN="$(kubectl describe secret default-token | grep 'token:' | sed 's/^.*://')"

GET_AUTH_TOKEN="$(kubectl get secret trino-auth -n $NB_NAMESPACE --template={{.data.password}} | base64 -d)"

SERVER=https://trino.aaw-dev.cloud.statcan.ca

export TRINO_PASSWORD=$GET_AUTH_TOKEN

# Trino client pass in server, user, access token and additional options the user can configures
trino-original --server $SERVER --debug --catalog hive --user $NB_NAMESPACE --password "$@"
rohank07 commented 2 years ago

Branch https://github.com/StatCan/aaw-trino/tree/file-auth User authentication using password-file auth is functional in Dev

rohank07 commented 2 years ago

Must have http-server.process-forwarded=true enabled to true on the coordinator for auth to be functional