Skip to content

Commit 6c72222

Browse files
SNOW-1902246 Workload Identity Federation authentication (#1195)
1 parent 6f510e0 commit 6c72222

File tree

44 files changed

+2164
-33
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+2164
-33
lines changed

Snowflake.Data.Tests/UnitTests/Authenticator/OAuthAuthorizationCodeFlowTest.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ public void TestRefreshToken()
303303
_runner.AddMappings(s_authorizationCodeSuccessfulMappingPath);
304304
_runner.AddMappings(s_oauthSnowflakeLoginInvalidTokenMappingPath);
305305
_runner.AddMappings(s_refreshTokenMappingPath);
306-
_runner.AddMappings(s_oauthSnowflakeLoginSuccessMappingPath, new StringTransformation(AccessToken, NewAccessToken));
306+
_runner.AddMappings(s_oauthSnowflakeLoginSuccessMappingPath, new StringTransformations().ThenTransform(AccessToken, NewAccessToken));
307307
var session = PrepareSession();
308308
var authenticator = (OAuthAuthorizationCodeAuthenticator)session.GetAuthenticator();
309309

@@ -325,7 +325,7 @@ public async Task TestRefreshTokenAsync()
325325
_runner.AddMappings(s_authorizationCodeSuccessfulMappingPath);
326326
_runner.AddMappings(s_oauthSnowflakeLoginInvalidTokenMappingPath);
327327
_runner.AddMappings(s_refreshTokenMappingPath);
328-
_runner.AddMappings(s_oauthSnowflakeLoginSuccessMappingPath, new StringTransformation(AccessToken, NewAccessToken));
328+
_runner.AddMappings(s_oauthSnowflakeLoginSuccessMappingPath, new StringTransformations().ThenTransform(AccessToken, NewAccessToken));
329329
var session = PrepareSession();
330330
var authenticator = (OAuthAuthorizationCodeAuthenticator)session.GetAuthenticator();
331331

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Globalization;
4+
using System.Net.Http;
5+
using Amazon.Runtime;
6+
using NUnit.Framework;
7+
using Snowflake.Data.Core.Authenticator.WorkflowIdentity;
8+
9+
namespace Snowflake.Data.Tests.UnitTests.Authenticator.WorkflowIdentity
10+
{
11+
[TestFixture]
12+
public class AwsSignature4SignerTest
13+
{
14+
private const string AwsStsHost = "sts.eu-west-1.amazonaws.com";
15+
private const string AwsAccessKey = "ABCDEFGHIJ12345KLMNO"; // pragma: allowlist secret
16+
private const string AwsSecretKey = "aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStT"; // pragma: allowlist secret
17+
private const string AwsToken = "HIJKLMNOPQRSTUWXYZ"; // pragma: allowlist secret
18+
private const string SnowflakeAudience = "snowflakecomputing.com";
19+
private static readonly DateTime s_time = new(2025, 6, 12, 15, 46, 13, 5, new GregorianCalendar(), DateTimeKind.Utc);
20+
private const string ExpectedAmazonDate = "20250612T154613Z";
21+
private const string ExpectedSignature = "3fa477a5d4df0381fa0d303cc944723b20e6fff8e1917602a19f4dc67c18df17"; // pragma: allowlist secret
22+
private static readonly string s_expectedAuthorization = $"AWS4-HMAC-SHA256 Credential={AwsAccessKey}/20250612/eu-west-1/sts/aws4_request, SignedHeaders=host;x-amz-date;x-amz-security-token;x-snowflake-audience, Signature={ExpectedSignature}";
23+
24+
[Test]
25+
public void TestRequestSigning()
26+
{
27+
// arrange
28+
var request = new AttestationRequest
29+
{
30+
HttpMethod = HttpMethod.Post,
31+
Uri = new Uri($"https://{AwsStsHost}/?Action=GetCallerIdentity&Version=2011-06-15"),
32+
Headers = new Dictionary<string, string>
33+
{
34+
{ "host", AwsStsHost },
35+
{ "x-snowflake-audience", SnowflakeAudience }
36+
}
37+
};
38+
var awsConfig = new AwsConfiguration()
39+
{
40+
Region = "eu-west-1",
41+
Service = "sts",
42+
Credentials = new ImmutableCredentials(AwsAccessKey, AwsSecretKey, AwsToken)
43+
};
44+
45+
// act
46+
AwsSignature4Signer.AddTokenAndSignatureHeaders(request, awsConfig, s_time);
47+
48+
// assert
49+
Assert.AreEqual(5, request.Headers.Count);
50+
Assert.AreEqual(AwsStsHost, request.Headers["host"]);
51+
Assert.AreEqual(SnowflakeAudience, request.Headers["x-snowflake-audience"]);
52+
Assert.AreEqual(ExpectedAmazonDate, request.Headers["x-amz-date"]);
53+
Assert.AreEqual(AwsToken, request.Headers["x-amz-security-token"]);
54+
Assert.AreEqual(s_expectedAuthorization, request.Headers["authorization"]);
55+
}
56+
}
57+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using NUnit.Framework;
2+
using Snowflake.Data.Core.Authenticator.WorkflowIdentity;
3+
4+
namespace Snowflake.Data.Tests.UnitTests.Authenticator.WorkflowIdentity
5+
{
6+
[TestFixture]
7+
public class WorkflowIdentityAwsAttestationRetrieverTest
8+
{
9+
[Test]
10+
[TestCase("cn-northwest-1", "sts.cn-northwest-1.amazonaws.com.cn")]
11+
[TestCase("us-east-1", "sts.us-east-1.amazonaws.com")]
12+
public void TestGetStsHost(string region, string expectedHost)
13+
{
14+
// act
15+
var host = WorkflowIdentityAwsAttestationRetriever.GetStsHostName(region);
16+
17+
// assert
18+
Assert.AreEqual(expectedHost, host);
19+
}
20+
}
21+
}

0 commit comments

Comments
 (0)