Skip to content
This repository has been archived by the owner on May 2, 2022. It is now read-only.

Commit

Permalink
Draft - Multi entity claims (#30)
Browse files Browse the repository at this point in the history
* Update contribution guidelines

* Add multi-entity attrs
  • Loading branch information
bleggett authored Jan 19, 2022
1 parent 5c574bc commit 9667172
Show file tree
Hide file tree
Showing 7 changed files with 263 additions and 51 deletions.
143 changes: 143 additions & 0 deletions api/entitlement-api.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
openapi: 3.0.2
info:
title: FastAPI
version: 0.1.0
paths:
/v1/claimsobject:
post:
summary: Request ClaimsObject
operationId: read_entity_attribute_relationship_v1_entity__entityId__claimsobject_post
requestBody:
$ref: "#/components/requestBodies/ClaimsRequest"
responses:
'200':
description: Successful Response
content:
application/json:
schema: {}
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
'404':
description: Entity Not Found Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
security:
- OAuth2AuthorizationCodeBearer: []
components:
schemas:
AttributeObject:
title: AttributeObject
required:
- attribute
type: object
properties:
attribute:
title: Attribute
maxLength: 2083
minLength: 1
type: string
format: uri
example:
attribute: https://eas.local/attr/ClassificationUS/value/Unclassified
ClaimsObject:
title: ClaimsObject
required:
- subjects
- client_public_signing_key
type: object
properties:
entities:
title: Entities (min. 1)
type: array
items:
$ref: '#/components/schemas/EntitlementObject'
client_public_signing_key:
title: Requesting Entity Public Signing Key
type: string
tdf_spec_version:
title: Version of the TDF spec this object maps to (optional)
type: string
EntitlementObject:
title: EntitlementObject
required:
- entity_identifier
- entity_attributes
type: object
properties:
entity_identifier:
title: Entity Identifier
type: string
entity_attributes:
title: Entity Attributes
type: array
items:
$ref: '#/components/schemas/AttributeObject'
HTTPValidationError:
title: HTTPValidationError
type: object
properties:
detail:
title: Detail
type: array
items:
$ref: '#/components/schemas/ValidationError'
ValidationError:
title: ValidationError
required:
- loc
- msg
- type
type: object
properties:
loc:
title: Location
type: array
items:
type: string
msg:
title: Message
type: string
type:
title: Error Type
type: string
requestBodies:
ClaimsRequest:
description: Claims request body
required: true
content:
application/json:
schema:
oneOf:
- type: object
required:
- primary_subject_id
- secondary_entity_ids
- client_public_signing_key
maxProperties: 3
properties:
primary_subject_id:
title: Primary entity ID entitlements are being fetched for (e.g. `sub` in JWT token)
type: string
secondary_entity_ids:
title: Secondary Entity Ids
description: Array of additional entities that EntitlementObjects should be fetched for.
type: array
items:
type: string
client_public_signing_key:
title: Requesting Client Public Signing Key
type: string
securitySchemes:
OAuth2AuthorizationCodeBearer:
type: oauth2
flows:
authorizationCode:
scopes: {}
authorizationUrl: ''
tokenUrl: ''
7 changes: 4 additions & 3 deletions protocol/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ This document describes the canonical system architecture used to encrypt and de

The canonical architecture contains four major components.

* *TDF Client* - Initiates and drives the TDF encryption and decryption workflows. Only component with access to the content (ciphertext or plaintext).
* *TDF Client* - Initiates and drives the TDF encryption and decryption workflows. Only component with access to the content (ciphertext or plaintext).
* May be entitled as Non-Person Entity acting on behalf of itself, OR on behalf of a Person Entity.
* *OpenID Connect (OIDC) Identity Provider (IdP)* - This system could be any OIDC IdP software. Virtru has chosen Keycloak as its reference implementation IdP.
* From Wikipedia: "Keycloak is an open source software product to allow single sign-on with Identity and Access Management aimed at modern applications and services. As of March 2018 this JBoss community project is under the stewardship of Red Hat. Keycloak is licensed under Apache 2.0."
* Any OIDC-compliant IdP software may be used, provided it supports custom claims, and can:
Expand All @@ -15,8 +16,8 @@ The canonical architecture contains four major components.
* Return the resulting Claims Object in the signed IdP JWT.
* A list of Certified OpenID Connect applications can be found at: https://openid.net/developers/certified/
* *Virtru Protocol Mapper* (PM) is Virtru's Keycloak-specific reference implementation of the above functionality.
* *Attribute Provider* (AP) - A web service that receives requests which contain information about the authenticated subject from an OIDC IdP with custom claims support (ex: Keycloak with Virtru Protocol Mapper), and returns custom TDF OIDC claims in response. It is the responsibility of Attribute Provider to transform incoming 3rd party IdP claims/metadata to a set of outgoing [Attribute Objects](../schema/AttributeObject.md). It returns a TDF [Claims Object](../schema/ClaimsObject.md).
* *Key Access Service* (KAS) - Responsible for authorizing and granting TDF Clients access to rewrapped data key material. If authorized, TDF Clients can use this rewrapped data key to decrypt TDF ciphertext. A valid OIDC token containing [TDF Claims](../schema/ClaimsObject.md) must be used as a bearer token when communicating with KAS. KAS will first verify the authenticity of the bearer token and then the policy claims within that bearer token. An otherwise valid and trusted OIDC token without valid TDF Claims will be rejected.
* *Attribute Provider* (AP) - A web service that receives requests which contain information about the authenticated entities from an OIDC IdP with custom claims support (ex: Keycloak with Virtru Protocol Mapper), and returns custom TDF OIDC claims in response. It is the responsibility of Attribute Provider to transform incoming 3rd party IdP claims/metadata to a set of outgoing [Attribute Objects](../schema/AttributeObject.md). It returns a TDF [Claims Object](../schema/ClaimsObject.md).
* *Key Access Service* (KAS) - Responsible for authorizing and granting TDF Clients access to rewrapped data key material. If authorized, TDF Clients (on behalf of themselves, or other entities) can use this rewrapped data key to decrypt TDF ciphertext. A valid OIDC token containing [TDF Claims](../schema/ClaimsObject.md) must be used as a bearer token when communicating with KAS. KAS will first verify the authenticity of the bearer token and then the policy claims within that bearer token. An otherwise valid and trusted OIDC token without valid TDF Claims will be rejected.

## Workflow

Expand Down
37 changes: 16 additions & 21 deletions schema/AttributeObject.md
Original file line number Diff line number Diff line change
@@ -1,46 +1,41 @@
# Attribute Object

## Summary
An Attribute Object contains attribute information the TDF3 system uses to enforce attribute-based access control (ABAC). Attributes are used in both the [PolicyObject](PolicyObject.md) to define the attributes that a subject "needs" to gain access in an ABAC sense, and in the [ClaimsObject](ClaimsObject.md) to assert the attributes that an actor "has".
Access decisions are made by comparing the attributes a subject has with the attributes a policy requires.
An Attribute Object contains attribute information the TDF3 system uses to enforce attribute-based access control (ABAC).

Attributes that a subject (or actor, or entity) "has" are referred to as "subject attributes".
Attributes are used in both the [Policy Object](PolicyObject.md) to define the attributes that an entity "needs" to gain access to data in an ABAC sense,
and in the [Entitlement Object](EntitlementObject.md) to assert the attributes that an entity "has".

Attributes that subjects "need" in order to access data are referred to as "object attributes".
Access decisions are made by comparing the attributes all entities have with the attributes a data policy requires.

The _attribute_ field must be both unique and immutable as it is the reference id for the attribute. All of the other fields are mutable. The attribute string contains three pieces of information - the authority namespace, the attribute name, and the attribute value.
Attributes that an entity (or actor, or subject) "has" are referred to as "entity entitlements" and are represented by [Entitlement Objects](EntitlementObject.md)

When encrypting, the client determines which attributes a subject must have in order to decrypt the payload and applies those attributes to the file's [Policy Object](PolicyObject.md).
Attributes that entities "need" in order to access data are referred to as "data attributes" and are represented by [Policy Objects](PolicyObject.md)

The set of all entity entitlements involved in a request are referred to as "claims" and are represented by a [Claims Object](ClaimsObject.md)

The _attribute_ field must be both globally unique and immutable as it is the reference id for the attribute.
All of the other fields are mutable. The attribute string contains three pieces of information - the authority namespace, the attribute name, and the attribute value.

When encrypting, the client determines which attributes an entity must have in order to decrypt the payload and applies those attributes to the file's [Policy Object](PolicyObject.md).

When a decrypt is requested, the KAS checks the [Policy Object](PolicyObject.md) against the [Claims Object](ClaimsObject.md) from the requesting client to
ensure the attributes that an entity "has" satisfies those that an entity "needs".

If this check succeeds, the KAS permits a decrypt operation and returns a valid key which the client can decrypt and use to expose the file contents.

The public key is used to wrap the object key or key splits on TDF3 file creation. On decrypt, the kasUrl defines where this key or key split can be rewrapped.

The AttributeObject alone does not define how the KAS will compare a subject attribute to an object attribute when making an access decision.
The KAS uses the namespaced object attributes in the [PolicyObject](PolicyObject.md) look up attribute policies from the cognizant authority
The AttributeObject alone does not define how the KAS will compare an entity's attribute to an object attribute when making an access decision.
The KAS uses the namespaced object attributes in the [Policy Object](PolicyObject.md) to look up attribute policies from the cognizant authority
to make its policy decisions. Clients writing policies should use best available information from their organizations to select which AttributeObjects to include to protect the policy.

## Example

```javascript
{
"attribute": "https://example.com/attr/classification/value/topsecret",
"isDefault": true,
"displayName": "classification",
"pubKey": "pem encoded public key of the attribute",
"kasUrl": "https://kas.example.com/",
"tdfVersion:": "x.y.z"
"attribute": "https://example.com/attr/classification/value/topsecret"
}
```

|Parameter|Type|Description|Required?|
|---|---|---|---|
|`attribute`|String|Also known as the "attribute url." The unique resource name for the attribute represented as a case-insensitive URL string. This field must be both unique and immutable as it is the reference id for the attribute. The attribute URL string contains three pieces of information - in the above example, the authority namespace (https://example.com), the attribute name (classification), and the attribute value (topsecret). |Yes|
|`isDefault`|Boolean|If "true" this flag identifies the attribute as the default attribute. If missing (preferred) or false then the attribute is not the default attribute.|No|
|`displayName`|String|A human-readable nickname for the attribute for convenience.|Yes|
|`pubKey`|PEM|PEM encoded public key for this attribute. Often other attributes will use the same pubKey.|Yes|
|`kasUrl`|URL|Base URL of a KAS that can make access control decisions for this attribute.|Yes|
|`tdf_spec_version`|String|Semver version number of the TDF spec.|No|
78 changes: 53 additions & 25 deletions schema/ClaimsObject.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,57 +2,85 @@

## What is this?

The Claims Object is a JSON object used to ensure that subjects
The Claims Object is a JSON object used to ensure that entities
attempting to decrypt an encrypted file under the Trusted Data Format
have all permissions required to do so.

The term `Subject` is a generic term that refers to both Person Entities (PE)
and Non-Person Entities (NPE). Subjects are also sometimes referred to as "actors"
The term `Entity` is a generic term that refers to both Person Entities (PE)
and Non-Person Entities (NPE). Entities are also sometimes referred to as "actors" or "subjects"
in ABAC systems.

Under this definition, *both* the human user attempting to authenticate, and the specific TDF client they are using to authenticate with would be classified as Entities - a PE and an NPE respectively.

## How does it work?

When a subject wishes to decrypt a file, the following steps using
the Claims Object are made:
When an entity (either on behalf of itself, or another entity) wishes to decrypt a file,
the following happens:

1. The TDF client requests an OIDC Bearer Token by first authenticating via the
1. The TDF client requests an OIDC Bearer Token (either on behalf of itself, or another entity)
by first authenticating via the
OpenID Connect (OIDC) Identity Provider (IdP) with Custom Claims
support (in this case Keycloak), and if subject authentication succeeds, a
support (in this case Keycloak), and if entity authentication succeeds, a
[TDF Claims Object](../schema/ClaimsObject.md) is obtained from
Attribute Provider and signed by the IdP. The signed OIDC Bearer Token is
returned to the client with the Claims Object inside. The Claims
Object contains [AttributeObjects](AttributeObject.md) the subject has
been entitled with.
returned to the client with the Claims Object inside.

The Claims Object contains one or more [Entitlement Objects](EntitlementObject.md) entitling all entities
involved in the authentication request.

2. The client requests a decrypt from the Key Access Server (KAS),
presenting the OIDC Bearer Token (containing the Claims Object) to the KAS.
The KAS ensures that the requestor has the correct permissions to access
the contents of the file by:
presenting the OIDC Bearer Token (containing the Claims Object) to the KAS.
The KAS ensures that all entities entitled in the OIDC bearer token have the
correct permissions to access the contents of the file by:

- Examining the validity of the OIDC Bearer Token signature.
- Validating that the Claims Object contains the client's public signing key.
- Validating that the request signature in the client payload can be validated
with the client's public signing key embedded in the OIDC Bearer Token
- Determining if the TDF Client has all the required Attributes and is on
the [Policy Object](PolicyObject.md).
- Determining if all the entities entitled in the presented bearer token have all the required Attributes,
according to PDP rules.

If these requirements are met, the KAS will permit a decrypt of the file.

## Example

```javascript
{
"subject_attributes": [
{"attribute": "https://example.com/attr/Classification/value/S", "displayName": "classification"},
{"attribute": "https://example.com/attr/COI/value/PRX", "displayName": "category of intent"}
"entitlements":[
{
"entity_identifier":"cliententityid-14443434-1111343434-asdfdffff",
"entity_attributes":[
{
"attribute":"https://example.com/attr/Classification/value/S",
"displayName":"classification"
},
{
"attribute":"https://example.com/attr/COI/value/PRX",
"displayName":"category of intent"
}
]
},
{
"entity_identifier":"dd-ff-eeeeee1134r34434-user-beta",
"entity_attributes":[
{
"attribute":"https://example.com/attr/Classification/value/U",
"displayName":"classification"
},
{
"attribute":"https://example.com/attr/COI/value/PRZ",
"displayName":"category of intent"
}
]
}
],
"client_public_signing_key": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy18Efi6+3vSELpbK58gC\nA9vJxZtoRHR604yi707h6nzTsTSNUg5mNzt/nWswWzloIWCgA7EPNpJy9lYn4h1Z\n6LhxEgf0wFcaux0/C19dC6WRPd6 ... XzNO4J38CoFz/\nwwIDAQAB\n-----END PUBLIC KEY-----",
"tdf_spec_version:": "x.y.z"
"client_public_signing_key":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy18Efi6+3vSELpbK58gC\nA9vJxZtoRHR604yi707h6nzTsTSNUg5mNzt/nWswWzloIWCgA7EPNpJy9lYn4h1Z\n6LhxEgf0wFcaux0/C19dC6WRPd6 ... XzNO4J38CoFz/\nwwIDAQAB\n-----END PUBLIC KEY-----",
"tdf_spec_version:":"x.y.z"
}
```

|Parameter|Type|Description|Required?|
|---|---|---|---|
|`subject_attributes`|Array|An array of [Attribute Objects](AttributeObject.md) that entitle the subject.
|`client_public_signing_key`|String|The TDF Client's public signing key, in a PEM-encoded format. |Yes|
|`tdf_spec_version`|String|Semver version number of the TDF spec.|No|
| Parameter | Type | Description | Required? |
|-----------------------------|--------|------------------------------------------------------------------------------------------------------------------------------------------|--------------------|
| `entitlements` | Array | An array of [Entitlement Objects](EntitlementObject.md) for each entity (PE or NPE) involved in the authentication request. | Yes |
| `client_public_signing_key` | String | The TDF Client's public signing key, in a PEM-encoded format. | Yes |
| `tdf_spec_version` | String | Semver version number of the TDF spec. | No |
Loading

0 comments on commit 9667172

Please sign in to comment.