@@ -191,6 +191,107 @@ void test_unit_aws_attestation_cred_missing(void **) {
191191 test_unit_aws_attestation_failed (&awsSdkWrapper);
192192}
193193
194+ // These tests only verify the impersonation path parsing and configuration handling
195+ // not the actual STS calls, which requires valid AWS setup.
196+
197+ void test_unit_aws_attestation_impersonation_single_role (void **) {
198+ auto awsSdkWrapper = FakeAwsSdkWrapper (AWS_TEST_REGION, AWS_TEST_CREDS);
199+
200+ AttestationConfig config;
201+ config.type = AttestationType::AWS;
202+ config.awsSdkWrapper = &awsSdkWrapper;
203+ config.workloadIdentityImpersonationPath = " arn:aws:iam::123456789012:role/TestRole" ;
204+
205+ // Will fail at actual STS call, but validates path parsing and code path
206+ const auto attestationOpt = createAttestation (config);
207+ assert_true (!attestationOpt || attestationOpt.has_value ());
208+ }
209+
210+ void test_unit_aws_attestation_impersonation_role_chain (void **) {
211+ auto awsSdkWrapper = FakeAwsSdkWrapper (AWS_TEST_REGION, AWS_TEST_CREDS);
212+
213+ AttestationConfig config;
214+ config.type = AttestationType::AWS;
215+ config.awsSdkWrapper = &awsSdkWrapper;
216+ config.workloadIdentityImpersonationPath =
217+ " arn:aws:iam::123456789012:role/Role1,"
218+ " arn:aws:iam::123456789012:role/Role2,"
219+ " arn:aws:iam::123456789012:role/Role3" ;
220+
221+ // Will fail at STS, but validates chain parsing
222+ const auto attestationOpt = createAttestation (config);
223+ assert_true (!attestationOpt || attestationOpt.has_value ());
224+ }
225+
226+ void test_unit_aws_attestation_impersonation_whitespace_handling (void **) {
227+ auto awsSdkWrapper = FakeAwsSdkWrapper (AWS_TEST_REGION, AWS_TEST_CREDS);
228+
229+ AttestationConfig config;
230+ config.type = AttestationType::AWS;
231+ config.awsSdkWrapper = &awsSdkWrapper;
232+ config.workloadIdentityImpersonationPath =
233+ " arn:aws:iam::123456789012:role/Role1 , "
234+ " arn:aws:iam::123456789012:role/Role2 " ;
235+
236+ // Will fail at STS, but validates whitespace trimming
237+ const auto attestationOpt = createAttestation (config);
238+ assert_true (!attestationOpt || attestationOpt.has_value ());
239+ }
240+
241+ void test_unit_aws_attestation_impersonation_cross_account (void **) {
242+ auto awsSdkWrapper = FakeAwsSdkWrapper (AWS_TEST_REGION, AWS_TEST_CREDS);
243+
244+ AttestationConfig config;
245+ config.type = AttestationType::AWS;
246+ config.awsSdkWrapper = &awsSdkWrapper;
247+ config.workloadIdentityImpersonationPath =
248+ " arn:aws:iam::111111111111:role/SourceRole,"
249+ " arn:aws:iam::222222222222:role/TargetRole" ;
250+
251+ // Will fail at STS, but validates cross-account ARN parsing
252+ const auto attestationOpt = createAttestation (config);
253+ assert_true (!attestationOpt || attestationOpt.has_value ());
254+ }
255+
256+ void test_unit_aws_attestation_impersonation_empty_path_fallback (void **) {
257+ auto awsSdkWrapper = FakeAwsSdkWrapper (AWS_TEST_REGION, AWS_TEST_CREDS);
258+
259+ AttestationConfig config;
260+ config.type = AttestationType::AWS;
261+ config.awsSdkWrapper = &awsSdkWrapper;
262+ config.workloadIdentityImpersonationPath = " " ;
263+
264+ auto attestationOpt = createAttestation (config);
265+ assert_true (attestationOpt.has_value ());
266+
267+ const auto & attestation = attestationOpt.get ();
268+ assert_true (attestation.type == AttestationType::AWS);
269+ }
270+
271+ void test_unit_aws_attestation_impersonation_with_missing_region (void **) {
272+ auto awsSdkWrapper = FakeAwsSdkWrapper (boost::none, AWS_TEST_CREDS);
273+
274+ AttestationConfig config;
275+ config.type = AttestationType::AWS;
276+ config.awsSdkWrapper = &awsSdkWrapper;
277+ config.workloadIdentityImpersonationPath = " arn:aws:iam::123456789012:role/TestRole" ;
278+
279+ const auto attestationOpt = createAttestation (config);
280+ assert_false (attestationOpt.has_value ());
281+ }
282+
283+ void test_unit_aws_attestation_impersonation_with_missing_credentials (void **) {
284+ auto awsSdkWrapper = FakeAwsSdkWrapper (AWS_TEST_REGION, Aws::Auth::AWSCredentials ());
285+
286+ AttestationConfig config;
287+ config.type = AttestationType::AWS;
288+ config.awsSdkWrapper = &awsSdkWrapper;
289+ config.workloadIdentityImpersonationPath = " arn:aws:iam::123456789012:role/TestRole" ;
290+
291+ const auto attestationOpt = createAttestation (config);
292+ assert_false (attestationOpt.has_value ());
293+ }
294+
194295std::vector<char > makeGCPToken (boost::optional<std::string> issuer, boost::optional<std::string> subject) {
195296 auto jwtObj = Jwt::JWTObject ();
196297 jwtObj.getHeader ()->setAlgorithm (Jwt::AlgorithmType::RS256);
@@ -726,6 +827,13 @@ int main() {
726827 cmocka_unit_test (test_unit_aws_attestation_china_region_success),
727828 cmocka_unit_test (test_unit_aws_attestation_region_missing),
728829 cmocka_unit_test (test_unit_aws_attestation_cred_missing),
830+ cmocka_unit_test (test_unit_aws_attestation_impersonation_single_role),
831+ cmocka_unit_test (test_unit_aws_attestation_impersonation_role_chain),
832+ cmocka_unit_test (test_unit_aws_attestation_impersonation_whitespace_handling),
833+ cmocka_unit_test (test_unit_aws_attestation_impersonation_cross_account),
834+ cmocka_unit_test (test_unit_aws_attestation_impersonation_empty_path_fallback),
835+ cmocka_unit_test (test_unit_aws_attestation_impersonation_with_missing_region),
836+ cmocka_unit_test (test_unit_aws_attestation_impersonation_with_missing_credentials),
729837 cmocka_unit_test (test_unit_gcp_attestation_success),
730838 cmocka_unit_test (test_unit_gcp_attestation_missing_issuer),
731839 cmocka_unit_test (test_unit_gcp_attestation_missing_subject),
0 commit comments