-
Notifications
You must be signed in to change notification settings - Fork 1
JACAL Example 3 Self Service Profile Edit
This example models a very common application capability: allowing users to edit their own account profile while preventing them from editing profiles belonging to other users.
Typical examples include:
- updating personal information
- changing notification settings
- modifying contact information
- updating passwords or authentication preferences
From an authorization perspective this scenario illustrates one of the most fundamental attribute‑based authorization patterns:
subject‑resource identity matching.
Instead of checking a role such as admin or editor, the policy verifies that:
the user performing the operation is the same user who owns the resource being modified.
This pattern appears in nearly every identity‑based system and is therefore an excellent early example for understanding how ACAL models authorization logic.
The policy controls whether a subject may perform the action edit-profile on a resource representing a user profile.
Within core JACAL the authorization logic is expressed using:
- a top‑level Policy element
- a CombinerInput wrapper containing a Rule
- a Condition constructed from Apply, AttributeDesignator and Value expressions
The ACAL core schema requires the following properties on PolicyType:
PolicyIdVersionCombiningAlgId
and requires the following properties on RuleType:
IdEffect
The Target element is optional and not used in this example. All
decision logic is expressed directly in the rule condition.
This policy is evaluated by a JACAL-compliant PDP. The application server (PEP) constructs an authorization request containing the subject user identifier and the resource owner identifier before each profile-edit decision.
See JACAL-Architecture-and-Evaluation-Flow for the PEP/PDP/PIP interaction model and JACAL-Attribute-Sourcing for guidance on populating request attributes at runtime.
All attributes referenced in this policy use MustBePresent: true. If
the system cannot supply the subject's identity or the resource's
ownership metadata, the rule returns Indeterminate, which under
deny-unless-permit results in Deny.
This example uses attributes from three categories: Subject, Action, and Resource.
| Attribute | Datatype | Description |
|---|---|---|
| urn:example:jacal:identity:subject:user-id | string | Unique identifier for the authenticated user |
This attribute represents the identity of the user making the request.
| Attribute | Datatype | Expected Value |
|---|---|---|
| urn:oasis:names:tc:acal:1.0:action:action-id | string | edit-profile |
This attribute represents the operation the subject wants to perform.
| Attribute | Datatype | Description |
|---|---|---|
| urn:example:jacal:identity:resource:type | string | Identifies the resource as a user profile |
| urn:example:jacal:identity:resource:owner-id | string | Identifier of the user who owns the profile |
The resource owner identifier is the critical attribute used to determine authorization.
The policy permits profile editing only when all of the following conditions are true:
- the action is edit-profile
- the resource type is user-profile
- the subject user identifier matches the resource owner identifier
In other words:
subject.user-id == resource.owner-id
If this equality condition fails, the rule does not match and the request is denied.
Because the policy uses the deny‑unless‑permit combining algorithm, any request that does not satisfy the permit rule automatically results in Deny.
This ensures that users can edit only their own profiles.
{
"Policy": {
"PolicyId": "urn:example:jacal:policy:webapp-self-service-profile-edit",
"Version": "1.0",
"Description": "Permit editing of a user-profile resource only when the authenticated subject is the owner of that profile.",
"CombiningAlgId": "urn:oasis:names:tc:acal:1.0:combining-algorithm:deny-unless-permit",
"CombinerInput": [
{
"Rule": {
"Id": "PermitSelfProfileEdit",
"Description": "Permit profile editing only when the subject user identifier matches the resource owner identifier.",
"Effect": "Permit",
"Condition": {
"Apply": {
"FunctionId": "urn:oasis:names:tc:acal:1.0:function:and",
"Expression": [
{
"Apply": {
"FunctionId": "urn:oasis:names:tc:acal:1.0:function:string-equal",
"Expression": [
{
"AttributeDesignator": {
"Category": "urn:oasis:names:tc:acal:1.0:attribute-category:action",
"AttributeId": "urn:oasis:names:tc:acal:1.0:action:action-id",
"DataType": "urn:oasis:names:tc:acal:1.0:data-type:string",
"MustBePresent": true
}
},
{
"Value": "edit"
}
]
}
},
{
"Apply": {
"FunctionId": "urn:oasis:names:tc:acal:1.0:function:string-equal",
"Expression": [
{
"AttributeDesignator": {
"Category": "urn:oasis:names:tc:acal:1.0:attribute-category:resource",
"AttributeId": "urn:example:jacal:webapp:resource:type",
"DataType": "urn:oasis:names:tc:acal:1.0:data-type:string",
"MustBePresent": true
}
},
{
"Value": "user-profile"
}
]
}
},
{
"Apply": {
"FunctionId": "urn:oasis:names:tc:acal:1.0:function:string-equal",
"Expression": [
{
"AttributeDesignator": {
"Category": "urn:oasis:names:tc:acal:1.0:subject-category:access-subject",
"AttributeId": "urn:example:jacal:webapp:subject:user-id",
"DataType": "urn:oasis:names:tc:acal:1.0:data-type:string",
"MustBePresent": true
}
},
{
"AttributeDesignator": {
"Category": "urn:oasis:names:tc:acal:1.0:attribute-category:resource",
"AttributeId": "urn:example:jacal:webapp:resource:owner-id",
"DataType": "urn:oasis:names:tc:acal:1.0:data-type:string",
"MustBePresent": true
}
}
]
}
}
]
}
}
}
}
]
}
}The policy remains fully within core JACAL and uses:
- the root
Policywrapper - required
PolicyTypeproperties - a
CombinerInputwrapper containing the rule - a rule
Conditionexpressed throughApply,AttributeDesignatorandValue
No profiles or short identifiers are required.
- subject user-id = user123
- action id = edit-profile
- resource type = user-profile
- resource owner-id = user123
Result:
Permit.
The subject identifier matches the resource owner identifier, so the equality predicate evaluates true and the permit rule matches.
Under deny‑unless‑permit, the final result is Permit.
- subject user-id = user123
- action id = edit-profile
- resource type = user-profile
- resource owner-id = user789
Result:
Deny.
The equality comparison fails because the subject and resource identifiers differ. The permit rule does not match.
Under deny‑unless‑permit, the final result is Deny.
- subject user-id = user123
- action id = delete-account
- resource type = user-profile
- resource owner-id = user123
Result:
Deny.
The action comparison fails, so the permit rule does not match.
- resource owner-id attribute absent
- other attributes present and otherwise matching
Result:
The rule evaluates Indeterminate because the owner identifier is
referenced with MustBePresent: true.
Under deny‑unless‑permit, the final decision becomes Deny.
This behavior prevents profile modification when ownership information cannot be established.
This example illustrates a key ABAC capability: comparing attributes from two different categories.
The equality check compares:
subject.user-id
resource.owner-id
This pattern is extremely common in systems where resources are owned by individual users.
Identity attributes such as user-id and owner-id are typically
single‑valued attributes.
Because of this, the string-equal comparison function is usually safe
and will not encounter bag‑cardinality problems.
In contrast, attributes such as roles or scopes often contain multiple values and require bag‑aware functions.
For this policy to function securely, the subject identity must come from a trusted authentication system.
The PEP should not rely on user‑supplied identifiers in request payloads. Instead, identity attributes should be populated from a verified authentication context such as:
- a session identity record
- a signed authentication token
- an identity provider assertion
This example demonstrates one of the most widely used ABAC authorization patterns:
identity equality between the subject and the resource owner.
The example illustrates:
- attribute‑to‑attribute comparison
- identity‑based authorization decisions
- rule evaluation under
deny‑unless‑permit - safe handling of missing attributes through
MustBePresent
This pattern forms the foundation for many real‑world capabilities including:
- user profile management
- personal data editing
- account preference updates
Understanding this pattern is essential for designing secure identity‑centric authorization systems.
- Introduction
- Architecture and Evaluation Flow
- Patterns and Pitfalls
- Requests and Responses
- Authoring Your First Policy