Developing APIs with OAuth (Inbound Apps)
To fully leverage Inbound Apps, your APIs should be designed to enforce OAuth scopes and permissions effectively. This ensures secure and granular access control, allowing AI agents, partner applications, and users to interact with your APIs while respecting consented permissions.
Designing an OAuth-specific API
Below is a generic OpenAPI spec for constructing an API that integrates Descope as an OAuth provider, manages user consent and scopes, and enforces general authorization using OAuth tokens.
This OpenAPI spec:
- Defines an authentication mechanism using Descope as an OAuth Provider with Inbound Apps.
- Includes endpoints that validate and enforce scopes.
- Supports role-based authorization with OAuth scopes.
- Implements OAuth 2.0 Bearer Token Authentication.
OpenAPI 3.0 Specification (YAML)
You can test this API spec with Swagger here.
How This OpenAPI Spec Works
-
OAuth2 Authentication
- Uses Descope as an OAuth provider with an authorization code flow.
- Enforces OAuth scopes at the API level.
-
Authorization Enforcement
- User Profile (
profile
scope) → Required for retrieving user details. - Contacts (
contacts.read
,contacts.write
scopes) → Controls read/write access. - Admin Actions (
admin
scope) → Only users with theadmin
scope can access system-wide data.
- User Profile (
-
Consent-Driven Access
- Users must grant consent before third-party applications can access their data.
Best Practices for Securing OAuth-based APIs
When developing APIs that rely on OAuth for authentication and authorization, consider the following best practices to ensure secure and compliant access control.
1. Enforce Scope-Based Access Control
Scopes define what an application can do on behalf of a user. When an inbound app requests an access token, the API must verify that the token includes the required scopes for the requested operation.
Scope enforcement can be handled in two ways:
- At the API level - Using middleware within your application to validate scopes before processing requests. See the example below.
- At the API Gateway level - Many API gateways natively support JWT validation and can enforce scopes before requests reach your backend.
For more details on using API gateways to validate Descope tokens, see our OIDC JWT authorizers documentation.
Example: Validating Scopes in an API Request (FastAPI)
This example shows how you would typically enforce OAuth scopes in a FastAPI application using Descope JWTs.
This ensures that only tokens with the contacts.read
scope can call the /contacts
API.
Example: Conditional Data Filtering Based on Scopes
Instead of blocking access entirely (as in scope validation), you can also use fine-grained filtering to adjust the response based on the user's scopes. This is typically used when some data should always be accessible, but specific data requires additional permissions (e.g., private files, admin-only records, sensitive fields).
Unlike general scope validation (require_scope), which denies access with a 403 Forbidden error if the required scope is missing, this method still allows access but limits the data returned.
In this example, all users can retrieve a list of files, but only those with the files.read_private
scope can see private files.
This ensures that users or applications with only files.read_public
cannot access private data.
2. Use Role-Based Access Control (RBAC) with OAuth Scopes
Descope enables mapping RBAC roles to OAuth scopes, ensuring that API permissions align with organizational policies. This approach allows applications to enforce fine-grained access control while maintaining role-based governance.
Multiple roles can be mapped to a singular scope with Inbound Apps, therefore it's advantageous to use both scopes and roles for comprehensive access control.
Why Use Both Scopes and Roles?
While scopes and roles both control access, they serve different purposes, and using them together provides a more secure and scalable authorization model.
-
Scopes define action-based access - OAuth scopes specify what an application or user can do within an API (e.g.,
contacts.read
,contacts.write
). They are best suited for enforcing API-level access control, particularly for third-party applications that request permissions dynamically. -
Roles define user-based access - Roles represent who the user is within an organization (e.g.,
editor
,admin
,manager
). They provide a structured way to manage permissions internally, ensuring that only authorized users can access certain features or data. -
Using both ensures security and flexibility - Scopes enforce OAuth-based permissions, while roles help maintain business logic and organizational policies. Relying solely on scopes makes it difficult to manage internal user permissions, while using only roles makes it harder to enforce fine-grained API access, especially for external applications.
Example: Mapping Roles to Scopes in API Requests
When a user authenticates, their access token includes both scopes and roles. For example, a user with the editor
role may receive the following token payload:
Enforcing Access Control with Scopes and Roles
The necessary steps therefore, that you will need to take to properly protect your APIs with OAuth scopes and roles are the following:
- Validate the OAuth scope - Ensure that the token includes the necessary scope for the requested API action.
- Check the user's role - Confirm that the user has a role that grants access to the resource or functionality.
- Apply business logic - Use the combination of scopes and roles to enforce least privilege access while maintaining organizational security policies.
Conclusion
Designing APIs with OAuth ensures secure, scalable, and fine-grained access control for applications, users, and third-party integrations. By leveraging inbound apps with Descope, developers can implement robust authentication and authorization mechanisms that enforce scopes, roles, and permissions dynamically.
By following these best practices, your API will be well-equipped to handle user authentication, enforce secure access, and integrate seamlessly with external services while maintaining compliance with the OAuth industry standards.