Summary
"Private Clients" are only used to connect to the tenant where the OAuth Client has been created; "Published Clients" can be used with other tenants - speak with Planhat if you would like to publish an OAuth Client
If permissions are changed in a connected user's Role or in the connected OAuth Client, a reduction in permissions is automatically passed on to the external application, but an increase in permissions needs to be specifically authorized by the user
You (as the builder of an external application) can limit the permissions requested by the external application via scopes
If the "Applications" tab is not showing in User Profiles, you (as a Planhat admin) can add it to the User Full-Page Profile Template in the Planhat "Data Model" Global Tool
Who is this article for?
Technical teams and developers, including integration partners building third-party applications to connect into Planhat
Planhat admins who configure their Planhat tenant on behalf of their organization
This feature is currently in beta.
Series
This is the second article of two about Planhat OAuth Clients.
For the first article, giving an introduction and overview, see here.
Article contents
Introduction
In our overview article on Planhat OAuth Clients, we explain the concept of OAuth Clients, how to create them in Planhat, and how a user would connect to an application outside of Planhat via an OAuth Client. If you haven't yet seen that article, please go through it before reading this one.
In this article, we dive deeper into some specific OAuth Client topics, providing further technical details.
Private and Published OAuth Clients
While "Confidential Clients" and "Public Clients" are standard OAuth terms (so you can read general definitions for them online - e.g. see here and here) ...
... "Private Clients" and "Published Clients" refer to something different, and these are Planhat-specific terms.
A Private Client (not the same as a Confidential Client) is an OAuth Client created by and for you and your co-workers
A Private Client is the default state of OAuth Clients within Planhat - "Private" means it has not been "published" (by a Planhat staff member, also called a "Super Admin")
A Private Client can only be used (authorized) by users within the Planhat tenant where it's been created
Editing the Client is possible for users in the Planhat tenant with the relevant access
A Published Client (not the same as a Public Client) is an OAuth Client created for your customers
"Published" means the OAuth Client can be used (authorized) by users in different Planhat tenants
The OAuth Client first needs to go through an approval process, and then is "published" via a Planhat staff member ("Super Admin"), via a "Publish app" button in the OAuth Client only available to Planhat staff
After a Super Admin has clicked the "Publish app" button, the Public Client will become available to all tenants, so anyone can connect to the relevant external application/integration via this OAuth Client, but each user's authorization will only be for the data in their own tenant
Note that this does not mean that it will be added to Planhat's Apps Library or similar; the authorization request will come into Planhat from the external integrator's side (outside of Planhat), as per the general process we describe in the overview article here
After it's been published, the OAuth Client creator can no longer make changes to the Client (only regenerate the Client Secret and see the Audit Events). Any additional changes must be done through a Planhat staff member
π Tip
If you would like to discuss getting your OAuth Client published, please speak to Planhat staff.
Changing permissions after authorization
In our OAuth Client overview article, we went through an example of authorizing via an OAuth Client set to have all permissions for the Company model (and no other model) - you can refer back to this here if you need a refresher.
Let's continue that example - you can see the OAuth Client permissions pictured below.
Once a user has authorized access to Planhat via this OAuth Client, assuming that the user themselves has access to Companies (in their Role; we discuss this general concept here), the external application/integration could use the Planhat API to "Get" Companies, but would not have access to the Asset model, for instance (giving an error message if it was tried: You are not allowed to view m_asset.).
Let's go through a couple of scenarios where permissions levels are changed - either in the Planhat user's Role or in the OAuth Client - after the connection has been authorized, to see what the consequences would be.
To summarize, you'll see that the basic principle is that a reduction in permissions (reduction in access) is automatically applied, but an increase in permissions (increase in access) needs to be specifically authorized by the user.
User losing permissions in Planhat
What happens if a Planhat user connects to an external application/integration via the example OAuth Client above, and then that user loses access (permissions) to the Company model (as their Planhat "Role" changes)?
The external application/integration had got permission to access to Companies on behalf of this user, but now that the user no longer has any access to Companies, if the external application/integration attempts to access Companies, it will fail. In other words, this loss of permissions is automatically passed on.
This works on a granular level too. For example, imagine a user had full access to the Company model, and granted access to an external application/integration based on this, but then at a later date loses access to specifically the "Address" field on the Company model. If the application then sends a request for Companies, the Planhat API will return the Companies, but without the "Address" field.
User gaining permissions in Planhat
If a connected user's Role in Planhat is updated so that it has more permissions, that extra access would not automatically be passed on to the external application/integration, regardless of the permissions set in the OAuth Client.
Let's go back to our example described above, where an OAuth Client was set to full Company access, and a user connected when they had full Company access, but after authorization, the user's Role was adjusted so they lost access to the Company model (or one of its fields), and the external application/integration automatically lost that access too.
If the user then later regains full access to Companies in Planhat, they will need to go through the authorization process again to give access to the external application/integration.
π Important to note
For Role portfolio permissions specifically (so that's about which Company records you can access, rather than model/field permissions) reauthorizing isn't needed if your access level increases.
OAuth Client / external application requesting more permissions
Let's again say that the user had previously authorized the external application/integration and granted access to Companies in their Planhat tenant via the integrator's OAuth Client.
Now the external integrator also needs access to Issues, so they update their OAuth Client and add permissions for the Issue model.
Updating the OAuth Client like this does not automatically give extra access to the connected external application/integration. The user will need to explicitly grant the additional access by going through the authorization process again.
OAuth Client / external application requesting fewer permissions
What about the other way round?
Again, let's say that a user had already granted full Company access to the external application/integration via their OAuth Client.
Now, imagine that the external integrator realizes they don't need all the Company permissions (e.g. maybe only "View" is required, whereas "Create" and "Update" are not), so they update their OAuth Client to remove some of the permissions.
In this case, as we are reducing permissions, the user's OAuth grant will be automatically updated to remove those permissions. If the external application/integration then later on tries to use those removed permissions, the Planhat API will return a failure error message.
OAuth scopes
π Tip
OAuth scopes are not something that will be used regularly, as you would typically simply set permissions using the OAuth Client.
However, using OAuth scopes can be useful for developers in some development/debugging scenarios.
In the OAuth Clients overview article, and above, we have discussed how you specify permissions within an OAuth Client. This defines the maximum access available to an external application/integration using that OAuth Client. It means that a user can authorize access up to the permissions stated in the OAuth Client.
But it's also possible for the external application/integration to request less access than this maximum set within the OAuth Client. This would mean that when the user clicks on a "Authorize" or "Connect" or similar button within the external application/integration, the modal that's shown to them requesting access actually shows a narrower set of permissions, and the user then consents to only that more restricted level of access.
This is achieved via "scopes", which is a standard OAuth concept, rather than being something Planhat-specific. Scopes effectively act as another layer of permission restrictions.
Scopes are set up within the external application/integration, by the integrator.
The general principle is that a user clicks on a button within the external application (as we mentioned above), which requests access to one or more scopes. The details of the scopes are shown to the user, who reviews and can click to authorize. The access token that is issued to the external application will have permissions limited by the scope(s), rather than the OAuth Client (although note that the scopes cannot have greater permissions than the OAuth Client).
Technical details
By passing the "default" parameter in the scope, you (as an integrator) get access to whatever was configured in the "Permissions" tab of the OAuth Client - this is the maximum permissions available.
To request partial access, you can specify scopes using a notation beginning with m_ (for "model").
The basic structure is: m_[model][.optional property/field]:[action]
You can specify multiple scopes in one go, with a space between each scope.
Let's go through an example. In this example, the OAuth Client has all the permissions for the Company model enabled.
Let's say you are an integrator, and you only need the "View" permission for the Company model, despite there being more permissions available for Company in the OAuth Client in Planhat as shown above.
You can achieve this by specifying "m_company:view" in the scope.
When the user of your application/integration clicks "Authorize" or "Connect" or similar, it will only request Company "Read-only" (i.e. View), as shown below.
Clicking on "Show more", we can see that all Company properties (fields) are included in this case:
If you (as the integrator) want to specify other actions, such as "Update", it follows a similar structure - e.g. "m_company:update".
If you just want access to a particular property (field) on a Planhat data model, rather than the whole model, you can specify this in the scope. For example, you may want to just view the "Address" property on the Company model.
You can specify this by entering "m_company.address:view" in the scope. You do not need to specify "m_company:view" in the scope (for the whole Company model) as well, because that's assumed by the property access requested. Now when the authorization flow is initiated by the user, it will be specifically for "Company Read-only" and "Can view: Address", as shown in the screenshot below
By default, the standard Planhat record ID field is available for all models, so there is no need to ask for the ID specifically.
Both standard fields and custom fields are supported. (For custom fields, you need to specify "custom " before the field name.)
A word of warning
Summary
When you reduce the scope and successfully reauthorize:
New access/refresh tokens are generated to match the new scope
Previous access tokens will have the scope reduced
Previous refresh tokens will stop working
Background context
The basic OAuth authorization flow is:
In the external application (third-party integration), a user clicks on a button to authorize access to Planhat - with the appropriate access as per the scope
The user is redirected to Planhat with a consent screen (the modal showing the access being requested and the options to authorize or cancel)
The user clicks "Authorize" to approve the request
Planhat redirects back to the defined redirect URL (defined in 1 and in OAuth Client settings) with an authorization code
The external application uses that auth code to ask Planhat to generate an access/refresh token pair
Planhat issues the token pair, matching the scope defined in step 1, and the external application stores it
Going forward, if the external application wants to connect to Planhat on behalf of the user, it uses the stored access token from step 6, which has the appropriate scope.
Access tokens expire in 1 hour after they're issued, or when the application gets disconnected.
Refresh tokens expire 1 year after they're issued, or when they're used, or when the application gets disconnected, or when another authorization flow happens (the steps listed above).
If the current access token expires or becomes invalid, the external application can use the refresh token (not the authorization code) to ask Planhat to generate a new access/refresh token pair, without requiring the user to re-authenticate. As with the usual authorization flow, Planhat issues the token pair, and the external application stores it.
When a new token pair is generated, the previous tokens will be marked as deleted/consumed (for security). The old refresh token can no longer be used. If there is any other attempt to use the old refresh token that was already deleted/consumed, the application will be disconnected.
How this applies to scopes
After the initial authorization, if you (as an integration builder) reduce the scope and then the user (or you when testing) clicks through the authorization flow again, this includes generating a new pair of access/refresh tokens to match the new, smaller scope.
The old access token will have its scope reduced to match the new scope, and the old refresh token will be invalidated and will cause the application to be disconnected if you attempt to use it.
How to add the "Applications" tab to User Profiles
In the OAuth Clients overview article, we discussed how users can disconnect any connected external applications via the "Applications" tab in their Planhat User Profile.
If the "Applications" tab is not showing there, it needs to be added to the Full-Page Profile Template of the User model (by a Planhat user who has the appropriate permissions, e.g. a Planhat admin):
In Planhat, go to the "Data Model" Global Tool for admins (in the "System Admin" menu)
Select the "User" model on the left-hand side, and select the "Profile" tab
Click on the Profile, and click "Full Page"
Click the "+" symbol next to "Tabs", and select "Applications" from the list
You can "drag and drop" the tab to your chosen position. Once you've done this, click "Save" in the top-right corner
Further reading
For information on connecting Planhat's MCP Server to external AI tools via OAuth, please refer to our separate MCP documentation here.











