Skip to content
59 changes: 59 additions & 0 deletions docs/components/policy/obligations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Obligations

Obligations are policy constructs that enable conditional access enforcement at the Policy Enforcement Point (PEP) level. They define additional restrictions and requirements beyond basic attribute-based access control (ABAC), allowing security administrators to enforce conditions such as multi-factor authentication (MFA), watermarking, encryption, or time-based access controls.

## Composition

An obligation consists of three parts:

1. A Namespace
2. A Definition
3. A Value

Platform Policy Obligations can contain multiple Namespaces, each with multiple Definitions, and each Definition can have multiple Values.

Check failure on line 13 in docs/components/policy/obligations.md

View workflow job for this annotation

GitHub Actions / Vale

[vale] reported by reviewdog 🐶 [Vale.Spelling] Did you really mean 'Namespaces'? Raw Output: {"message": "[Vale.Spelling] Did you really mean 'Namespaces'?", "location": {"path": "docs/components/policy/obligations.md", "range": {"start": {"line": 13, "column": 50}}}, "severity": "ERROR"}

```mermaid
graph LR;
Namespace_A-->Definition_A;
Definition_A-->Value_A;
Definition_A-->Value_B;

Namespace_A-->Definition_B;
Definition_B-->Value_C;
Definition_B-->Value_D;
```

## Standard Obligations

Standard Obligations are enforced by the Access PDP (Policy Decision Point) when validating whether an Entity of a specified Category can perform an Action on a given Resource. These obligations must be satisfied for access to be granted.

A Standard Obligation includes:
- **Entity Category**: The type of entity (SUBJECT or ENVIRONMENT) that must satisfy this obligation
- **Action**: The specific action being performed (READ, STORE, CREATE, UPDATE, DELETE)
- **Resource Attribute Value**: The data attribute for which this obligation is scoped
- **Obligation Value**: The required obligation value that must be satisfied

### Examples of Standard Obligations:

#### Watermarking
Ensure document traceability:
- **Obligation**: `https://example.com/obl/drm/value/watermarking`
- **Applied to**: sensitive documents
- **Condition**: PEP must apply watermark

#### Prevent Download
Ensure persistent file protection (PFP):
- **Obligation**: `https://example.com/obl/drm/value/pfp`
- **Applied to**: sensitive documents
- **Condition**: PEP must not allow download

## FQN (Fully Qualified Name) Convention

Check failure on line 50 in docs/components/policy/obligations.md

View workflow job for this annotation

GitHub Actions / Vale

[vale] reported by reviewdog 🐶 [Vale.Terms] Use 'ECDSA' instead of 'FQN'. Raw Output: {"message": "[Vale.Terms] Use 'ECDSA' instead of 'FQN'.", "location": {"path": "docs/components/policy/obligations.md", "range": {"start": {"line": 50, "column": 4}}}, "severity": "ERROR"}

Obligations use a specific naming convention to distinguish them from attributes:

- **Obligation Definition**: `<namespace>/obl/<obligation_name>`
- **Obligation Value**: `<namespace>/obl/<obligation_name>/value/<obligation_value>`

For example:
- `https://example.com/obl/drm` (definition)
- `https://example.com/obl/drm/value/watermarking` (value)
55 changes: 52 additions & 3 deletions specs/authorization/v2/authorization.openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,25 @@ components:
title: resources
maxItems: 1000
minItems: 1
fulfillableObligationFqns:
type: array
items:
type: string
description: |+
if provided, fulfillable_obligation_fqns must be between 1 and 50 in count with all valid FQNs:
```
this.size() == 0 || (this.size() <= 50 && this.all(item, item.isUri()))
```

title: fulfillable_obligation_fqns
description: |+
obligations (fully qualified values) the requester is capable of fulfilling
i.e. https://<namespace>/obl/<definition name>/value/<value>
if provided, fulfillable_obligation_fqns must be between 1 and 50 in count with all valid FQNs:
```
this.size() == 0 || (this.size() <= 50 && this.all(item, item.isUri()))
```

title: GetDecisionMultiResourceRequest
required:
- entityIdentifier
Expand All @@ -306,6 +325,9 @@ components:
1. one entity reference (actor)
2. one action
3. multiple resources

If entitled, checks obligation policy: fulfillable obligations must satisfy all triggered.

Note: this is a more performant bulk request for multiple resource decisions, up to 1000 per request
action.name must be provided:
```
Expand Down Expand Up @@ -341,6 +363,25 @@ components:
resource:
title: resource
$ref: '#/components/schemas/authorization.v2.Resource'
fulfillableObligationFqns:
type: array
items:
type: string
description: |+
if provided, fulfillable_obligation_fqns must be between 1 and 50 in count with all valid FQNs:
```
this.size() == 0 || (this.size() <= 50 && this.all(item, item.isUri()))
```

title: fulfillable_obligation_fqns
description: |+
obligations (fully qualified values) the requester is capable of fulfilling
i.e. https://<namespace>/obl/<definition name>/value/<value>
if provided, fulfillable_obligation_fqns must be between 1 and 50 in count with all valid FQNs:
```
this.size() == 0 || (this.size() <= 50 && this.all(item, item.isUri()))
```

title: GetDecisionRequest
required:
- entityIdentifier
Expand All @@ -352,6 +393,8 @@ components:
1. one entity reference (actor)
2. one action
3. one resource

If entitled, checks obligation policy: fulfillable obligations must satisfy all triggered.
action.name must be provided:
```
has(this.action.name)
Expand All @@ -362,9 +405,7 @@ components:
properties:
decision:
title: decision
description: |-
decision on the resource optional list of obligations represented in URI format
repeated string obligations = 2;
description: decision on the resource
$ref: '#/components/schemas/authorization.v2.ResourceDecision'
title: GetDecisionResponse
additionalProperties: false
Expand Down Expand Up @@ -457,6 +498,14 @@ components:
title: decision
description: decision result
$ref: '#/components/schemas/authorization.v2.Decision'
requiredObligations:
type: array
items:
type: string
title: required_obligations
description: |-
obligations (fully qualified values) the PEP is required to fulfill on the given resource
i.e. https://<namespace>/obl/<definition name>/value/<value>
title: ResourceDecision
additionalProperties: false
common.Metadata:
Expand Down
100 changes: 100 additions & 0 deletions specs/policy/actions/actions.openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -665,6 +665,81 @@ components:
description: Keys for the namespace
title: Namespace
additionalProperties: false
policy.Obligation:
type: object
properties:
id:
type: string
title: id
namespace:
title: namespace
$ref: '#/components/schemas/policy.Namespace'
name:
type: string
title: name
values:
type: array
items:
$ref: '#/components/schemas/policy.ObligationValue'
title: values
fqn:
type: string
title: fqn
metadata:
title: metadata
$ref: '#/components/schemas/common.Metadata'
title: Obligation
additionalProperties: false
policy.ObligationTrigger:
type: object
properties:
id:
type: string
title: id
obligationValue:
title: obligation_value
$ref: '#/components/schemas/policy.ObligationValue'
action:
title: action
$ref: '#/components/schemas/policy.Action'
attributeValue:
title: attribute_value
$ref: '#/components/schemas/policy.Value'
context:
type: array
items:
$ref: '#/components/schemas/policy.RequestContext'
title: context
metadata:
title: metadata
$ref: '#/components/schemas/common.Metadata'
title: ObligationTrigger
additionalProperties: false
policy.ObligationValue:
type: object
properties:
id:
type: string
title: id
obligation:
title: obligation
$ref: '#/components/schemas/policy.Obligation'
value:
type: string
title: value
triggers:
type: array
items:
$ref: '#/components/schemas/policy.ObligationTrigger'
title: triggers
fqn:
type: string
title: fqn
metadata:
title: metadata
$ref: '#/components/schemas/common.Metadata'
title: ObligationValue
additionalProperties: false
policy.PageRequest:
type: object
properties:
Expand Down Expand Up @@ -707,6 +782,15 @@ components:
description: Total count of entire list
title: PageResponse
additionalProperties: false
policy.PolicyEnforcementPoint:
type: object
properties:
clientId:
type: string
title: client_id
minLength: 1
title: PolicyEnforcementPoint
additionalProperties: false
policy.PublicKey:
type: object
oneOf:
Expand Down Expand Up @@ -735,6 +819,17 @@ components:
title: PublicKey
additionalProperties: false
description: Deprecated
policy.RequestContext:
type: object
properties:
pep:
title: pep
$ref: '#/components/schemas/policy.PolicyEnforcementPoint'
title: RequestContext
required:
- pep
additionalProperties: false
description: Holds the context needed for obligation fulfillment
policy.ResourceMapping:
type: object
properties:
Expand Down Expand Up @@ -927,6 +1022,11 @@ components:
items:
$ref: '#/components/schemas/policy.ResourceMapping'
title: resource_mappings
obligations:
type: array
items:
$ref: '#/components/schemas/policy.Obligation'
title: obligations
metadata:
title: metadata
description: Common metadata
Expand Down
Loading