-
Notifications
You must be signed in to change notification settings - Fork 1
JACAL Example 9 AI Agent Tool Invocation
This example models a modern authorization scenario: controlling how AI agents interact with external services.
Many AI systems now rely on external APIs, tools, and data providers to complete tasks. Examples include:
- calling web search APIs
- invoking payment systems
- retrieving knowledge from external databases
- interacting with third‑party SaaS platforms
These integrations introduce new governance risks. AI agents must be permitted to call only approved services and only when the risk level of the action falls within an authorized threshold.
This example demonstrates two important ABAC modeling patterns:
- external service approval attributes
- numeric risk-threshold comparisons
The policy controls whether an AI agent may perform the action invoke-service on a resource representing an external service endpoint.
Within core JACAL, the authorization logic is expressed using:
- a top-level Policy element
- a CombinerInput wrapper containing a Rule
- a Condition built from Apply, AttributeDesignator, and Value expressions
The ACAL schema requires:
PolicyIdVersionCombiningAlgId
for PolicyType, and requires:
IdEffect
for RuleType.
The optional Target element is not used in this example.
This policy is evaluated by a JACAL-compliant PDP. The AI runtime or orchestration layer (PEP) constructs an authorization request containing agent identity, risk tolerance, and target service classification before each tool invocation 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 runtime cannot establish the agent's risk tolerance or the service's
classification, 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:ai-agent:subject:agent-id | string | Identifier for the AI agent |
| urn:example:jacal:ai-agent:subject:max-risk-level | integer | Maximum permitted risk level for the agent |
These attributes describe the operational risk tolerance of the AI agent.
| Attribute | Datatype | Expected Value |
|---|---|---|
| urn:oasis:names:tc:acal:1.0:action:action-id | string | invoke-service |
This attribute represents the invocation of an external service.
| Attribute | Datatype | Description |
|---|---|---|
| urn:example:jacal:ai-agent:resource:type | string | Identifies the resource as an external service |
| urn:example:jacal:ai-agent:resource:service-id | string | Identifier for the external service |
| urn:example:jacal:ai-agent:resource:service-risk-level | integer | Risk classification of the external service |
| urn:example:jacal:ai-agent:resource:approval-status | string | Approval state of the service |
The approval-status attribute ensures the agent can only invoke approved services.
The policy permits service invocation only when all of the following conditions are true:
- the action is invoke-service
- the resource type is external-service
- the resource approval-status is approved
- the agent's maximum permitted risk level is greater than or equal to the service risk level
In other words:
subject.max-risk-level ≥ resource.service-risk-level
Any request that fails these conditions does not match the permit rule and is denied.
Because the policy uses the deny-unless-permit combining algorithm, unmatched requests result in Deny.
{
"Policy": {
"PolicyId": "urn:example:jacal:policy:ai-agent-approved-external-service-invocation",
"Version": "1.0",
"Description": "Permit invocation of an external service only when the subject is an AI agent, the service vendor is approved, and the service risk and data-classification levels do not exceed the agent's authorized limits.",
"CombiningAlgId": "urn:oasis:names:tc:acal:1.0:combining-algorithm:deny-unless-permit",
"CombinerInput": [
{
"Rule": {
"Id": "PermitApprovedExternalServiceInvocationWithinAuthorizedLimits",
"Description": "Permit tool invocation only when the service is approved and its risk and data-classification levels are within the AI agent's authorized limits.",
"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",
"MustBePresent": true
}
},
{
"Value": "invoke-tool"
}
]
}
},
{
"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:ai-agent:resource:type",
"MustBePresent": true
}
},
{
"Value": "external-service"
}
]
}
},
{
"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:ai-agent:subject:role",
"MustBePresent": true
}
},
{
"Value": "ai-agent"
}
]
}
},
{
"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:ai-agent:resource:vendor-approval-status",
"MustBePresent": true
}
},
{
"Value": "approved"
}
]
}
},
{
"Apply": {
"FunctionId": "urn:oasis:names:tc:acal:1.0:function:integer-greater-than-or-equal",
"Expression": [
{
"AttributeDesignator": {
"Category": "urn:oasis:names:tc:acal:1.0:subject-category:access-subject",
"AttributeId": "urn:example:jacal:ai-agent:subject:tool-risk-limit",
"MustBePresent": true
}
},
{
"AttributeDesignator": {
"Category": "urn:oasis:names:tc:acal:1.0:attribute-category:resource",
"AttributeId": "urn:example:jacal:ai-agent:resource:tool-risk-level",
"MustBePresent": true
}
}
]
}
},
{
"Apply": {
"FunctionId": "urn:oasis:names:tc:acal:1.0:function:integer-greater-than-or-equal",
"Expression": [
{
"AttributeDesignator": {
"Category": "urn:oasis:names:tc:acal:1.0:subject-category:access-subject",
"AttributeId": "urn:example:jacal:ai-agent:subject:data-clearance-level",
"MustBePresent": true
}
},
{
"AttributeDesignator": {
"Category": "urn:oasis:names:tc:acal:1.0:attribute-category:resource",
"AttributeId": "urn:example:jacal:ai-agent:resource:data-classification-level",
"MustBePresent": true
}
}
]
}
}
]
}
}
}
}
]
}
}The policy remains fully compliant with core JACAL.
It uses:
- the root
Policywrapper - required
PolicyTypeproperties - a
CombinerInputwrapper containing the rule - rule logic expressed using
Apply,AttributeDesignator, andValueexpressions
No profiles or short identifiers are required.
- subject agent-id = agent42
- subject max-risk-level = 5
- action id = invoke-service
- resource type = external-service
- resource service-id = payments-api
- resource service-risk-level = 3
- resource approval-status = approved
Result:
Permit.
The service is approved and the risk comparison evaluates true:
5 ≥ 3
Under deny-unless-permit, the final result is Permit.
- subject max-risk-level = 5
- resource service-risk-level = 3
- resource approval-status = pending
Result:
Deny.
The approval status comparison fails, preventing the permit rule from matching.
- subject max-risk-level = 3
- resource service-risk-level = 5
- resource approval-status = approved
Result:
Deny.
The risk comparison fails because the service risk exceeds the agent's authorized risk threshold.
- resource service-risk-level attribute absent
- other attributes present and otherwise matching
Result:
The rule evaluates Indeterminate because the risk attribute is
referenced with MustBePresent: true.
Under deny-unless-permit, the final decision becomes Deny.
AI agents should operate under explicit governance controls to prevent uncontrolled access to external services.
Policies like this allow organizations to:
- restrict which services agents may call
- limit risk exposure
- enforce approval processes for integrations
This example uses numeric comparison to enforce risk thresholds.
integer-greater-than-or-equal(max-risk-level, service-risk-level)
This ensures that agents cannot invoke services classified above their permitted risk level.
External service metadata such as approval status and risk classification should originate from a trusted service registry.
The registry acts as the authoritative source describing service trustworthiness.
This example demonstrates how ACAL can govern AI agent behavior when interacting with external systems.
Key concepts illustrated include:
- external service approval attributes
- risk-based authorization thresholds
- numeric comparison functions
- safe evaluation under
deny-unless-permit
This pattern is increasingly important as AI systems become more capable and autonomous in their interactions with external services.
- Introduction
- Architecture and Evaluation Flow
- Patterns and Pitfalls
- Requests and Responses
- Authoring Your First Policy