Skip to main content

Resource Model

Summary

A Resource in Keymate represents any protected digital asset that requires authorization control. Resources can be REST API endpoints, files, database records, UI components, or any other system artifact. Keymate extends Keycloak's UMA 2.0 resource model with organizational metadata, lifecycle states, and classification capabilities through types, categories, and tags.

Why It Exists

Authorization systems need a structured way to represent "what" is being protected. Without a formal resource model:

  • Inconsistent protection — Different teams model the same API differently
  • No lifecycle tracking — No visibility into resource status (active, deprecated, inactive)
  • Missing context — Authorization decisions lack environmental and ownership context
  • Classification gaps — Resources cannot be grouped for bulk policy assignment

The Resource Model provides a standardized representation that enables consistent policy authoring, organizational classification, and lifecycle governance.

Where It Fits in Keymate

Resources belong to a Resource Server (a Keycloak Client with authorizationServicesEnabled=true). Each resource can have multiple Scopes defining permitted actions. Policies evaluate against resource-scope pairs to make authorization decisions.

Boundaries

This concept covers:

  • Resource entity structure and metadata fields
  • Resource Server relationship
  • Type and Category classification
  • Lifecycle states (ACTIVE, INACTIVE, DEPRECATED)
  • URI pattern matching
  • Tenant inheritance from Resource Server

This concept does not cover:

How It Works

Resource Server Relationship

Every resource belongs to a Resource Server, which is a Keycloak Client configured with:

  • serviceAccountsEnabled = true — enables Client Credentials Grant
  • authorizationServicesEnabled = true — enables UMA 2.0 resource management

When a Resource Server is created with a tenantId, all resources under it inherit that tenant association. This provides automatic tenant isolation without per-resource configuration.

Resource Entity Structure

FieldTypeDescription
idUUIDKeycloak-generated resource identifier
nameStringUnique identifier within Resource Server (e.g., /api/users/*)
displayNameStringHuman-readable name for admin UI and consent screens
urisArray of stringsURI patterns for request matching (supports wildcards)
typeStringFree-text resource type (e.g., "API", "FILE")
typeIdUUIDReference to ResourceType entity for formalized classification
categoryIdUUIDReference to ResourceCategory for business domain grouping
scopesArray of stringsActions permitted on this resource
statusEnumACTIVE, INACTIVE, or DEPRECATED
environmentEnumDEV, TEST, or PROD
ownerStringTeam or person responsible for this resource
tagsJSON ArrayFlexible keyword labels for filtering
ownerManagedAccessBooleanUMA 2.0 user-managed access flag

Classification System

Keymate provides three complementary classification mechanisms:

Resource Type — What kind of resource is it?

  • REST API, GraphQL API, gRPC Service, Database Table, File Storage, UI Component
  • Standardized types enable type-based filtering and reporting

Resource Category — What business domain does it belong to?

  • UI, UI_MENU_ITEM, DATA_OBJECT, URI
  • Categories group resources by functional area

Tags — Flexible keyword labeling

  • ["pci-compliant", "critical", "v2"]
  • Tags are auto-created when referenced — no pre-registration required

Lifecycle States

StatusBehavior
ACTIVENormal operation — authorization checks are performed
INACTIVETemporarily disabled — all access denied (403 Forbidden)
DEPRECATEDMarked for removal — new usage blocked, existing access may continue

URI Pattern Matching

Resources use URI patterns for request matching at Policy Enforcement Points:

/api/users/*           → Matches all paths under /api/users/
/api/users/{id} → Matches parameterized paths
/api/users/{id}/profile → Specific sub-resource

Multiple URIs can be assigned to a single resource to group related endpoints.

Diagram

Example Scenario

Scenario

A platform administrator creates a resource representing the payment transactions API, classifying it as a REST API in the UI category with PCI compliance tagging.

Input

  • Actor: Platform administrator
  • Resource Server: payment-api (tenant: Acme Corp)
  • Action: Create resource
  • Context:
    {
    "name": "/api/payments/transactions",
    "displayName": "Payment Transactions API",
    "uris": ["/api/payments/transactions", "/api/payments/transactions/*"],
    "typeId": "type-rest-api-uuid",
    "categoryId": "category-ui-uuid",
    "scopes": ["read", "create", "refund"],
    "status": "ACTIVE",
    "environment": "PROD",
    "owner": "payment-team@example.com",
    "tags": ["pci-compliant", "critical", "sla-99.9"]
    }

Expected Outcome

  • Result: Resource created with Keycloak UUID and extension metadata
  • Why: The resource is now available for policy assignment. Authorization requests to /api/payments/transactions/* will match this resource, and policies can evaluate based on its scopes, type, category, tags, and tenant association.

Common Misunderstandings

  • "Resources are the same as permissions" — Resources represent what is protected; permissions combine resources, scopes, and policies to determine who can access what.

  • "Each endpoint needs its own resource" — URI wildcards (/api/users/*) allow grouping related endpoints under a single resource. Create separate resources only when different scopes or policies apply.

  • "Status INACTIVE deletes the resource" — INACTIVE is a soft-disable; the resource remains in storage but authorization checks fail. Use DELETE to permanently remove.

warning

Resources inherit tenant association from their Resource Server. You cannot assign a resource to a different tenant than its parent Resource Server.

Design Notes / Best Practices

  • Use URI-based naming for API resources (e.g., /api/orders/{id}) to enable clear request-to-resource mapping at enforcement points.

  • Prefer wildcards over many resources when the same scopes and policies apply. /api/users/* is cleaner than separate resources for /api/users/list, /api/users/create, etc.

  • Tag for cross-cutting concerns — Use tags like pci-compliant, gdpr-relevant, or rate-limited for attributes that span multiple types and categories.

  • Lifecycle resources through environments — Create resources in DEV first, promote to TEST, then PROD. Use environment filtering for deployment-specific views.

tip

Auto-created tags simplify onboarding. Reference any tag in a resource creation request — if it does not exist, Keymate creates it automatically.

  • Defining API resources for microservice authorization
  • Classifying UI components for menu-level access control
  • Tagging resources for compliance reporting
  • Implementing multi-tenant resource isolation

FAQ

Can a resource belong to multiple Resource Servers?

No. Each resource belongs to exactly one Resource Server. If the same logical resource needs different policies in different contexts, create separate resources in each Resource Server.

How do I migrate resources between environments?

Export the resource definition from the source environment, update the environment field, and import into the target Resource Server. The resource ID will be newly generated in the target.

What happens to policies when I deprecate a resource?

Policies referencing the resource remain intact but no longer match requests. Review and update policies before or after deprecation to avoid unexpected authorization failures.

Can I use regex in URI patterns?

Keycloak supports simple wildcards (*) and path parameters ({id}), not full regex. For complex matching, use multiple URIs or implement custom matching logic at the enforcement point.