# Residual Policy Negotiation
## Step-up Request Response
### Request
Initial request by PEP without any indications of which residual policy types are supported.
```
{
"subject": {
"type": "user",
"id": "alice@the-smiths.com"
},
"action": "read",
"context": {},
"resource": {
"type": "docs"
}
}
```
### Response
Denial which includes the supported residual policy content types the PEP must support.
```
{
"decision": false,
"context": {
"step-up": {
"type": "residual-policy-accept",
"content-types": [ "application/x-fhir-query", "application/vnd.odrl+turtle"]
}
}
}
```
## Stepped-up Request Response
### Request
A request which indicates the supported types of residual policies.
```
{
"subject": {
"type": "user",
"id": "alice@the-smiths.com"
},
"action": "read",
"context": {
"residual-policy-accept": [ "application/x-fhir-query", "application/vnd.odrl+turtle" ]
},
"resource": {
"type": "docs"
}
}
```
### Response
A positive decision which includes residual policies in the context.
```
{
"decision": true,
"context": {
"residual-policies": [
{
"content-type": "application/x-fhir-query?version=2&features=jwt,moment",
"content": "Practitioner?_has:PractitionerRole:practitioner:role=http://terminology.hl7.org/CodeSystem/practitioner-role|doctor"
},
{
"content-type": "application/vnd.odrl+turtle",
"location": "http://example.com/service-grants/odrl-policy.turtle"
},
]
}
}
```
## Built-in partial evaluation
The following request-response flows describe how partial evaluation and residual policy negotiation would work if they are first-class citizens in AuthZEN
### Request
Inital request without any residual policy acceptance types.
```
{
"subject": {
"type": "user",
"id": "alice@the-smiths.com"
},
"action": "read",
"resource": {
"type": "docs"
}
}
```
### Response
A partial decision is returned with its residual policies. If not all residual policies can be enforced the request *MUST* be denied be the PEP.
```
{
"decision":{
"result": "partial",
"residual": [
{
"content-type": "application/vnd.authzen.composite+json",
"content": {
"or": [
{
"content-type": "application/vnd.rego",
"content": "package partial.object.document\n\nallow {\n\t"Joe Bloggs" = document.ownerName\n\tdocument.classificationLevel <= 1\n}\n\ndefault allow = false"
},
{
"and" : [
{
"content-type": "application/scim.filter",
"content": "document.ownerName co \"Joe Bloggs\""
},
{
"content-type": "application/scim.filter",
"content": "document.ownerName lte 1"
}
]
},
{
"content-type": "application/prs.berger.vladi+json",
"content": {
"filter": {
"or": [
{
"and": [
{
"document.ownerName": {
"eq": "Joe Bloggs"
}
},
{
"document.classificationLevel": {
"lte": 1
}
}
]
}
]
}
}
}
]
}
}
]
}
}
```
## Specify accept types to reduce overhead
Clienst *MAY* specify supported types of residual policies to optimize the flow and not receive unneccesary policy information.
### Request
The request specifies the accepted policy types.
```
{
"subject": {
"type": "user",
"id": "alice@the-smiths.com"
},
"action": "read",
"resource": {
"type": "docs"
},
"context": {
"residual-policy-accept": ["application/scim.filter"]
}
}
```
### Response
The response returns a simplified residual policy including only the relevant residual policy content type.
```
{
"decision":{
"result": "partial",
"residual": [
{
"content-type": "application/scim.filter",
"content": "document.ownerName co \"Joe Bloggs\""
},
{
"content-type": "application/scim.filter",
"content": "document.ownerName lte 1"
}
]
}
}
```
## Denial of unsupported policy types
If the required policy types aren't accepted the request *MAY* be immediately denied.
### Request
```
{
"subject": {
"type": "user",
"id": "alice@the-smiths.com"
},
"action": "read",
"resource": {
"type": "docs"
},
"context": {
"residual-policy-accept": ["application/vnd.odrl+turtle"]
}
}
```
### Response
```
{
"decision": false
}
```