Both our APIs—Python and REST—allow the use of a username/password pair for authentication when connecting to Shotgun, but if a site is using SSO, the username/password method is not allowed.
While this may be surprising, there is a good explanation:
Shotgun is no longer the gate-keeper, and cannot tell by itself if your credentials are valid. This task is now handled by your IdP (Identity Provider, like Azure, Okta, etc.).
(Note: scripts that authenticate with a script_name/api_key pair are not impacted by the use of SSO, it is business-as-usual for them)
When using a browser, Shotgun redirects you to your IdP (using a 302) and then the IdP redirects your browser back to Shotgun once authenticated. Unfortunately, this mechanism is not possible when using a API-based communication. The handshake process between the servers involves Javascript being interpreted and the actual login flow varies across IdPs.
But, can't Shotgun just contact the IdP to validate the credentials?
Unfortunately, no. Depending on your specific network topology, Shotgun may not able to directly connect to your IdP (in fact, our SSO implementation assumes that Shotgun cannot connect directly to an IdP). As well, no IdP offers an API to validate a password as it is a potential security risk.
The key take-away is:
Use of username/password in API calls are inherently insecure and highly discouraged.
So, what are my options to authenticate with the API when SSO is enabled?
Use a web browser—or a browser-like widget—to authenticate and then use the session_id
from the browser to initiate an API connection with Shotgun. This is what is done by Shotgun Create, Shotgun Desktop, and RV.
These applications use a special path on the Shotgun server (<SERVER_URL>/auth/renew
) to start an authentication process for a user. Once the web widget gets back to the <SERVER_URL>/auth/landing
, we know that the login process was successful. The widget is then closed and we fetch the _session_id
value from the cookie jar. This is used to create an API connection to Shotgun.
It is assumed that any web page shown to the user is part of the authentication process or is reporting back errors to the users with additional instructions. If the widget is closed without reaching the landing page, then we know the user abandoned the process.
The mechanism used by our applications is available to all external clients, but the simplest way to make use of it is to use Shotgun Toolkit in combination with Shotgun Desktop or Shotgun Create installed on your system to use the existing session.
Additional Background and Context
Shotgun's SSO implementation relies on SAML2.0 as this older standard maximizes the number of IdP we can support. This means we do not have to rely on IdP-specific SDKs or APIs—thereby reducing maintenance and support complexity.We expect Shotgun and the IdP to know about each other, but we do not rely on direct communications between the two. In order to support the case where Shotgun is hosted on the cloud, but the IdP is hosted internally in the company’s infrastructure. For Shotgun to connect to the IdP, a special firewall configuration would be needed to allow.
Instead, we rely on the client application (e.g.—the browser or the web widget) to be the relay for communications between the two servers. The expectation being that the user’s machine is able to reach both Shotgun and the IdP. This also sheds some light on the absence of server-to-server calls to validate the user’s credentials.
Implementation Examples
Here are two potential examples of ways to proceed that connects to a site and gets the list of projects (before.py) using a username and password when assuming a simple initial Python API script:
Sample 1—Using Toolkit for User Authentication Reference
(after_simple.py) We use the toolkit to get a reference to the currently authenticated user and create a new connection to the server (which is the equivalent of a Shotgun()
object creating in the Python API). If there are no currenlty authenticated users, we instruct the script invoker to start either the Shotgun Desktop or Shotgun Create and authenticate.
Sample 2—Using Current Toolkit User
(after_self_auth.py) We attempt to use the current toolkit user. If there are none, we create a Qt Application (so that the GUI can be shown, not just command-line prompts), and then ask the user to select a site and authenticate.
These are just simple examples that can easily be modified and tailored to suit the different needs.
They each have pros and cons, and your individual use case will dictate which one makes more sense for you.
-Patrick