Skip to content

Commit c0c7501

Browse files
authored
Configure the SMS at startup to generate Scone sessions in Hardware or MAA mode (#275)
1 parent ad3a2f2 commit c0c7501

File tree

10 files changed

+263
-70
lines changed

10 files changed

+263
-70
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file.
88

99
- Accept scheduler default result-proxy as a web2 secret to fallback on it when no proxy
1010
is specified in deal parameters. (#273)
11+
- Configure the SMS at startup to generate Scone sessions in Hardware or MAA mode. (#275)
1112

1213
### Quality
1314

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ To support:
8484
| `IEXEC_SMS_SSL_KEYSTORE_ALIAS` | Alias that identifies the key in the key store. | String | `iexec-core` |
8585
| `IEXEC_SCONE_TOLERATED_INSECURE_OPTIONS` | List of hardware or software Scone vulnerabilities to ignore. | String | |
8686
| `IEXEC_IGNORED_SGX_ADVISORIES` | List of hardware or software Intel vulnerabilities to ignore. | String | |
87+
| `TEE_SCONE_ATTESTATION_MODE` | Attestation mode used for TEE tasks Scone session generation. | String | `maa` |
88+
| `TEE_SCONE_ATTESTATION_URL` | URL of the Microsoft Azure Attestation service used for TEE tasks Scone session generation. | URL | `https://sharedweu.weu.attest.azure.net` |
8789
| `IEXEC_SMS_IMAGE_LAS_IMAGE` | Scontain LAS OCI image to be used by workers to execute TEE tasks. LAS performs local attestation which creates a quote that CAS can verify. | String | |
8890

8991
## Health checks

src/main/java/com/iexec/sms/tee/session/scone/SconeSessionHandlerService.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2022-2023 IEXEC BLOCKCHAIN TECH
2+
* Copyright 2022-2024 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.
@@ -38,16 +38,16 @@ public class SconeSessionHandlerService implements TeeSessionHandler {
3838
private final CasConfiguration casConfiguration;
3939

4040
public SconeSessionHandlerService(SconeSessionMakerService sessionService,
41-
CasClient apiClient,
42-
CasConfiguration casConfiguration) {
41+
CasClient apiClient,
42+
CasConfiguration casConfiguration) {
4343
this.sessionService = sessionService;
4444
this.apiClient = apiClient;
4545
this.casConfiguration = casConfiguration;
4646
}
4747

4848
/**
4949
* Build and post secret session on secret provisioning service.
50-
*
50+
*
5151
* @param request tee session generation request
5252
* @return String secret provisioning service url
5353
* @throws TeeSessionGenerationException if call to CAS failed

src/main/java/com/iexec/sms/tee/session/scone/SconeSessionMakerService.java

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020-2023 IEXEC BLOCKCHAIN TECH
2+
* Copyright 2020-2024 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.
@@ -85,7 +85,7 @@ public SconeSession generateSession(TeeSessionRequest request)
8585
teeServicesConfig.getPreComputeProperties().getEntrypoint(),
8686
true);
8787
services.add(sconePreEnclave);
88-
images.add(new SconeSession.Image(
88+
images.add(new Image(
8989
sconePreEnclave.getImageName(),
9090
List.of(iexecInVolume)));
9191
}
@@ -95,7 +95,7 @@ public SconeSession generateSession(TeeSessionRequest request)
9595
request.getTaskDescription().getAppCommand(),
9696
false);
9797
services.add(sconeAppEnclave);
98-
images.add(new SconeSession.Image(
98+
images.add(new Image(
9999
sconeAppEnclave.getImageName(),
100100
List.of(iexecInVolume, iexecOutVolume)));
101101
// post
@@ -104,22 +104,27 @@ public SconeSession generateSession(TeeSessionRequest request)
104104
teeServicesConfig.getPostComputeProperties().getEntrypoint(),
105105
true);
106106
services.add(sconePostEnclave);
107-
images.add(new SconeSession.Image(
107+
images.add(new Image(
108108
sconePostEnclave.getImageName(),
109109
List.of(iexecOutVolume, postComputeTmpVolume)));
110110

111111
return SconeSession.builder()
112112
.name(request.getSessionId())
113-
.version("0.3")
113+
.version("0.3.10")
114114
.accessPolicy(new AccessPolicy(List.of("CREATOR"), List.of("NONE")))
115115
.services(services)
116116
.images(images)
117117
.volumes(Arrays.asList(new Volumes(iexecInVolume.getName()),
118118
new Volumes(iexecOutVolume.getName()),
119119
new Volumes(postComputeTmpVolume.getName())))
120-
.security(new Security(
121-
attestationSecurityConfig.getToleratedInsecureOptions(),
122-
attestationSecurityConfig.getIgnoredSgxAdvisories()))
120+
.security(
121+
new Security(
122+
attestationSecurityConfig.getToleratedInsecureOptions(),
123+
attestationSecurityConfig.getIgnoredSgxAdvisories(),
124+
attestationSecurityConfig.getMode(),
125+
attestationSecurityConfig.getUrl()
126+
)
127+
)
123128
.build();
124129
}
125130

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020-2023 IEXEC BLOCKCHAIN TECH
2+
* Copyright 2020-2024 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.
@@ -18,21 +18,32 @@
1818

1919
import com.iexec.commons.poco.tee.TeeFramework;
2020
import com.iexec.sms.tee.ConditionalOnTeeFramework;
21-
import lombok.Getter;
22-
import org.springframework.beans.factory.annotation.Value;
23-
import org.springframework.context.annotation.Configuration;
21+
import lombok.Value;
22+
import org.springframework.boot.context.properties.ConfigurationProperties;
23+
import org.springframework.boot.context.properties.ConstructorBinding;
2424

25+
import javax.validation.constraints.NotBlank;
26+
import java.net.URL;
2527
import java.util.List;
2628

27-
@Configuration
29+
@Value
30+
@ConstructorBinding
31+
@ConfigurationProperties(prefix = "tee.scone.attestation")
2832
@ConditionalOnTeeFramework(frameworks = TeeFramework.SCONE)
2933
public class SconeSessionSecurityConfig {
34+
List<String> toleratedInsecureOptions;
35+
List<String> ignoredSgxAdvisories;
36+
@NotBlank
37+
String mode;
38+
URL url;
3039

31-
@Value("${tee.scone.attestation.tolerated-insecure-options}")
32-
@Getter
33-
private List<String> toleratedInsecureOptions;
34-
35-
@Value("${tee.scone.attestation.ignored-sgx-advisories}")
36-
@Getter
37-
private List<String> ignoredSgxAdvisories;
40+
public SconeSessionSecurityConfig(List<String> toleratedInsecureOptions, List<String> ignoredSgxAdvisories, String mode, URL url) {
41+
this.toleratedInsecureOptions = toleratedInsecureOptions;
42+
this.ignoredSgxAdvisories = ignoredSgxAdvisories;
43+
this.mode = mode;
44+
this.url = url;
45+
if ("maa".equals(this.mode) && this.url == null) {
46+
throw new IllegalArgumentException("Attestation URL can not be null when scone session mode is 'maa'");
47+
}
48+
}
3849
}

src/main/java/com/iexec/sms/tee/session/scone/cas/SconeSession.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2022 IEXEC BLOCKCHAIN TECH
2+
* Copyright 2022-2024 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.
@@ -22,6 +22,7 @@
2222
import lombok.*;
2323
import lombok.extern.slf4j.Slf4j;
2424

25+
import java.net.URL;
2526
import java.util.List;
2627

2728
@Slf4j
@@ -85,8 +86,8 @@ public static class Security {
8586
@JsonProperty("attestation")
8687
private Attestation attestation;
8788

88-
public Security(List<String> tolerate, List<String> ignoreAdvisories) {
89-
this.attestation = new Attestation(tolerate, ignoreAdvisories);
89+
public Security(List<String> tolerate, List<String> ignoreAdvisories, String mode, URL url) {
90+
this.attestation = new Attestation(tolerate, ignoreAdvisories, mode, url);
9091
}
9192

9293
@AllArgsConstructor
@@ -96,6 +97,10 @@ public class Attestation {
9697
private List<String> tolerate;
9798
@JsonProperty("ignore_advisories")
9899
private List<String> ignoreAdvisories;
100+
@JsonProperty("mode")
101+
private String mode;
102+
@JsonProperty("url")
103+
private URL url;
99104
}
100105
}
101106

src/main/resources/application-scone.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,5 @@ tee:
3131
attestation:
3232
tolerated-insecure-options: ${IEXEC_SCONE_TOLERATED_INSECURE_OPTIONS:} # e.g.: hyperthreading,software-hardening-needed,insecure-igpu,outdated-tcb,debug-mode
3333
ignored-sgx-advisories: ${IEXEC_IGNORED_SGX_ADVISORIES:} # e.g.: INTEL-SA-00220,INTEL-SA-00270
34+
mode: maa
35+
url: https://sharedweu.weu.attest.azure.net

src/test/java/com/iexec/sms/tee/session/scone/SconeSessionMakerServiceTests.java

Lines changed: 81 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020-2023 IEXEC BLOCKCHAIN TECH
2+
* Copyright 2020-2024 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.
@@ -23,29 +23,49 @@
2323
import com.iexec.sms.tee.session.base.SecretEnclaveBase;
2424
import com.iexec.sms.tee.session.base.SecretSessionBase;
2525
import com.iexec.sms.tee.session.base.SecretSessionBaseService;
26+
import com.iexec.sms.tee.session.generic.TeeSessionGenerationException;
2627
import com.iexec.sms.tee.session.generic.TeeSessionRequest;
2728
import com.iexec.sms.tee.session.scone.cas.SconeSession;
2829
import lombok.extern.slf4j.Slf4j;
2930
import org.junit.jupiter.api.BeforeEach;
31+
import org.junit.jupiter.api.Nested;
3032
import org.junit.jupiter.api.Test;
33+
import org.junit.jupiter.api.extension.ExtendWith;
3134
import org.mockito.InjectMocks;
3235
import org.mockito.Mock;
33-
import org.mockito.MockitoAnnotations;
36+
import org.mockito.junit.jupiter.MockitoExtension;
3437
import org.yaml.snakeyaml.Yaml;
3538

39+
import java.net.MalformedURLException;
40+
import java.net.URI;
41+
import java.net.URISyntaxException;
42+
import java.net.URL;
3643
import java.util.List;
3744
import java.util.Map;
3845

3946
import static com.iexec.sms.tee.session.TeeSessionTestUtils.*;
4047
import static org.mockito.Mockito.when;
4148

4249
@Slf4j
50+
@ExtendWith(MockitoExtension.class)
4351
class SconeSessionMakerServiceTests {
4452

4553
private static final String PRE_COMPUTE_ENTRYPOINT = "entrypoint1";
4654
private static final String APP_FINGERPRINT = "01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b";
4755
private static final String APP_ENTRYPOINT = "appEntrypoint";
4856
private static final String POST_COMPUTE_ENTRYPOINT = "entrypoint3";
57+
private static final URL MAA_URL;
58+
59+
static {
60+
try {
61+
MAA_URL = new URI("https://maa.attestation.service").toURL();
62+
} catch (MalformedURLException | URISyntaxException e) {
63+
throw new RuntimeException(e);
64+
}
65+
}
66+
67+
private final List<String> toleratedInsecureOptions = List.of("hyperthreading", "debug-mode");
68+
private final List<String> ignoredSgxAdvisories = List.of("INTEL-SA-00161", "INTEL-SA-00289");
4969

5070
private final TeeAppProperties preComputeProperties = TeeAppProperties.builder()
5171
.image("PRE_COMPUTE_IMAGE")
@@ -63,27 +83,29 @@ class SconeSessionMakerServiceTests {
6383
private SconeServicesProperties teeServicesConfig;
6484
@Mock
6585
private SecretSessionBaseService teeSecretsService;
66-
@Mock
86+
6787
private SconeSessionSecurityConfig attestationSecurityConfig;
6888

6989
@InjectMocks
7090
private SconeSessionMakerService palaemonSessionService;
7191

72-
@BeforeEach
73-
void beforeEach() {
74-
MockitoAnnotations.openMocks(this);
92+
private TeeSessionRequest request;
93+
94+
private void setupCommonMocks() throws TeeSessionGenerationException {
95+
palaemonSessionService = new SconeSessionMakerService(
96+
teeSecretsService,
97+
teeServicesConfig,
98+
attestationSecurityConfig
99+
);
100+
75101
when(teeServicesConfig.getPreComputeProperties()).thenReturn(preComputeProperties);
76102
when(teeServicesConfig.getPostComputeProperties()).thenReturn(postComputeProperties);
77-
}
78103

79-
// region getSessionYml
80-
@Test
81-
void shouldGetSessionYml() throws Exception {
82104
TeeEnclaveConfiguration enclaveConfig = TeeEnclaveConfiguration.builder()
83105
.fingerprint(APP_FINGERPRINT)
84106
.entrypoint(APP_ENTRYPOINT)
85107
.build();
86-
TeeSessionRequest request = createSessionRequest(createTaskDescription(enclaveConfig).build());
108+
request = createSessionRequest(createTaskDescription(enclaveConfig).build());
87109

88110
SecretEnclaveBase preCompute = SecretEnclaveBase.builder()
89111
.name("pre-compute")
@@ -141,25 +163,57 @@ void shouldGetSessionYml() throws Exception {
141163
.appCompute(appCompute)
142164
.postCompute(postCompute)
143165
.build());
166+
}
144167

145-
when(attestationSecurityConfig.getToleratedInsecureOptions())
146-
.thenReturn(List.of("hyperthreading", "debug-mode"));
147-
when(attestationSecurityConfig.getIgnoredSgxAdvisories())
148-
.thenReturn(List.of("INTEL-SA-00161", "INTEL-SA-00289"));
168+
// region HardwareModeTests
169+
@Nested
170+
class HardwareModeTests {
171+
@BeforeEach
172+
void setup() throws TeeSessionGenerationException {
173+
attestationSecurityConfig = new SconeSessionSecurityConfig(
174+
toleratedInsecureOptions,
175+
ignoredSgxAdvisories,
176+
"hardware",
177+
null
178+
);
179+
setupCommonMocks();
180+
}
149181

150-
when(teeSecretsService.getSecretsTokens(request))
151-
.thenReturn(SecretSessionBase.builder()
152-
.preCompute(preCompute)
153-
.appCompute(appCompute)
154-
.postCompute(postCompute)
155-
.build());
182+
@Test
183+
void shouldGenerateHardwareSession() throws Exception {
184+
SconeSession actualCasSession = palaemonSessionService.generateSession(request);
185+
log.info(actualCasSession.toString());
186+
Map<String, Object> actualYmlMap = new Yaml().load(actualCasSession.toString());
187+
String expectedYamlString = FileHelper.readFile("src/test/resources/palaemon-tee-session-hardware.yml");
188+
Map<String, Object> expectedYmlMap = new Yaml().load(expectedYamlString);
189+
assertRecursively(expectedYmlMap, actualYmlMap);
190+
}
191+
}
192+
// endregion
193+
194+
// region MaaModeTests
195+
@Nested
196+
class MaaModeTests {
197+
@BeforeEach
198+
void setup() throws TeeSessionGenerationException {
199+
attestationSecurityConfig = new SconeSessionSecurityConfig(
200+
toleratedInsecureOptions,
201+
ignoredSgxAdvisories,
202+
"maa",
203+
MAA_URL
204+
);
205+
setupCommonMocks();
206+
}
156207

157-
SconeSession actualCasSession = palaemonSessionService.generateSession(request);
158-
log.info(actualCasSession.toString());
159-
Map<String, Object> actualYmlMap = new Yaml().load(actualCasSession.toString());
160-
String expectedYamlString = FileHelper.readFile("src/test/resources/palaemon-tee-session.yml");
161-
Map<String, Object> expectedYmlMap = new Yaml().load(expectedYamlString);
162-
assertRecursively(expectedYmlMap, actualYmlMap);
208+
@Test
209+
void shouldGenerateMaaSession() throws Exception {
210+
SconeSession actualCasSession = palaemonSessionService.generateSession(request);
211+
log.info(actualCasSession.toString());
212+
Map<String, Object> actualYmlMap = new Yaml().load(actualCasSession.toString());
213+
String expectedYamlString = FileHelper.readFile("src/test/resources/palaemon-tee-session-maa.yml");
214+
Map<String, Object> expectedYmlMap = new Yaml().load(expectedYamlString);
215+
assertRecursively(expectedYmlMap, actualYmlMap);
216+
}
163217
}
164218
// endregion
165219
}

0 commit comments

Comments
 (0)