Skip to content

Commit d5ff87d

Browse files
authored
Merge pull request #2422 from beyonnex-io/feature/transitive-policy-imports
Add transitiveImports for selective multi-level policy import resolution
2 parents adf4e2b + db77eb4 commit d5ff87d

43 files changed

Lines changed: 3444 additions & 55 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

documentation/src/main/resources/jsonschema/policy.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,15 @@
5757
}
5858
}
5959
}
60+
},
61+
"transitiveImports": {
62+
"title": "Transitive imports",
63+
"type": "array",
64+
"description": "List of policy IDs from the imported policy's own imports that should be resolved transitively before extracting entries. This enables multi-level import chains where a template policy defines resources and an intermediate policy adds subjects via entriesAdditions.",
65+
"items": {
66+
"type": "string",
67+
"description": "Policy ID of a policy that the imported policy itself imports from."
68+
}
6069
}
6170
}
6271
}

documentation/src/main/resources/openapi/ditto-api-2.yml

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7618,6 +7618,141 @@ paths:
76187618
$ref: '#/components/schemas/AdvancedError'
76197619
'412':
76207620
$ref: '#/components/responses/PreconditionFailed'
7621+
'/api/2/policies/{policyId}/imports/{importedPolicyId}/transitiveImports':
7622+
get:
7623+
summary: Retrieve the transitive resolution policy IDs of a specific policy import
7624+
description: |-
7625+
Returns the "transitiveImports" array of the policy import identified by the `policyId` path
7626+
parameter and the `importedPolicyId` path parameter.
7627+
7628+
The array lists policy IDs from the imported policy's own imports that should be resolved
7629+
transitively before extracting entries. This enables multi-level import chains.
7630+
tags:
7631+
- Policies
7632+
parameters:
7633+
- $ref: '#/components/parameters/PolicyIdPathParam'
7634+
- $ref: '#/components/parameters/ImportedPolicyIdPathParam'
7635+
- $ref: '#/components/parameters/IfMatchHeaderParamHash'
7636+
- $ref: '#/components/parameters/IfNoneMatchHeaderParam'
7637+
- $ref: '#/components/parameters/TimeoutParam'
7638+
responses:
7639+
'200':
7640+
description: The request successfully returned. The transitiveImports array is returned.
7641+
headers:
7642+
ETag:
7643+
description: |-
7644+
The (current server-side) ETag for this (sub-)resource. For top-level resources it is in the format
7645+
"rev:[revision]", for sub-resources it has the format "hash:[calculated-hash]".
7646+
schema:
7647+
type: string
7648+
content:
7649+
application/json:
7650+
schema:
7651+
$ref: '#/components/schemas/TransitiveImports'
7652+
'304':
7653+
$ref: '#/components/responses/NotModified'
7654+
'400':
7655+
description: |-
7656+
The request could not be completed. Possible reasons:
7657+
7658+
* the `policyId` or the `importedPolicyId` does not conform to the namespaced entity ID notation (see [Ditto documentation on namespaced entity IDs](https://www.eclipse.dev/ditto/basic-namespaces-and-names.html#namespaced-id))
7659+
content:
7660+
application/json:
7661+
schema:
7662+
$ref: '#/components/schemas/AdvancedError'
7663+
'401':
7664+
description: The request could not be completed due to missing authentication.
7665+
content:
7666+
application/json:
7667+
schema:
7668+
$ref: '#/components/schemas/AdvancedError'
7669+
'404':
7670+
description: |-
7671+
The request could not be completed. The policy with the given ID or
7672+
the policy import was not found in the context of the authenticated
7673+
user.
7674+
content:
7675+
application/json:
7676+
schema:
7677+
$ref: '#/components/schemas/AdvancedError'
7678+
'412':
7679+
$ref: '#/components/responses/PreconditionFailed'
7680+
put:
7681+
summary: Modify the transitive resolution policy IDs of a specific policy import
7682+
description: |-
7683+
Modify the "transitiveImports" array of the policy import identified by the `policyId` path
7684+
parameter and the `importedPolicyId` path parameter.
7685+
7686+
The array lists policy IDs from the imported policy's own imports that should be resolved
7687+
transitively before extracting entries.
7688+
tags:
7689+
- Policies
7690+
parameters:
7691+
- $ref: '#/components/parameters/PolicyIdPathParam'
7692+
- $ref: '#/components/parameters/ImportedPolicyIdPathParam'
7693+
- $ref: '#/components/parameters/IfMatchHeaderParamHash'
7694+
- $ref: '#/components/parameters/IfNoneMatchHeaderParam'
7695+
- $ref: '#/components/parameters/IfEqualHeaderParam'
7696+
- $ref: '#/components/parameters/TimeoutParam'
7697+
- $ref: '#/components/parameters/ResponseRequiredParam'
7698+
responses:
7699+
'204':
7700+
description: The transitiveImports array was successfully updated.
7701+
headers:
7702+
ETag:
7703+
description: |-
7704+
The (current server-side) ETag for this (sub-)resource. For top-level resources it is in the format
7705+
"rev:[revision]", for sub-resources it has the format "hash:[calculated-hash]".
7706+
schema:
7707+
type: string
7708+
'400':
7709+
description: |-
7710+
The request could not be completed. Possible reasons:
7711+
7712+
* the `policyId` or the `importedPolicyId` does not conform to the namespaced entity ID notation (see [Ditto documentation on namespaced entity IDs](https://www.eclipse.dev/ditto/basic-namespaces-and-names.html#namespaced-id))
7713+
* the JSON body is not a valid JSON array of policy ID strings
7714+
content:
7715+
application/json:
7716+
schema:
7717+
$ref: '#/components/schemas/AdvancedError'
7718+
'401':
7719+
description: The request could not be completed due to missing authentication.
7720+
content:
7721+
application/json:
7722+
schema:
7723+
$ref: '#/components/schemas/AdvancedError'
7724+
'403':
7725+
description: |-
7726+
The request could not be completed. Possible reasons:
7727+
* the caller has insufficient permissions.
7728+
You need `WRITE` permission on the `policy:/imports/{importedPolicyId}` resource,
7729+
without any revoke in a deeper path of the policy resource.
7730+
content:
7731+
application/json:
7732+
schema:
7733+
$ref: '#/components/schemas/AdvancedError'
7734+
'404':
7735+
description: |-
7736+
The request could not be completed. The policy with the given ID or
7737+
the policy import was not found in the context of the authenticated
7738+
user.
7739+
content:
7740+
application/json:
7741+
schema:
7742+
$ref: '#/components/schemas/AdvancedError'
7743+
'412':
7744+
$ref: '#/components/responses/PreconditionFailed'
7745+
'413':
7746+
$ref: '#/components/responses/EntityTooLarge'
7747+
requestBody:
7748+
content:
7749+
application/json:
7750+
schema:
7751+
$ref: '#/components/schemas/TransitiveImports'
7752+
example:
7753+
- 'org.eclipse.ditto:policy-template'
7754+
description: JSON array of policy IDs to resolve transitively.
7755+
required: true
76217756
'/api/2/policies/{policyId}/importsAliases':
76227757
get:
76237758
summary: Retrieve all imports aliases of a policy
@@ -11071,6 +11206,10 @@ components:
1107111206
properties:
1107211207
entries:
1107311208
$ref: '#/components/schemas/PolicyEntries'
11209+
imports:
11210+
$ref: '#/components/schemas/PolicyImports'
11211+
importsAliases:
11212+
$ref: '#/components/schemas/ImportsAliases'
1107411213
required:
1107511214
- entries
1107611215
Policy:
@@ -11084,6 +11223,8 @@ components:
1108411223
$ref: '#/components/schemas/PolicyEntries'
1108511224
imports:
1108611225
$ref: '#/components/schemas/PolicyImports'
11226+
importsAliases:
11227+
$ref: '#/components/schemas/ImportsAliases'
1108711228
required:
1108811229
- policyId
1108911230
- entries
@@ -11120,6 +11261,8 @@ components:
1112011261
description: Label of a policy entry to import from the referenced policy.
1112111262
entriesAdditions:
1112211263
$ref: '#/components/schemas/EntriesAdditions'
11264+
transitiveImports:
11265+
$ref: '#/components/schemas/TransitiveImports'
1112311266
example:
1112411267
entries:
1112511268
- default
@@ -11323,6 +11466,20 @@ components:
1132311466
grant:
1132411467
- READ
1132511468
revoke: []
11469+
TransitiveImports:
11470+
type: array
11471+
description: |-
11472+
List of policy IDs from the imported policy's own imports that should be resolved transitively
11473+
before extracting entries. This enables multi-level import chains where a template policy defines
11474+
resources and an intermediate policy adds subjects via "entriesAdditions".
11475+
11476+
Each entry is the policy ID of a policy that the directly imported policy itself imports from.
11477+
Only the listed policy IDs are resolved — this is an explicit whitelist, not a recursive flag.
11478+
items:
11479+
type: string
11480+
description: Policy ID of a policy that the imported policy itself imports from.
11481+
example:
11482+
- 'org.eclipse.ditto:policy-template'
1132611483
ImportsAliases:
1132711484
type: object
1132811485
description: |-

documentation/src/main/resources/openapi/sources/api-2-index.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,8 @@ paths:
145145
$ref: "./paths/policies/entriesAdditions.yml"
146146
'/api/2/policies/{policyId}/imports/{importedPolicyId}/entriesAdditions/{label}':
147147
$ref: "./paths/policies/entryAddition.yml"
148+
'/api/2/policies/{policyId}/imports/{importedPolicyId}/transitiveImports':
149+
$ref: "./paths/policies/transitiveImports.yml"
148150
'/api/2/policies/{policyId}/importsAliases':
149151
$ref: "./paths/policies/importsAliases.yml"
150152
'/api/2/policies/{policyId}/importsAliases/{label}':
@@ -443,6 +445,8 @@ components:
443445
$ref: "./schemas/policies/entriesAdditions.yml"
444446
EntryAddition:
445447
$ref: "./schemas/policies/entryAddition.yml"
448+
TransitiveImports:
449+
$ref: "./schemas/policies/transitiveImports.yml"
446450
ImportsAliases:
447451
$ref: "./schemas/policies/importsAliases.yml"
448452
ImportsAlias:
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
# Copyright (c) 2026 Contributors to the Eclipse Foundation
2+
#
3+
# See the NOTICE file(s) distributed with this work for additional
4+
# information regarding copyright ownership.
5+
#
6+
# This program and the accompanying materials are made available under the
7+
# terms of the Eclipse Public License 2.0 which is available at
8+
# http://www.eclipse.org/legal/epl-2.0
9+
#
10+
# SPDX-License-Identifier: EPL-2.0
11+
get:
12+
summary: Retrieve the transitive resolution policy IDs of a specific policy import
13+
description: |-
14+
Returns the "transitiveImports" array of the policy import identified by the `policyId` path
15+
parameter and the `importedPolicyId` path parameter.
16+
17+
The array lists policy IDs from the imported policy's own imports that should be resolved
18+
transitively before extracting entries. This enables multi-level import chains.
19+
tags:
20+
- Policies
21+
parameters:
22+
- $ref: '../../parameters/policyIdPathParam.yml'
23+
- $ref: '../../parameters/importedPolicyIdPathParam.yml'
24+
- $ref: '../../parameters/ifMatchHeaderParamHash.yml'
25+
- $ref: '../../parameters/ifNoneMatchHeaderParam.yml'
26+
- $ref: '../../parameters/timeoutParam.yml'
27+
responses:
28+
'200':
29+
description: The request successfully returned. The transitiveImports array is returned.
30+
headers:
31+
ETag:
32+
description: |-
33+
The (current server-side) ETag for this (sub-)resource. For top-level resources it is in the format
34+
"rev:[revision]", for sub-resources it has the format "hash:[calculated-hash]".
35+
schema:
36+
type: string
37+
content:
38+
application/json:
39+
schema:
40+
$ref: '../../schemas/policies/transitiveImports.yml'
41+
'304':
42+
$ref: '../../responses/notModified.yml'
43+
'400':
44+
description: |-
45+
The request could not be completed. Possible reasons:
46+
47+
* the `policyId` or the `importedPolicyId` does not conform to the namespaced entity ID notation (see [Ditto documentation on namespaced entity IDs](https://www.eclipse.dev/ditto/basic-namespaces-and-names.html#namespaced-id))
48+
content:
49+
application/json:
50+
schema:
51+
$ref: '../../schemas/errors/advancedError.yml'
52+
'401':
53+
description: The request could not be completed due to missing authentication.
54+
content:
55+
application/json:
56+
schema:
57+
$ref: '../../schemas/errors/advancedError.yml'
58+
'404':
59+
description: |-
60+
The request could not be completed. The policy with the given ID or
61+
the policy import was not found in the context of the authenticated
62+
user.
63+
content:
64+
application/json:
65+
schema:
66+
$ref: '../../schemas/errors/advancedError.yml'
67+
'412':
68+
$ref: '../../responses/preconditionFailed.yml'
69+
put:
70+
summary: Modify the transitive resolution policy IDs of a specific policy import
71+
description: |-
72+
Modify the "transitiveImports" array of the policy import identified by the `policyId` path
73+
parameter and the `importedPolicyId` path parameter.
74+
75+
The array lists policy IDs from the imported policy's own imports that should be resolved
76+
transitively before extracting entries.
77+
tags:
78+
- Policies
79+
parameters:
80+
- $ref: '../../parameters/policyIdPathParam.yml'
81+
- $ref: '../../parameters/importedPolicyIdPathParam.yml'
82+
- $ref: '../../parameters/ifMatchHeaderParamHash.yml'
83+
- $ref: '../../parameters/ifNoneMatchHeaderParam.yml'
84+
- $ref: '../../parameters/ifEqualHeaderParam.yml'
85+
- $ref: '../../parameters/timeoutParam.yml'
86+
- $ref: '../../parameters/responseRequiredParam.yml'
87+
responses:
88+
'204':
89+
description: The transitiveImports array was successfully updated.
90+
headers:
91+
ETag:
92+
description: |-
93+
The (current server-side) ETag for this (sub-)resource. For top-level resources it is in the format
94+
"rev:[revision]", for sub-resources it has the format "hash:[calculated-hash]".
95+
schema:
96+
type: string
97+
'400':
98+
description: |-
99+
The request could not be completed. Possible reasons:
100+
101+
* the `policyId` or the `importedPolicyId` does not conform to the namespaced entity ID notation (see [Ditto documentation on namespaced entity IDs](https://www.eclipse.dev/ditto/basic-namespaces-and-names.html#namespaced-id))
102+
* the JSON body is not a valid JSON array of policy ID strings
103+
content:
104+
application/json:
105+
schema:
106+
$ref: '../../schemas/errors/advancedError.yml'
107+
'401':
108+
description: The request could not be completed due to missing authentication.
109+
content:
110+
application/json:
111+
schema:
112+
$ref: '../../schemas/errors/advancedError.yml'
113+
'403':
114+
description: |-
115+
The request could not be completed. Possible reasons:
116+
* the caller has insufficient permissions.
117+
You need `WRITE` permission on the `policy:/imports/{importedPolicyId}` resource,
118+
without any revoke in a deeper path of the policy resource.
119+
content:
120+
application/json:
121+
schema:
122+
$ref: '../../schemas/errors/advancedError.yml'
123+
'404':
124+
description: |-
125+
The request could not be completed. The policy with the given ID or
126+
the policy import was not found in the context of the authenticated
127+
user.
128+
content:
129+
application/json:
130+
schema:
131+
$ref: '../../schemas/errors/advancedError.yml'
132+
'412':
133+
$ref: '../../responses/preconditionFailed.yml'
134+
'413':
135+
$ref: '../../responses/entityTooLarge.yml'
136+
requestBody:
137+
content:
138+
application/json:
139+
schema:
140+
$ref: '../../schemas/policies/transitiveImports.yml'
141+
example:
142+
- "org.eclipse.ditto:policy-template"
143+
description: |-
144+
JSON array of policy IDs to resolve transitively.
145+
required: true

documentation/src/main/resources/openapi/sources/schemas/policies/newPolicy.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,9 @@ description: Policy consisting of policy entries
1313
properties:
1414
entries:
1515
$ref: 'policyEntries.yml'
16+
imports:
17+
$ref: 'policyImports.yml'
18+
importsAliases:
19+
$ref: 'importsAliases.yml'
1620
required:
1721
- entries

documentation/src/main/resources/openapi/sources/schemas/policies/policy.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ properties:
1818
$ref: 'policyEntries.yml'
1919
imports:
2020
$ref: 'policyImports.yml'
21+
importsAliases:
22+
$ref: 'importsAliases.yml'
2123
required:
2224
- policyId
2325
- entries

0 commit comments

Comments
 (0)