Scope Model
Summary
A Scope in Keymate defines an action that can be performed on a resource — such as read, write, delete, or admin. Scopes bridge resources and permissions: authorization policies evaluate whether a user has a specific scope on a specific resource. Beyond action scopes, Keymate introduces Scope Types — a 7-level organizational hierarchy that defines authorization boundaries from system-wide to individual user level.
Why It Exists
Authorization requires answering: "Can this user do this action on this resource?" Scopes provide the "action" component:
- Granular control — Define exactly what operations are permitted (read vs. write vs. admin)
- Reusability — The same scope (
read) applies across many resources - Consent clarity — OAuth consent screens display scope names to users
- Policy simplification — Policies reference scopes, not individual operations
Scope Types address multi-tenant complexity:
- Organizational boundaries — Define where authorization rules apply (global, tenant, organization, user)
- Hierarchical inheritance — Higher-level scopes cascade to lower levels
- Audit isolation — Enable/disable audit logging per scope level
Where It Fits in Keymate
Scopes are assigned to resources, then combined with policies in permissions. When a request arrives, the authorization engine checks: "Does the user's policy grant this scope on this resource?"
Boundaries
This concept covers:
- Scope entity structure and naming conventions
- Scope Type hierarchy (7 levels)
- Default scopes and client assignment
- Permission linking and usage tracking
- Audit logging configuration per scope type
This concept does not cover:
- Resource definitions → see Resource Model
- Permission and policy configuration → see Policy Model
- OAuth scope tokens → see Token & Session
How It Works
Scope Entity Structure
| Field | Type | Description |
|---|---|---|
id | UUID | Keycloak-generated scope identifier |
name | String | Unique action identifier (e.g., read, payment:refund) |
displayName | String | Human-readable name for consent screens |
iconUri | String | Icon URL for visual consent representation |
isDefaultScope | Boolean | Auto-assign to new clients if true |
linkedResourcesCount | Long | Number of resources using this scope |
Naming Conventions
Use consistent scope naming for maintainability:
| Pattern | Example | Use Case |
|---|---|---|
| Simple action | read, write, delete | Generic CRUD operations |
| Resource-prefixed | payment:read, user:admin | Resource-specific actions |
| Hierarchical | order:item:update | Nested resource actions |
Use lowercase, colon-separated naming (resource:action) for consistency. This pattern clearly identifies both the resource context and the action.
Default Scopes
When isDefaultScope = true, the scope is automatically added to new clients. Use default scopes for:
- Basic read access that most applications need
- Common operations like
profile:readoropenid
Sensitive scopes (write, delete, admin) should require explicit assignment.
Scope Type Hierarchy
Scope Types define organizational authorization boundaries. Keymate provides a configurable 7-level hierarchy, enabling dynamic configuration:
| Level | Scope Type | Description |
|---|---|---|
| 0 | system | Platform-wide, system administrators only |
| 1 | global | All tenants and organizations |
| 2 | tenant-type | Specific tenant tier (Enterprise, SMB, Free) |
| 3 | tenant | Single tenant boundary — most common level |
| 4 | organization | Sub-organization within a tenant |
| 5 | user-groups | Specific user group membership |
| 6 | user | Individual user, narrowest scope |
Scope Type Entity
| Field | Type | Description |
|---|---|---|
id | String | Unique identifier |
name | String | Display name (e.g., tenant) |
level | Integer | Hierarchy level (0 = root) |
parentId | String | Parent scope type reference |
isAuditEnabled | Boolean | Enable audit logging for this level |
status | Enum | ACTIVE, INACTIVE, or DEPRECATED |
Scope Type Assignment
Resource Servers are assigned a scope type that defines their authorization boundary:
{
"clientId": "payment-api",
"scopeTypeId": "<TENANT_SCOPE_TYPE_ID>",
"tenantId": "acme-corp-uuid"
}
This Resource Server operates at the tenant level — its resources are isolated to the Acme Corp tenant and policies evaluate within that boundary.
Audit Configuration
Each scope type has an isAuditEnabled flag. When enabled:
- Authorization decisions at that scope level are logged
- Policy evaluations generate audit events
- Compliance reporting captures access patterns
Disable audit for high-volume, low-sensitivity scope levels to reduce storage overhead.
Diagram
Example Scenario
Scenario
An architect configures scopes for a payment processing API, establishing fine-grained actions and assigning the Resource Server to operate at the tenant scope type.
Input
-
Actor: Platform architect
-
Resource Server:
payment-api -
Action: Configure scopes and scope type
-
Context:
Scope definitions:
[
{"name": "payment:read", "displayName": "Read Payment Information"},
{"name": "payment:create", "displayName": "Create Payments"},
{"name": "payment:refund", "displayName": "Process Refunds"},
{"name": "payment:admin", "displayName": "Payment Administration"}
]Scope type assignment:
{
"clientId": "payment-api",
"scopeTypeId": "<TENANT_SCOPE_TYPE_ID>",
"tenantId": "acme-corp"
}
Expected Outcome
- Result: Four scopes created; Resource Server bound to tenant scope type
- Why: Authorization policies can now grant
payment:readto viewers,payment:createandpayment:refundto operators, andpayment:adminto administrators — all isolated within the Acme Corp tenant boundary.
Common Misunderstandings
-
"Scopes are permissions" — Scopes define what actions exist; permissions combine scopes with resources and policies to determine who can perform them.
-
"Scope types are OAuth scopes" — Scope types define organizational boundaries (tenant, organization, user). OAuth scopes are the
scopeparameter in token requests, which may reference Keymate scopes. -
"Higher scope type level means more permissions" — Scope type levels define breadth, not privilege. A
systemscope type resource is accessible across all tenants, but policies still control who can access it.
Deleting a scope type with assigned Resource Servers fails with a 409 Conflict error. Reassign clients to a different scope type before deletion.
Design Notes / Best Practices
-
Use resource-prefixed scopes for domain-specific actions (
order:cancel,user:suspend) to avoid naming collisions. -
Keep default scopes minimal — only auto-assign scopes that all applications genuinely need. Require explicit assignment for sensitive actions.
-
Match scope type to data boundaries — If data is tenant-isolated, use
scope-type-tenant. If data spans tenants, usescope-type-global. -
Enable audit selectively — Enable
isAuditEnabledfor scope types with compliance requirements (tenant, organization) and disable for high-volume system-level operations.
Use linkedResourcesCount before deleting scopes to assess impact. A scope with 50 linked resources requires careful migration planning.
Related Use Cases
- Defining CRUD scopes for REST API resources
- Configuring tenant-level authorization boundaries
- Implementing hierarchical organization permissions
- Setting up audit logging for compliance
Related Docs
Resource Model
Protected digital assets
Organization Model
Tenant and hierarchy concepts
Authorization Models
RBAC, ABAC, ReBAC policies
Token & Session
OAuth scope tokens
FAQ
Can I create custom scope types beyond the default seven?
Yes. Scope types are configurable entities, not fixed values. Create new scope types via the API with appropriate level and parentId values to extend the hierarchy.
What happens if I change a Resource Server's scope type?
Changing scope type affects the authorization boundary. Policies referencing the Resource Server's resources will evaluate within the new scope type context. Review policies after changing scope types.
How do scopes appear in OAuth tokens?
When a client requests a token with specific scopes, Keycloak includes granted scopes in the scope claim. The token's scopes are then checked against resource permissions during authorization.
Can I nest scope types with multiple parents?
No. Each scope type has a single parent (parentId), forming a strict tree hierarchy. Use tags or categories for cross-cutting classification needs.