Turnstile simplifies the building of SaaS apps on Azure by automating subscription and seat (or license) management. Turnstile is deployed into your own Azure environment and is designed to work with any SaaS app regardless of development stack or architecture.
Before we dive deeper into how Turnstile works, let's first establish a common vocabulary.
Customers (represented in your SaaS app as tenants) purchase subscriptions to your SaaS app. A subscription may include a predefined number of seats (or licenses) that users can obtain to access your SaaS app.
When a user tries to access your SaaS app, your app first calls an API endpoint that Turnstile exposes to check if the user already has a seat. If the user does not have a seat, your SaaS app redirects the user to Turnstile to try to obtain one as illustrated in the diagram below.
graph TD
A(User tries to<br />access SaaS app) --> B(SaaS app asks<br />Turnstile for a seat<br />for the user)
B --> C{Does the user<br />already<br />have a seat?}
C -- Yes --> D((User accesses<br />SaaS app))
C -- No --> E(User is redirected<br />to Turnstile to try<br />to get a seat)
E --> F{Is a seat<br />available?}
F -- Yes -->G(Turnstile assigns a<br />seat to the user)
G --> H(Turnstile redirects<br />user to SaaS app)
H --> B
F -- No -->I((User informed<br />that no seats<br />are available))
style D fill:darkgreen,color:white
style I fill:darkred,color:white
Turnstile exposes two endpoints to users trying to access a subscription —
/turnstile/{subscription_id}
where {subscription_id}
is the ID of the subscription the user is trying to access. This endpoint executes the workflow illustrated below on behalf of the user to try and obtain them a seat. graph TD
A{Does Turnstile<br />know about<br />this subscription?}
A -- No --> B((Subscription<br />not found))
A -- Yes --> C{Does the user<br />have access to<br />this subscription?}
C -- No --> D((Access denied))
C -- Yes --> E{Has this subscription<br />been canceled?}
E -- Yes --> F((Subscription<br />canceled))
E -- No --> G{Is this subscription<br />suspended?}
G -- Yes --> H((Subscription<br />suspended))
G -- No --> I{Does this user<br />already have a seat?}
I -- Yes --> J((Redirect to<br />SaaS app))
I -- No --> K{Is a seat<br />reserved for<br />this user?}
K -- Yes --> L(Assign seat<br />to user)
L --> J
K -- No --> M{Are there any<br />more seats<br />available in this<br />subscription?}
M -- Yes --> L
M -- No --> N{Is limited<br />seating enabled?}
N -- Yes --> O(Assign limited<br />seat to user)
O --> J
N -- No --> P((No seats<br />available))
style B fill:darkred,color:white
style D fill:darkred,color:white
style F fill:darkred,color:white
style H fill:darkred,color:white
style P fill:darkred,color:white
style J fill:darkgreen,color:white
First, ensure that the following prerequisites are met.
Navigate to the Azure portal and launch the Bash cloud shell.
If this is the first time that you've used the cloud shell, you will be prompted to create or choose an existing an Azure Files share.
Run this command from the cloud shell to clone this repository —
git clone https://github.com/microsoft/turnstile
Navigate to the setup folder by running —
cd ./turnstile/Turnstile/Turnstile.Setup
Finally, allow the setup script to be executed locally by running —
chmod +x ./setup_turnstile.sh
At a minimum, you need this information before running the setup script —
az account list-locations -o table
from the cloud shell. Be sure to use the region's Name
, not DisplayName
or RegionalDisplayName
.To setup Turnstile, run —
# Broken down into multiple lines for readability...
./setup_turnstile.sh \
-r "replace with your Azure region" \
-n "replace with the name of your Turnstile deployment" \
-d "replace with the display name of your Turnstile deployment"
Once the script is finished, note the information provided in the Turnstile Deployment Summary
. We strongly recommend saving these values somewhere safe and convenient as you will likely need to refer to them again later.
Locate the setup URL at the very bottom of the script output. It will look similiar to this —
https://turn-web-example01.azurewebsites.net/publisher/setup
# Where "example01" is the Turnstile deployment name.
Click the URL (it's automatically linked within the cloud shell) to navigate to that site and complete the Turnstile setup wizard.
The setup wizard is hosted entirely within your own Turnstile deployment so you're aren't sharing any information with Microsoft (or anyone else) at this point.
Turnstile exposes an API that allows you to manage seats and subscriptions. Turnstile includes an automated end-to-end testing script that stands up a Turnstile API test environment, runs a series of tests against the Turnstile API, then destroys the test environment. The script contains examples of how to perform the most common Turnstile API tasks —
This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.
When you submit a pull request, a CLA bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.
This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.
This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow Microsoft's Trademark & Brand Guidelines. Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos are subject to those third-party's policies.