Skip to content

Commit b5303b5

Browse files
mdanish98aaronzi
andauthored
Adds an example for the Dynamic Management of RBAC rules using Security Submodel (#598)
* Adds BaSyx Dynamic RBAC Management Example Signed-off-by: Mohammad Ghazanfar Ali Danish <[email protected]> * Addresses review remarks Signed-off-by: Mohammad Ghazanfar Ali Danish <[email protected]> * Fixes the Preconfig Rules Signed-off-by: Mohammad Ghazanfar Ali Danish <[email protected]> * Fixes line endings inside entrypoint.sh Signed-off-by: Mohammad Ghazanfar Ali Danish <[email protected]> * Fixes line endings by setting them to LF instead of CRLF --------- Signed-off-by: Mohammad Ghazanfar Ali Danish <[email protected]> Co-authored-by: Aaron Zielstorff <[email protected]>
1 parent ffa3601 commit b5303b5

30 files changed

+6041
-0
lines changed

examples/BaSyxDynamicRBAC/.env

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
BASYX_VERSION=2.0.0-SNAPSHOT
2+
AAS_WEBUI_VERSION=SNAPSHOT
3+
KEYCLOAK_VERSION=24.0.4
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Use Ubuntu as the base image
2+
FROM ubuntu:20.04 AS installer
3+
4+
# Switch to root user to install dependencies (default user is root in Ubuntu)
5+
USER root
6+
7+
# Install curl (to download jq) and other dependencies
8+
RUN apt-get update && apt-get install -y \
9+
curl \
10+
libcurl4-openssl-dev \
11+
wget
12+
13+
# Download jq version 1.4 binary from GitHub releases
14+
RUN wget -O /usr/local/bin/jq https://github.com/jqlang/jq/releases/download/jq-1.4/jq-linux-x86_64
15+
16+
# Make jq executable
17+
RUN chmod +x /usr/local/bin/jq
18+
19+
# Stage 2: Build the final image based on the submodel-repository image
20+
FROM eclipsebasyx/submodel-repository:2.0.0-milestone-04
21+
22+
# Switch to root user to install dependencies
23+
USER root
24+
25+
# Copy jq binary from the Ubuntu stage to the final image (submodel-repository)
26+
COPY --from=installer /usr/local/bin/jq /usr/local/bin/jq
27+
28+
# Copy the file from local system to Docker container
29+
COPY ./initial-submodel.json /application/initial-submodel.json
30+
31+
# Expose necessary ports
32+
EXPOSE 8081
33+
34+
# Set the entrypoint to run the JAR file
35+
ENTRYPOINT ["java", "-jar", "basyxExecutable.jar"]

examples/BaSyxDynamicRBAC/DynamicRBAC.postman_collection.json

Lines changed: 1022 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
# BaSyx Dynamic RBAC Management
2+
3+
* BaSyx supports dynamic management of RBAC rules using a security Submodel.
4+
* The administrator of the system controls the policy/access rules inside the Submodel.
5+
* Rules can be added or deleted during the system's runtime.
6+
7+
<img width="60%" alt="image" src="images/DynamicRBACMgmt.png">
8+
9+
## Prerequisites
10+
1. REST API Client (e.g., [Postman](https://www.postman.com/downloads/))
11+
2. Import the [Postman Collection](DynamicRBAC.postman_collection.json)
12+
3. Docker
13+
14+
To start the secure setup execute the following command
15+
16+
```bash
17+
docker-compose up -d
18+
```
19+
20+
This will start the BaSyx components and the Keycloak server. The Keycloak server can be found at http://localhost:9097.
21+
There you can login as admin with username `admin` and password `keycloak-admin`.
22+
23+
<img width="60%" alt="image" src="images/users.png">
24+
25+
The example comes with an already configured realm `BaSyx` and a user `john.doe` with password `johndoe`.
26+
This user has the `admin` role and can access all BaSyx components and all information about each component.
27+
28+
The entry point for accessing the Asset Administration Shells and their Submodels is the AAS Web UI running at http://localhost:3000.
29+
After opening the page you will be redirected to the Keycloak login page. Use the credentials of user `john.doe` to log in.
30+
31+
<img width="60%" alt="image" src="images/login.png">
32+
33+
## 📌 Note
34+
35+
> **Important:**
36+
> Currently, AAS GUI can only be used by admin account (`john.doe` with password `johndoe`) and not with any user account due to a limitation.
37+
> This problem will be fixed with this [Pull Request](https://github.com/eclipse-basyx/basyx-java-server-sdk/pull/575)
38+
> Once this PR is merged then you can login with any user account.
39+
> For now, please use provided Postman collection to interact with the authorized components with user accounts.
40+
41+
42+
## Security in BaSyx
43+
44+
Detailed documentation of BaSyx Security is available inside Authorization section of each component [here](https://wiki.basyx.org/en/latest/content/user_documentation/basyx_components/v2/index.html)
45+
46+
For e.g., AAS Repository authorization is documented [here](https://wiki.basyx.org/en/latest/content/user_documentation/basyx_components/v2/aas_repository/features/authorization.html)
47+
48+
Following shows how a JSON based RBAC rule looks like a Submodel-based rule:
49+
50+
#### Example of a Simple RBAC Rule
51+
```json
52+
{
53+
"role": "admin",
54+
"action": "READ",
55+
"targetInformation": {
56+
"@type": "aas",
57+
"aasIds": "*"
58+
}
59+
}
60+
```
61+
62+
#### Example of a Simple Submodel persistent RBAC Rule
63+
```json
64+
{
65+
"modelType": "SubmodelElementCollection",
66+
"idShort": "YWRtaW5ERUxFVEVvcmcuZWNsaXBzZS5kaWdpdGFsdHdpbi5iYXN5eC5hYXNyZXBvc2l0b3J5LmZlYXR1cmUuYXV0aG9yaXphdGlvbi5BYXNUYXJnZXRJbmZvcm1hdGlvbg==",
67+
"value": [
68+
{
69+
"modelType": "Property",
70+
"value": "admin",
71+
"idShort": "role"
72+
},
73+
{
74+
"modelType": "SubmodelElementList",
75+
"idShort": "action",
76+
"orderRelevant": true,
77+
"value": [
78+
{
79+
"modelType": "Property",
80+
"value": "READ"
81+
}
82+
]
83+
},
84+
{
85+
"modelType": "SubmodelElementCollection",
86+
"idShort": "targetInformation",
87+
"value": [
88+
{
89+
"modelType": "SubmodelElementList",
90+
"idShort": "aasIds",
91+
"orderRelevant": true,
92+
"value": [
93+
{
94+
"modelType": "Property",
95+
"value": "*"
96+
}
97+
]
98+
}
99+
]
100+
}
101+
]
102+
}
103+
```
104+
105+
## Example use case
106+
107+
* A bicycle manufacturer and suppliers of parts of bicycle works collaboratively.
108+
* There is one Manufacturer and two Suppliers.
109+
* Two suppliers are for Gear and Frame.
110+
* Following are the information for access rules configuration in Identity Management:
111+
112+
| Role | User | Password |
113+
|--------------------|-------|----------|
114+
| FrameSupplier | alice | alice |
115+
| GearSupplier | bob | bob |
116+
| ManufacturerFrame | dave | dave |
117+
| ManufacturerGear | dave | dave |
118+
119+
<img width="60%" alt="image" src="images/AASDS2.png">
120+
121+
### View Rules for this example
122+
123+
* Postman -> AASDataspace -> Rules -> Frame (In Postman collection)
124+
* Open any request
125+
* Go to body and check the structure of rules
126+
127+
### Formula for generating idShort of the RBAC rule for the Rule SubmodelElementCollection
128+
129+
* The idShort of the RBAC rule for the Rule SubmodelElementCollection is the Base64 encode of the concatenation of **Role** + **Action** + **TargetInformation Class**.
130+
* For e.g., Role = admin, Action = DELETE, TargetInformation Class = org.eclipse.digitaltwin.basyx.aasrepository.feature.authorization.AasTargetInformation. The idShort will be Base64(adminDELETEorg.eclipse.digitaltwin.basyx.aasrepository.feature.authorization.AasTargetInformation) which is YWRtaW5ERUxFVEVvcmcuZWNsaXBzZS5kaWdpdGFsdHdpbi5iYXN5eC5hYXNyZXBvc2l0b3J5LmZlYXR1cmUuYXV0aG9yaXphdGlvbi5BYXNUYXJnZXRJbmZvcm1hdGlvbg==.
131+
132+
Similarly, you can create idShorts using the below TargetInformation class as per the TargetInformation in consideration.
133+
134+
| Component | TargetInformation Class |
135+
|-----------------------------------|-------------------------------------------------------------------------------------------------------------------------------------|
136+
| AAS Environment | org.eclipse.digitaltwin.basyx.aasenvironment.feature.authorization.AasEnvironmentTargetInformation |
137+
| AAS Repository | org.eclipse.digitaltwin.basyx.aasrepository.feature.authorization.AuthorizedAasRepository |
138+
| Submodel Repository | org.eclipse.digitaltwin.basyx.submodelrepository.feature.authorization.SubmodelTargetInformation |
139+
| Concept Description Repository | org.eclipse.digitaltwin.basyx.conceptdescriptionrepository.feature.authorization.ConceptDescriptionTargetInformation |
140+
| AAS Registry | org.eclipse.digitaltwin.basyx.aasregistry.feature.authorization.AasRegistryTargetInformation |
141+
| Submodel Registry | org.eclipse.digitaltwin.basyx.submodelregistry.feature.authorization.SubmodelRegistryTargetInformation |
142+
| AAS Discovery | org.eclipse.digitaltwin.basyx.aasdiscoveryservice.feature.authorization.AasDiscoveryServiceTargetInformation |
143+
144+
### Scenario
145+
146+
<img width="80%" alt="image" src="images/BicycleExampleDataspaceFlow_short.png">
147+
148+
* When Frame Supplier delivers the product they also add a policy/rule (using Dynamic RBAC) so that the manufacturer can see the Digital Twin of the supplied product.
149+
- Postman -> AASDataspace -> Rules -> Frame (In Postman collection)
150+
- We need to add rules separately for AAS/SM Registry as well as AAS/SM Repository
151+
- Before providing the access
152+
- Postman -> AASDataspace -> Rules -> Manufacturer
153+
- Go to GET_FrameAAS request or GET_SupplierSMFrom_FrameAAS -> Authorization -> Get New Access Token (at very bottom) -> Use Token
154+
- Send the request
155+
- These requests will return 403
156+
- Add rules to provide access
157+
- Postman -> AASDataspace -> Rules -> Frame
158+
- For each requests -> Authorization -> Get New Access Token (at very bottom) -> Use Token
159+
- Send each requests
160+
- These requests will return 201 indicating a new rule has been added to the Security Submodel using Dynamic RBAC Management
161+
- Now retry accessing the resource as a Manufacturer
162+
- Postman -> AASDataspace -> Rules -> Manufacturer
163+
- Go to GET_FrameAAS request or GET_SupplierSMFrom_FrameAAS -> Authorization -> Get New Access Token (at very bottom) -> Use Token
164+
- Send the request
165+
- These requests will return 200 OK
166+
167+
168+
* Similarly, when Gear Supplier delivers the product they also add a policy/rule (using Dynamic RBAC) so that the manufacturer can see the Digital Twin of the supplied product.
169+
- Postman -> AASDataspace -> Rules -> Gear (In Postman collection)
170+
- We need to add rules separately for AAS/SM Registry as well as AAS/SM Repository
171+
- Before providing the access
172+
- Postman -> AASDataspace -> Rules -> Manufacturer
173+
- Go to GET_GearAAS request or GET_SupplierSMFrom_GearAAS -> Authorization -> Get New Access Token (at very bottom) -> Use Token
174+
- Send the request
175+
- These requests will return 403
176+
- Add rules to provide access
177+
- Postman -> AASDataspace -> Rules -> Gear
178+
- For each requests -> Authorization -> Get New Access Token (at very bottom) -> Use Token
179+
- Send each requests
180+
- These requests will return 201 indicating a new rule has been added to the Security Submodel using Dynamic RBAC Management
181+
- Now retry accessing the resource as a Manufacturer
182+
- Postman -> AASDataspace -> Rules -> Manufacturer
183+
- Go to GET_GearAAS request or GET_SupplierSMFrom_GearAAS -> Authorization -> Get New Access Token (at very bottom) -> Use Token
184+
- Send the request
185+
- These requests will return 200 OK
2.2 KB
Binary file not shown.
2.17 KB
Binary file not shown.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
server.port=8081
2+
spring.application.name=AAS Discovery Service
3+
basyx.aasdiscoveryservice.name=aas-discovery-service
4+
basyx.backend=InMemory
5+
basyx.cors.allowed-origins=*
6+
basyx.cors.allowed-methods=GET,POST,PATCH,DELETE,PUT,OPTIONS,HEAD
7+
8+
basyx.feature.authorization.enabled = true
9+
basyx.feature.authorization.type = rbac
10+
basyx.feature.authorization.jwtBearerTokenProvider = keycloak
11+
basyx.feature.authorization.rbac.file = file:/application/rbac_rules.json
12+
spring.security.oauth2.resourceserver.jwt.issuer-uri= http://keycloak:9097/realms/BaSyx
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
server.port=8081
2+
basyx.backend=InMemory
3+
basyx.environment=file:aas
4+
basyx.cors.allowed-origins=*
5+
basyx.cors.allowed-methods=GET,POST,PATCH,DELETE,PUT,OPTIONS,HEAD
6+
basyx.aasrepository.feature.registryintegration=http://aas-registry:8080
7+
basyx.submodelrepository.feature.registryintegration=http://sm-registry:8080
8+
basyx.externalurl=http://localhost:8081
9+
10+
basyx.feature.authorization.enabled = true
11+
basyx.feature.authorization.type = rbac
12+
basyx.feature.authorization.jwtBearerTokenProvider = keycloak
13+
basyx.feature.authorization.rbac.file = file:/application/rbac_rules.json
14+
15+
basyx.feature.authorization.rules.backend=Submodel
16+
basyx.feature.authorization.rules.backend.submodel.authorization.endpoint=http://security-submodel:8081/submodels/U2VjdXJpdHlTdWJtb2RlbA==
17+
basyx.feature.authorization.rules.backend.submodel.authorization.token-endpoint=http://keycloak-rbac:8080/realms/BaSyx/protocol/openid-connect/token
18+
basyx.feature.authorization.rules.backend.submodel.authorization.grant-type = CLIENT_CREDENTIALS
19+
basyx.feature.authorization.rules.backend.submodel.authorization.client-id=workstation-1
20+
basyx.feature.authorization.rules.backend.submodel.authorization.client-secret=nY0mjyECF60DGzNmQUjL81XurSl8etom
21+
22+
spring.security.oauth2.resourceserver.jwt.issuer-uri= http://keycloak-rbac:8080/realms/BaSyx
23+
basyx.aasenvironment.authorization.preconfiguration.token-endpoint=http://keycloak-rbac:8080/realms/BaSyx/protocol/openid-connect/token
24+
basyx.aasenvironment.authorization.preconfiguration.grant-type = CLIENT_CREDENTIALS
25+
basyx.aasenvironment.authorization.preconfiguration.client-id=workstation-1
26+
basyx.aasenvironment.authorization.preconfiguration.client-secret=nY0mjyECF60DGzNmQUjL81XurSl8etom
27+
#basyx.aasenvironment.authorization.preconfiguration.username=username
28+
#basyx.aasenvironment.authorization.preconfiguration.password=password
29+
#basyx.aasenvironment.authorization.preconfiguration.scopes=
30+
spring.servlet.multipart.max-request-size=128MB
31+
spring.servlet.multipart.max-file-size=128MB
32+
33+
basyx.aasrepository.feature.registryintegration.authorization.enabled=true
34+
basyx.aasrepository.feature.registryintegration.authorization.token-endpoint=http://keycloak-rbac:8080/realms/BaSyx/protocol/openid-connect/token
35+
basyx.aasrepository.feature.registryintegration.authorization.grant-type = CLIENT_CREDENTIALS
36+
basyx.aasrepository.feature.registryintegration.authorization.client-id = workstation-1
37+
basyx.aasrepository.feature.registryintegration.authorization.client-secret = nY0mjyECF60DGzNmQUjL81XurSl8etom
38+
basyx.submodelrepository.feature.registryintegration.authorization.enabled=true
39+
basyx.submodelrepository.feature.registryintegration.authorization.token-endpoint=http://keycloak-rbac:8080/realms/BaSyx/protocol/openid-connect/token
40+
basyx.submodelrepository.feature.registryintegration.authorization.grant-type = CLIENT_CREDENTIALS
41+
basyx.submodelrepository.feature.registryintegration.authorization.client-id=workstation-1
42+
basyx.submodelrepository.feature.registryintegration.authorization.client-secret=nY0mjyECF60DGzNmQUjL81XurSl8etom
43+
#basyx.aasrepository.feature.registryintegration.authorization.username=test
44+
#basyx.aasrepository.feature.registryintegration.authorization.password=test
45+
#basyx.aasrepository.feature.registryintegration.authorization.scopes=[]
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
[
2+
{
3+
"role": "basyx-assetid-creator",
4+
"action": "CREATE",
5+
"targetInformation": {
6+
"@type": "aas-discovery-service",
7+
"aasIds": "*",
8+
"assetIds": []
9+
}
10+
},
11+
{
12+
"role": "basyx-assetid-discoverer",
13+
"action": "READ",
14+
"targetInformation": {
15+
"@type": "aas-discovery-service",
16+
"aasIds": "*",
17+
"assetIds": []
18+
}
19+
},
20+
{
21+
"role": "basyx-assetid-deleter",
22+
"action": "DELETE",
23+
"targetInformation": {
24+
"@type": "aas-discovery-service",
25+
"aasIds": "*",
26+
"assetIds": []
27+
}
28+
},
29+
{
30+
"role": "basyx-aas-discoverer",
31+
"action": "READ",
32+
"targetInformation": {
33+
"@type": "aas-discovery-service",
34+
"aasIds": null,
35+
"assetIds": [
36+
{
37+
"name": "*",
38+
"value": "*"
39+
}
40+
]
41+
}
42+
}
43+
]
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
[
2+
{
3+
"role": "admin",
4+
"action": ["CREATE", "READ", "UPDATE", "DELETE"],
5+
"targetInformation": {
6+
"@type": "concept-description",
7+
"conceptDescriptionIds": "*"
8+
}
9+
},
10+
{
11+
"role": "admin",
12+
"action": ["CREATE", "READ", "UPDATE", "DELETE"],
13+
"targetInformation": {
14+
"@type": "aas",
15+
"aasIds": "*"
16+
}
17+
},
18+
{
19+
"role": "admin",
20+
"action": ["CREATE", "READ", "UPDATE", "DELETE", "EXECUTE"],
21+
"targetInformation": {
22+
"@type": "submodel",
23+
"submodelIds": "*",
24+
"submodelElementIdShortPaths": "*"
25+
}
26+
},
27+
{
28+
"role": "admin",
29+
"action": ["CREATE", "READ", "UPDATE", "DELETE"],
30+
"targetInformation": {
31+
"@type": "aas-environment",
32+
"aasIds": "*",
33+
"submodelIds": "*"
34+
}
35+
}
36+
]

0 commit comments

Comments
 (0)