The biggest problem in API security is over-privileged access. Many of the risks mentioned in the OWASP API Security Top 10 stem from this issue. To solve these problems, developers and architects need an API security design that enables APIs and clients to run with the least privilege.
Scalable least-privilege access is the problem that OAuth 2.0 solves. You use scopes to set security boundaries and to reduce API privileges granted to clients. Often, however, developers do not understand scope best practices. Therefore, this article provides some practical guidance for using scopes effectively.
What Are OAuth 2.0 Scopes?
Scopes are strings attached to access tokens that define what the token can do. APIs then use these scopes to enforce access rules.
A simple example might look like this:
Resource Type - order
Access Level - read
Scope Value - order_read
The OAuth 2.0 spec doesn’t tell you how to design scopes; it leaves that to you. So let’s talk about how to do it well.
Example Scenario
Imagine you’re building a system that sells products online. You’ve got multiple APIs (orders, shipping, inventory) and multiple types of clients (customer app, admin portal, supplier dashboard).
Each client needs access to different parts of your APIs. That’s where scopes come in.
Scopes in Clients & User Consent
- Clients are configured with scopes that limit their API privileges.
- After login, the authorization server issues an access token with those scopes so that the user can control the access granted to the client.
- If it’s a third-party client, show a consent screen so the user can pick what to allow.
For first-party clients (where you own both the API and the client), you can skip the consent screen to avoid user confusion.
Designing Scopes
Good scope design keeps your system flexible and secure.
1. Use Hierarchical Scopes
You can model subresources with colon-separated scopes:
2. Keep Scopes Stable
Start simple. Use broad scopes for major business areas (e.g., marketing, finance) and add detail only when you really need it.
3. Give Clients Least Privilege Scopes
Only grant scopes to clients that they need so that they cannot access APIs outside of their area. Use readonly scopes where possible. Also consider threats based on the type of client or its environment. For example, use more restrictive scopes if you expose API endpoints to AI agents.
4. Avoid Scope Explosion
Avoid frequently upgrading clients to use new scopes.
Avoid the need for access token versioning in your APIs.
Avoid deploying frequent scope configuration updates to your authorization server.
Consider an incorrectly designed scope of 'orders:admin:usa' that could lead to scope explosion. To avoid that, use a single scope of 'orders' and two claims for 'role=admin' and 'country=USA'.
Include Scopes in your API Authorization Strategy
OAuth-secured APIs apply security in 3 main steps:
- Validate JWT access tokens
- Enforce required scopes
- Implement claims-based authorization
To implement the first step, follow JWT best practices. Then, enforce required scopes for each API request. If an API ever receives a valid access token but without the required scopes, the API should return an HTTP 403 forbidden response. The code to do so is straightforward and is sufficient to set API security boundaries and enforce least privilege access.
Scopes Contain Claims
Scopes do not provide a full authorization solution. Scopes are fixed at design time and do not vary per user. Scopes set security boundaries as part of a least privilege strategy. To complete API authorization, use claims.
Whenever you issue a scope to access tokens, you can issue one or more claims. Claims are evaluated at runtime and can have different values per user. To read more about claims and how they relate to scopes, see the claims best practices.
Advanced Scope Techniques
Although you need claims to complete authorization, scopes are versatile and also have some advanced use cases. For example, you can use the following techniques:
- High-Privilege Scopes Request extra scopes only when needed (e.g., order:payment during checkout).
- Prefix Scopes Design scopes with a dynamic suffix like transaction-12345.
- Scope Expiry (TTL) Configure short-lived high-privilege scopes (e.g., 15 minutes).
- Token Exchange Downscope tokens when passing between APIs. Example: Orders API → Shipping API.
Always design scopes in terms of end-to-end flows between the client and the set of API calls the client initiates. The Token Sharing article explains some ways to scale the use of scopes.
Best Practices Recap
Use the following best practices to use scopes effectively:
- Design scopes to set API security boundaries
- APIs must always enforce scopes for every request
- Keep scopes stable and business-focused
- Keep scopes manageable and avoid scope explosion
- Understand how to scale the use of scopes
Have a look at the scope best practices for a more detailed description of the aforementioned points.
Conclusion
Scopes are a simple concept that requires only trivial code to apply. However, they provide a highly effective way for users to run applications with the least privilege access to APIs.
The heart of using OAuth correctly is to design access tokens with scopes and claims. Use scopes for coarse-grained access, and pair them with claims for fine-grained control.
With a smart scope design, you’ll have APIs that are secure, scalable, and easier to maintain.
Top comments (0)