Kaseya Community

Custom App to Auth Against VSA with API

  • We have a custom application we built that currently authenticates against Active Directory. Now we have some Kaseya users outside of our domain that are going to need access to our application. I'm trying to avoid creating an additional user database. I have a few ideas, but was hoping to get some input from people with experience before wasting a lot of time doing research. Note, I haven't done research yet and I'm not asking you to; just asking for input from anyone that may know off the top of their head.

    My number 1 idea is using the VSA REST API to authenticate against the VSA user database. From the help, to authenticate it says "Enter the UserName and Password of a user authorized to connect with the Kaseya Server." What I wasn't sure about is if any account on the VSA has API access or is there a special permission to grant users API access.

    My number 2 option would be integrating with SSO in AuthAnvil. This might even be the better option, but we haven't been using AuthAnvil yet, so this will be more work on implementation. Is this even what SSO is really intended to do, act as a user database for other applications?

    My number 3 would be AD integration using a separate, custom built agent installed on remote DCs to authenticate against remote domains. This would work, but adds complexity, remote firewall configuration, and performance concerns.

    Thanks for any input!

  • I just ran a test and can confirm that a reduced privilege account will be authenticated by the API. The token provided has the same permissions as the user account, so it's useless to actually do anything, but it does show that the account can be authenticated. Here is a test you can run yourself (I'm doing this from an Ubuntu-based system):

    1. Create a user account with no permissions. For me, I had a scope called NoAccess that  can't see any organizations, machine groups, or machines. I'm going to use the username testuser and the password Testing 123 below as the example.
    2. Run the following commands to obtain a token for the user:
      # You should generate a random number, like this, but could get by in testing with just making up a number
      #rand=$(( `openssl rand 4 2>/dev/null|od -A d -t u4|awk '{print $2}'|sed s/^0*//` ));
      sha1=`echo -n "$pass$user"|sha1sum|awk '{print $1}'`
      sha2=`echo -n "$pass$user"|sha256sum|awk '{print $1}'`
      sha1=`echo -n "$sha1$rand"|sha1sum|awk '{print $1}'`
      sha2=`echo -n "$sha2$rand"|sha256sum|awk '{print $1}'`
      auth64=`echo -n $auth|base64 -w 0`
      token=`curl -X GET -H "Authorization: Basic $auth64" -s -S -f $url|grep -Po '"Token": "\d+"'|sed 's/.*:.*"\([0-9]*\)".*/\1/'`
      echo "Token: $token"
    3. Once you have a token, you can verify that your token doesn't have access to things by executing a query with the token. I ran this curl request to check for a list of machines in a machine group the account doesn't have access to:
      curl -G -H "Authorization: Bearer $token" -v --url "https://yourvsa.company.com/api/v1.0/assetmgmt/agents" --data-urlencode "\$filter=MachineGroup eq 'root.customer'"

    If you want to test what happens when the account fails to authenticate, just mess up your password and see.

    Hope this helps.


    P.S. Here's the whole token request script from above as a one-liner:

    user='testuser'; pass='Testing123'; twofapass=:undefined; url=https://yourvsa.company.com/api/v1.0/auth; rand=$(( `openssl rand 4 2>/dev/null|od -A d -t u4|awk '{print $2}'|sed s/^0*//` )); sha1=`echo -n "$pass$user"|sha1sum|awk '{print $1}'`; sha2=`echo -n "$pass$user"|sha256sum|awk '{print $1}'`; sha1=`echo -n "$sha1$rand"|sha1sum|awk '{print $1}'`; sha2=`echo -n "$sha2$rand"|sha256sum|awk '{print $1}'`; auth="user=$user,pass2=$sha2,pass1=$sha1,rand2=$rand,rpass2=$sha2,rpass1=$sha1,twofapass=$twofapass"; auth64=`echo -n $auth|base64 -w 0`; token=`curl -X GET -H "Authorization: Basic $auth64" -s -S -f $url|grep -Po '"Token": "\d+"'|sed 's/.*:.*"\([0-9]*\)".*/\1/'`; echo "Token: $token";

  • That helps a ton. Thanks! We'll head that direction then.