Skip to content

Commit

Permalink
feat: strict policy definition validation (#1688)
Browse files Browse the repository at this point in the history
* feat: strict policy definition validation

* chore: deps file

* pr suggestions
  • Loading branch information
wolf4ood authored Nov 28, 2024
1 parent fa0d014 commit bc34588
Show file tree
Hide file tree
Showing 27 changed files with 666 additions and 337 deletions.
568 changes: 258 additions & 310 deletions DEPENDENCIES

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions charts/tractusx-connector-azure-vault/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ helm install my-release tractusx-edc/tractusx-connector-azure-vault --version 0.
| controlplane.podSecurityContext.runAsGroup | int | `10001` | Processes within a pod will belong to this guid |
| controlplane.podSecurityContext.runAsUser | int | `10001` | Runs all processes within a pod with a special uid |
| controlplane.podSecurityContext.seccompProfile.type | string | `"RuntimeDefault"` | Restrict a Container's Syscalls with seccomp |
| controlplane.policy | object | `{"validation":{"enabled":true}}` | configuration for policy engine |
| controlplane.readinessProbe.enabled | bool | `true` | Whether to enable kubernetes [readiness-probes](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) |
| controlplane.readinessProbe.failureThreshold | int | `6` | when a probe fails kubernetes will try 6 times before giving up |
| controlplane.readinessProbe.initialDelaySeconds | int | `30` | seconds to wait before performing the first readiness check |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,12 @@ spec:
- name: "TX_EDC_CATALOG_NODE_LIST_FILE"
value: {{ .Values.controlplane.catalog.crawler.targetsFile }}

###################
## POLICY ENGINE ##
###################
- name: "EDC_POLICY_VALIDATION_ENABLED"
value: {{ .Values.controlplane.policy.validation.enabled | quote }}

######################################
## Additional environment variables ##
######################################
Expand Down
4 changes: 4 additions & 0 deletions charts/tractusx-connector-azure-vault/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,10 @@ controlplane:
initialDelay:
# -- File path to a JSON file containing TargetNode entries
targetsFile:
# -- configuration for policy engine
policy:
validation:
enabled: true

service:
# -- [Service type](https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types) to expose the running application on a set of Pods as a network service.
Expand Down
1 change: 1 addition & 0 deletions charts/tractusx-connector-memory/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ helm install my-release tractusx-edc/tractusx-connector-memory --version 0.8.0 \
| runtime.podSecurityContext.runAsGroup | int | `10001` | Processes within a pod will belong to this guid |
| runtime.podSecurityContext.runAsUser | int | `10001` | Runs all processes within a pod with a special uid |
| runtime.podSecurityContext.seccompProfile.type | string | `"RuntimeDefault"` | Restrict a Container's Syscalls with seccomp |
| runtime.policy | object | `{"validation":{"enabled":true}}` | configuration for policy engine |
| runtime.readinessProbe.enabled | bool | `true` | Whether to enable kubernetes [readiness-probes](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) |
| runtime.readinessProbe.failureThreshold | int | `6` | when a probe fails kubernetes will try 6 times before giving up |
| runtime.readinessProbe.initialDelaySeconds | int | `30` | seconds to wait before performing the first readiness check |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,12 @@ spec:
- name: "TX_EDC_CATALOG_NODE_LIST_FILE"
value: {{ .Values.runtime.catalog.crawler.targetsFile }}

###################
## POLICY ENGINE ##
###################
- name: "EDC_POLICY_VALIDATION_ENABLED"
value: {{ .Values.runtime.policy.validation.enabled | quote }}

######################################
## Additional environment variables ##
######################################
Expand Down
4 changes: 4 additions & 0 deletions charts/tractusx-connector-memory/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,10 @@ runtime:
initialDelay:
# -- File path to a JSON file containing TargetNode entries
targetsFile:
# -- configuration for policy engine
policy:
validation:
enabled: true

service:
# -- [Service type](https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types) to expose the running application on a set of Pods as a network service.
Expand Down
1 change: 1 addition & 0 deletions charts/tractusx-connector/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ helm install my-release tractusx-edc/tractusx-connector --version 0.8.0 \
| controlplane.podSecurityContext.runAsGroup | int | `10001` | Processes within a pod will belong to this guid |
| controlplane.podSecurityContext.runAsUser | int | `10001` | Runs all processes within a pod with a special uid |
| controlplane.podSecurityContext.seccompProfile.type | string | `"RuntimeDefault"` | Restrict a Container's Syscalls with seccomp |
| controlplane.policy | object | `{"validation":{"enabled":true}}` | configuration for policy engine |
| controlplane.readinessProbe.enabled | bool | `true` | Whether to enable kubernetes [readiness-probes](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) |
| controlplane.readinessProbe.failureThreshold | int | `6` | when a probe fails kubernetes will try 6 times before giving up |
| controlplane.readinessProbe.initialDelaySeconds | int | `30` | seconds to wait before performing the first readiness check |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -289,9 +289,17 @@ spec:
- name: "TX_EDC_CATALOG_NODE_LIST_FILE"
value: {{ .Values.controlplane.catalog.crawler.targetsFile }}


###################
## POLICY ENGINE ##
###################
- name: "EDC_POLICY_VALIDATION_ENABLED"
value: {{ .Values.controlplane.policy.validation.enabled | quote }}

######################################
## Additional environment variables ##
######################################

- name: "EDC_RUNTIME_ID"
value: {{ include "txdc.fullname" .}}-controlplane
{{- range $key, $value := .Values.controlplane.envValueFrom }}
Expand Down
5 changes: 4 additions & 1 deletion charts/tractusx-connector/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,10 @@ controlplane:
initialDelay:
# -- File path to a JSON file containing TargetNode entries
targetsFile:

# -- configuration for policy engine
policy:
validation:
enabled: true

service:
# -- [Service type](https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types) to expose the running application on a set of Pods as a network service.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ private boolean isCacheExpired() {
private Result<Void> updateCache() {
var membershipCredToken = createMembershipPresentation();
if (membershipCredToken.failed()) {
return membershipCredToken.mapTo();
return membershipCredToken.mapFailure();
}

var request = new Request.Builder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,11 @@
import org.eclipse.edc.runtime.metamodel.annotation.Inject;
import org.eclipse.edc.spi.system.ServiceExtension;
import org.eclipse.edc.spi.system.ServiceExtensionContext;
import org.eclipse.tractusx.edc.policy.cx.contractreference.ContractReferenceConstraintFunction;
import org.eclipse.tractusx.edc.policy.cx.dismantler.DismantlerCredentialConstraintFunction;
import org.eclipse.tractusx.edc.policy.cx.framework.FrameworkAgreementCredentialConstraintFunction;
import org.eclipse.tractusx.edc.policy.cx.membership.MembershipCredentialConstraintFunction;
import org.eclipse.tractusx.edc.policy.cx.usage.UsagePurposeConstraintFunction;

import java.util.Set;
import java.util.stream.Stream;
Expand All @@ -44,9 +46,11 @@
import static org.eclipse.tractusx.edc.policy.cx.common.PolicyScopes.NEGOTIATION_SCOPE;
import static org.eclipse.tractusx.edc.policy.cx.common.PolicyScopes.TRANSFER_PROCESS_REQUEST_SCOPE;
import static org.eclipse.tractusx.edc.policy.cx.common.PolicyScopes.TRANSFER_PROCESS_SCOPE;
import static org.eclipse.tractusx.edc.policy.cx.contractreference.ContractReferenceConstraintFunction.CONTRACT_REFERENCE;
import static org.eclipse.tractusx.edc.policy.cx.dismantler.DismantlerCredentialConstraintFunction.DISMANTLER_LITERAL;
import static org.eclipse.tractusx.edc.policy.cx.framework.FrameworkAgreementCredentialConstraintFunction.FRAMEWORK_AGREEMENT_LITERAL;
import static org.eclipse.tractusx.edc.policy.cx.membership.MembershipCredentialConstraintFunction.MEMBERSHIP_LITERAL;
import static org.eclipse.tractusx.edc.policy.cx.usage.UsagePurposeConstraintFunction.USAGE_PURPOSE;


/**
Expand All @@ -65,17 +69,6 @@ public class CxPolicyExtension implements ServiceExtension {
@Inject
private RuleBindingRegistry bindingRegistry;

@Override
public String name() {
return NAME;
}

@Override
public void initialize(ServiceExtensionContext context) {
registerFunctions(policyEngine);
registerBindings(bindingRegistry);
}

public static void registerFunctions(PolicyEngine engine) {
engine.registerFunction(CatalogPolicyContext.class, Permission.class, new DismantlerCredentialConstraintFunction<>());
engine.registerFunction(ContractNegotiationPolicyContext.class, Permission.class, new DismantlerCredentialConstraintFunction<>());
Expand All @@ -88,6 +81,14 @@ public static void registerFunctions(PolicyEngine engine) {
engine.registerFunction(CatalogPolicyContext.class, Permission.class, new MembershipCredentialConstraintFunction<>());
engine.registerFunction(ContractNegotiationPolicyContext.class, Permission.class, new MembershipCredentialConstraintFunction<>());
engine.registerFunction(TransferProcessPolicyContext.class, Permission.class, new MembershipCredentialConstraintFunction<>());

engine.registerFunction(CatalogPolicyContext.class, Permission.class, CX_POLICY_NS + USAGE_PURPOSE, new UsagePurposeConstraintFunction<>());
engine.registerFunction(ContractNegotiationPolicyContext.class, Permission.class, CX_POLICY_NS + USAGE_PURPOSE, new UsagePurposeConstraintFunction<>());
engine.registerFunction(TransferProcessPolicyContext.class, Permission.class, CX_POLICY_NS + USAGE_PURPOSE, new UsagePurposeConstraintFunction<>());

engine.registerFunction(CatalogPolicyContext.class, Permission.class, CX_POLICY_NS + CONTRACT_REFERENCE, new ContractReferenceConstraintFunction<>());
engine.registerFunction(ContractNegotiationPolicyContext.class, Permission.class, CX_POLICY_NS + CONTRACT_REFERENCE, new ContractReferenceConstraintFunction<>());
engine.registerFunction(TransferProcessPolicyContext.class, Permission.class, CX_POLICY_NS + CONTRACT_REFERENCE, new ContractReferenceConstraintFunction<>());
}

public static void registerBindings(RuleBindingRegistry registry) {
Expand All @@ -101,5 +102,24 @@ public static void registerBindings(RuleBindingRegistry registry) {
registry.bind(ODRL_SCHEMA + "use", CATALOG_SCOPE);
registry.bind(ODRL_SCHEMA + "use", NEGOTIATION_SCOPE);
registry.bind(ODRL_SCHEMA + "use", TRANSFER_PROCESS_SCOPE);

registry.bind(CX_POLICY_NS + USAGE_PURPOSE, CATALOG_SCOPE);
registry.bind(CX_POLICY_NS + USAGE_PURPOSE, NEGOTIATION_SCOPE);
registry.bind(CX_POLICY_NS + USAGE_PURPOSE, TRANSFER_PROCESS_SCOPE);

registry.bind(CX_POLICY_NS + CONTRACT_REFERENCE, CATALOG_SCOPE);
registry.bind(CX_POLICY_NS + CONTRACT_REFERENCE, NEGOTIATION_SCOPE);
registry.bind(CX_POLICY_NS + CONTRACT_REFERENCE, TRANSFER_PROCESS_SCOPE);
}

@Override
public String name() {
return NAME;
}

@Override
public void initialize(ServiceExtensionContext context) {
registerFunctions(policyEngine);
registerBindings(bindingRegistry);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/

package org.eclipse.tractusx.edc.policy.cx.contractreference;

import org.eclipse.edc.participant.spi.ParticipantAgentPolicyContext;
import org.eclipse.edc.policy.engine.spi.AtomicConstraintRuleFunction;
import org.eclipse.edc.policy.model.Operator;
import org.eclipse.edc.policy.model.Permission;


/**
* This is a placeholder constraint function for ContractReference. It always returns true but allows
* the validation of policies to be strictly enforced.
*/
public class ContractReferenceConstraintFunction<C extends ParticipantAgentPolicyContext> implements AtomicConstraintRuleFunction<Permission, C> {
public static final String CONTRACT_REFERENCE = "ContractReference";

@Override
public boolean evaluate(Operator operator, Object rightOperand, Permission permission, C c) {
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/

package org.eclipse.tractusx.edc.policy.cx.usage;

import org.eclipse.edc.participant.spi.ParticipantAgentPolicyContext;
import org.eclipse.edc.policy.engine.spi.AtomicConstraintRuleFunction;
import org.eclipse.edc.policy.model.Operator;
import org.eclipse.edc.policy.model.Permission;


/**
* This is a placeholder constraint function for UsagePurpose. It always returns true but allows
* the validation of policies to be strictly enforced.
*/
public class UsagePurposeConstraintFunction<C extends ParticipantAgentPolicyContext> implements AtomicConstraintRuleFunction<Permission, C> {
public static final String USAGE_PURPOSE = "UsagePurpose";

@Override
public boolean evaluate(Operator operator, Object rightOperand, Permission permission, C c) {
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/********************************************************************************
* Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/

package org.eclipse.tractusx.edc.policy.cx.contractreference;

import org.eclipse.edc.participant.spi.ParticipantAgent;
import org.eclipse.edc.participant.spi.ParticipantAgentPolicyContext;
import org.eclipse.edc.policy.model.Operator;
import org.eclipse.tractusx.edc.policy.cx.TestParticipantAgentPolicyContext;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;

class ContractReferenceConstraintFunctionTest {

private final ParticipantAgent participantAgent = mock();
private final ContractReferenceConstraintFunction<ParticipantAgentPolicyContext> function = new ContractReferenceConstraintFunction<>();
private final ParticipantAgentPolicyContext context = new TestParticipantAgentPolicyContext(participantAgent);

@Test
void evaluate() {
assertThat(function.evaluate(Operator.EQ, "contractRef", null, context)).isTrue();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/********************************************************************************
* Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/

package org.eclipse.tractusx.edc.policy.cx.usage;

import org.eclipse.edc.participant.spi.ParticipantAgent;
import org.eclipse.edc.participant.spi.ParticipantAgentPolicyContext;
import org.eclipse.edc.policy.model.Operator;
import org.eclipse.tractusx.edc.policy.cx.TestParticipantAgentPolicyContext;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;

class UsagePurposeConstraintFunctionTest {

private final ParticipantAgent participantAgent = mock();
private final UsagePurposeConstraintFunction<ParticipantAgentPolicyContext> function = new UsagePurposeConstraintFunction<>();
private final ParticipantAgentPolicyContext context = new TestParticipantAgentPolicyContext(participantAgent);

@Test
void evaluate() {
assertThat(function.evaluate(Operator.EQ, "usagePurpose", null, context)).isTrue();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,6 @@ private Result<Map<String, Object>> mapClaims(Map<String, String> claims, Map<St
var result = mappings.entrySet().stream()
.map((entry -> mapClaim(claims, entry)))
.peek(inner -> inner.onSuccess(mapped -> payload.put(mapped.getKey(), mapped.getValue())))
.map(Result::mapTo)
.reduce(Result::merge)
.orElseGet(() -> Result.success(null));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ public Map<String, String> getConfiguration() {
put("edc.dataplane.api.public.baseurl", "http://localhost:%d/api/public/v2/data".formatted(dataPlanePublic.getPort()));
put("edc.catalog.cache.execution.delay.seconds", "2");
put("edc.catalog.cache.execution.period.seconds", "2");
put("edc.policy.validation.enabled", "true");
}
};
}
Expand Down
Loading

0 comments on commit bc34588

Please sign in to comment.