Skip to content

Commit 0b596f5

Browse files
authored
feat: allow to start SMS for TDX framework and to expose TEE properties (#317)
1 parent 7b0e3cd commit 0b596f5

File tree

11 files changed

+244
-56
lines changed

11 files changed

+244
-56
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Copyright 2025 IEXEC BLOCKCHAIN TECH
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.iexec.sms.api.config;
18+
19+
import com.fasterxml.jackson.annotation.JsonCreator;
20+
import com.fasterxml.jackson.annotation.JsonProperty;
21+
import com.iexec.commons.poco.tee.TeeFramework;
22+
23+
public class TdxServicesProperties extends TeeServicesProperties {
24+
@JsonCreator
25+
public TdxServicesProperties(@JsonProperty("teeFrameworkVersion") final String teeFrameworkVersion,
26+
@JsonProperty("preComputeProperties") final TeeAppProperties preComputeProperties,
27+
@JsonProperty("postComputeProperties") final TeeAppProperties postComputeProperties) {
28+
super(TeeFramework.TDX, teeFrameworkVersion, preComputeProperties, postComputeProperties);
29+
}
30+
}

iexec-sms-library/src/main/java/com/iexec/sms/api/config/TeeServicesProperties.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,10 @@
2626
@AllArgsConstructor
2727
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "teeFramework", visible = true)
2828
@JsonSubTypes({
29+
@JsonSubTypes.Type(name = "TDX", value = TdxServicesProperties.class),
2930
@JsonSubTypes.Type(name = "SCONE", value = SconeServicesProperties.class),
3031
@JsonSubTypes.Type(name = "GRAMINE", value = GramineServicesProperties.class)
3132
})
32-
// TODO upgrade to sealed class in Java 17
3333
public abstract class TeeServicesProperties {
3434
private final TeeFramework teeFramework;
3535
private final String teeFrameworkVersion;
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* Copyright 2025 IEXEC BLOCKCHAIN TECH
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.iexec.sms.api.config;
18+
19+
import com.fasterxml.jackson.core.JsonProcessingException;
20+
import com.fasterxml.jackson.databind.ObjectMapper;
21+
import org.junit.jupiter.api.Test;
22+
23+
import static org.assertj.core.api.Assertions.assertThat;
24+
25+
class TdxServicesPropertiesTests {
26+
private final ObjectMapper mapper = new ObjectMapper();
27+
private final String frameworkVersion = "v0.1";
28+
29+
private final TeeServicesProperties tdxVersionProperties = new TdxServicesProperties(
30+
frameworkVersion, createTeeAppProperties("tdx-pre-compute"), createTeeAppProperties("tdx-post-compute"));
31+
32+
private TeeAppProperties createTeeAppProperties(final String name) {
33+
return TeeAppProperties.builder()
34+
.image(name)
35+
.fingerprint(name + "-fingerprint")
36+
.entrypoint(name + "-entrypoint")
37+
.heapSizeInBytes(1024 * 1024 * 1024L)
38+
.build();
39+
}
40+
41+
@Test
42+
void shouldSerializeAndDeserialize() throws JsonProcessingException {
43+
final String jsonString = mapper.writeValueAsString(tdxVersionProperties);
44+
final TeeServicesProperties deserializedProperties = mapper.readValue(jsonString, TdxServicesProperties.class);
45+
46+
assertThat(deserializedProperties)
47+
.usingRecursiveComparison()
48+
.isEqualTo(tdxVersionProperties);
49+
}
50+
51+
@Test
52+
void shouldPreserveFrameworkVersion() throws JsonProcessingException {
53+
final String jsonString = mapper.writeValueAsString(tdxVersionProperties);
54+
final TeeServicesProperties deserializedProperties = mapper.readValue(jsonString, TdxServicesProperties.class);
55+
56+
assertThat(deserializedProperties.getTeeFrameworkVersion())
57+
.isEqualTo(frameworkVersion);
58+
}
59+
60+
}

src/main/java/com/iexec/sms/tee/OnTeeFrameworkCondition.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2022-2023 IEXEC BLOCKCHAIN TECH
2+
* Copyright 2022-2025 IEXEC BLOCKCHAIN TECH
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -50,7 +50,7 @@ public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeM
5050
}
5151

5252
if (attributes == null) {
53-
log.warn("No attribute for bean annotation, won't be loaded [bean:{}",
53+
log.warn("No attribute for bean annotation, won't be loaded [bean:{}]",
5454
beanClassName);
5555
return new ConditionOutcome(
5656
false,

src/main/java/com/iexec/sms/tee/TeeController.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,10 @@ public class TeeController {
6363
private final TeeServicesProperties teeServicesProperties;
6464

6565
public TeeController(
66-
AuthorizationService authorizationService,
67-
TeeChallengeService teeChallengeService,
68-
TeeSessionService teeSessionService,
69-
@Value("${tee.worker.pipelines[0].version}") String version) {
66+
final AuthorizationService authorizationService,
67+
final TeeChallengeService teeChallengeService,
68+
final TeeSessionService teeSessionService,
69+
@Value("${tee.worker.pipelines[0].version}") final String version) {
7070
this.authorizationService = authorizationService;
7171
this.teeChallengeService = teeChallengeService;
7272
this.teeSessionService = teeSessionService;

src/main/java/com/iexec/sms/tee/config/TeeWorkerInternalConfiguration.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package com.iexec.sms.tee.config;
1818

1919
import com.iexec.commons.poco.tee.TeeFramework;
20+
import com.iexec.sms.api.config.TdxServicesProperties;
2021
import com.iexec.sms.api.config.TeeServicesProperties;
2122
import com.iexec.sms.tee.ConditionalOnTeeFramework;
2223
import jakarta.validation.constraints.NotBlank;
@@ -60,4 +61,19 @@ public Map<String, TeeServicesProperties> sconeServicesPropertiesMap(
6061
));
6162
}
6263

64+
@Bean
65+
@ConditionalOnTeeFramework(frameworks = TeeFramework.TDX)
66+
public Map<String, TeeServicesProperties> tdxServicesPropertiesMap(
67+
final TeeWorkerPipelineConfiguration pipelineConfig) {
68+
return pipelineConfig.getPipelines().stream()
69+
.map(pipeline -> new TdxServicesProperties(
70+
pipeline.version(),
71+
pipeline.preCompute().toTeeAppProperties(),
72+
pipeline.postCompute().toTeeAppProperties()))
73+
.collect(Collectors.toUnmodifiableMap(
74+
TeeServicesProperties::getTeeFrameworkVersion,
75+
Function.identity()
76+
));
77+
}
78+
6379
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* Copyright 2025 IEXEC BLOCKCHAIN TECH
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.iexec.sms.tee.session.tdx;
18+
19+
import com.iexec.commons.poco.tee.TeeFramework;
20+
import com.iexec.sms.api.TeeSessionGenerationError;
21+
import com.iexec.sms.tee.ConditionalOnTeeFramework;
22+
import com.iexec.sms.tee.session.generic.TeeSessionGenerationException;
23+
import com.iexec.sms.tee.session.generic.TeeSessionHandler;
24+
import com.iexec.sms.tee.session.generic.TeeSessionRequest;
25+
import org.springframework.stereotype.Service;
26+
27+
@Service
28+
@ConditionalOnTeeFramework(frameworks = TeeFramework.TDX)
29+
public class TdxSessionHandlerService implements TeeSessionHandler {
30+
/**
31+
* Build and post secret session on secret provisioning service.
32+
*
33+
* @param request tee session generation request
34+
* @return String secret provisioning service url
35+
* @throws TeeSessionGenerationException if an error occurs
36+
*/
37+
@Override
38+
public String buildAndPostSession(final TeeSessionRequest request) throws TeeSessionGenerationException {
39+
throw new TeeSessionGenerationException(
40+
TeeSessionGenerationError.SECURE_SESSION_STORAGE_CALL_FAILED,
41+
"Not implemented yet"
42+
);
43+
}
44+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
tee:
2+
worker:
3+
pipelines:
4+
- version: # v0.1
5+
pre-compute:
6+
image: # e.g.: iexechub/tee-worker-pre-compute-rust:<version>
7+
fingerprint:
8+
heap-size: # 1GB
9+
entrypoint: # /app/tee-worker-pre-compute
10+
post-compute:
11+
image: # e.g.: iexechub/tee-worker-post-compute-rust:<version>
12+
fingerprint:
13+
heap-size: # 1GB
14+
entrypoint: # /app/tee-worker-post-compute

src/test/java/com/iexec/sms/tee/config/TeeWorkerInternalConfigurationTests.java

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,15 @@
1616

1717
package com.iexec.sms.tee.config;
1818

19-
import com.iexec.commons.poco.tee.TeeFramework;
20-
import com.iexec.sms.api.config.GramineServicesProperties;
21-
import com.iexec.sms.api.config.SconeServicesProperties;
22-
import com.iexec.sms.api.config.TeeAppProperties;
23-
import com.iexec.sms.api.config.TeeServicesProperties;
19+
import com.iexec.sms.api.config.*;
2420
import org.junit.jupiter.api.BeforeEach;
2521
import org.junit.jupiter.api.Test;
2622
import org.springframework.util.unit.DataSize;
2723

28-
import java.util.Arrays;
24+
import java.util.List;
2925
import java.util.Map;
3026

31-
import static org.junit.jupiter.api.Assertions.*;
27+
import static org.assertj.core.api.Assertions.assertThat;
3228

3329
class TeeWorkerInternalConfigurationTests {
3430
private static final String PRE_IMAGE = "preComputeImage";
@@ -65,7 +61,7 @@ void setUp() {
6561
final TeeWorkerPipelineConfiguration.Pipeline additionalPipeline = getPipeline("v6");
6662

6763
pipelineConfig = new TeeWorkerPipelineConfiguration(
68-
Arrays.asList(pipeline, additionalPipeline)
64+
List.of(pipeline, additionalPipeline)
6965
);
7066
}
7167

@@ -96,36 +92,41 @@ void shouldBuildGramineServicesPropertiesMap() {
9692
final Map<String, TeeServicesProperties> multiPropertiesMap =
9793
teeWorkerInternalConfiguration.gramineServicesPropertiesMap(pipelineConfig);
9894

99-
assertNotNull(multiPropertiesMap);
100-
assertEquals(2, multiPropertiesMap.size());
95+
assertThat(multiPropertiesMap).isNotNull()
96+
.extracting(Map::size)
97+
.isEqualTo(2);
10198

102-
final TeeServicesProperties properties = multiPropertiesMap.get(VERSION);
103-
assertNotNull(properties);
104-
assertInstanceOf(GramineServicesProperties.class, properties);
105-
106-
final GramineServicesProperties gramineProperties = (GramineServicesProperties) properties;
107-
assertEquals(TeeFramework.GRAMINE, gramineProperties.getTeeFramework());
108-
assertEquals(preComputeProperties, gramineProperties.getPreComputeProperties());
109-
assertEquals(postComputeProperties, gramineProperties.getPostComputeProperties());
99+
assertThat(multiPropertiesMap.get(VERSION))
100+
.usingRecursiveComparison()
101+
.isEqualTo(new GramineServicesProperties(VERSION, preComputeProperties, postComputeProperties));
110102
}
111103

112104
@Test
113105
void shouldBuildSconeServicesPropertiesMap() {
114106
final Map<String, TeeServicesProperties> multiPropertiesMap =
115107
teeWorkerInternalConfiguration.sconeServicesPropertiesMap(pipelineConfig, LAS_IMAGE);
116108

117-
assertNotNull(multiPropertiesMap);
118-
assertEquals(2, multiPropertiesMap.size());
109+
assertThat(multiPropertiesMap).isNotNull()
110+
.extracting(Map::size)
111+
.isEqualTo(2);
112+
113+
assertThat(multiPropertiesMap.get(VERSION))
114+
.usingRecursiveComparison()
115+
.isEqualTo(new SconeServicesProperties(VERSION, preComputeProperties, postComputeProperties, LAS_IMAGE));
116+
}
117+
118+
@Test
119+
void shouldBuildTdxServicesPropertiesMap() {
120+
final Map<String, TeeServicesProperties> multiPropertiesMap =
121+
teeWorkerInternalConfiguration.tdxServicesPropertiesMap(pipelineConfig);
119122

120-
final TeeServicesProperties properties = multiPropertiesMap.get(VERSION);
121-
assertNotNull(properties);
122-
assertInstanceOf(SconeServicesProperties.class, properties);
123+
assertThat(multiPropertiesMap).isNotNull()
124+
.extracting(Map::size)
125+
.isEqualTo(2);
123126

124-
final SconeServicesProperties sconeProperties = (SconeServicesProperties) properties;
125-
assertEquals(TeeFramework.SCONE, sconeProperties.getTeeFramework());
126-
assertEquals(preComputeProperties, sconeProperties.getPreComputeProperties());
127-
assertEquals(postComputeProperties, sconeProperties.getPostComputeProperties());
128-
assertEquals(LAS_IMAGE, sconeProperties.getLasImage());
127+
assertThat(multiPropertiesMap.get(VERSION))
128+
.usingRecursiveComparison()
129+
.isEqualTo(new TdxServicesProperties(VERSION, preComputeProperties, postComputeProperties));
129130
}
130131

131132
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright 2025 IEXEC BLOCKCHAIN TECH
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.iexec.sms.tee.session.tdx;
18+
19+
import com.iexec.sms.api.TeeSessionGenerationError;
20+
import com.iexec.sms.tee.session.generic.TeeSessionGenerationException;
21+
import com.iexec.sms.tee.session.generic.TeeSessionRequest;
22+
import org.junit.jupiter.api.Test;
23+
24+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
25+
26+
class TdxSessionHandlerServiceTests {
27+
private final TdxSessionHandlerService sessionHandlerService = new TdxSessionHandlerService();
28+
29+
@Test
30+
void shouldThrow() {
31+
assertThatThrownBy(() -> sessionHandlerService.buildAndPostSession(TeeSessionRequest.builder().build()))
32+
.isInstanceOf(TeeSessionGenerationException.class)
33+
.hasMessage("Not implemented yet")
34+
.hasFieldOrPropertyWithValue("error", TeeSessionGenerationError.SECURE_SESSION_STORAGE_CALL_FAILED);
35+
}
36+
}

0 commit comments

Comments
 (0)