Skip to content

Commit 421e62f

Browse files
committed
feat(sso): use SSOTokenProvider in SSOCredentialProvider
1 parent e5d0217 commit 421e62f

File tree

6 files changed

+59
-15
lines changed

6 files changed

+59
-15
lines changed

packages/credential-provider-ini/src/resolveSsoCredentials.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ import { SsoProfile } from "@aws-sdk/credential-provider-sso";
44
export { isSsoProfile } from "@aws-sdk/credential-provider-sso";
55

66
export const resolveSsoCredentials = (data: Partial<SsoProfile>) => {
7-
const { sso_start_url, sso_account_id, sso_region, sso_role_name } = validateSsoProfile(data);
7+
const { sso_start_url, sso_account_id, sso_session, sso_region, sso_role_name } = validateSsoProfile(data);
88
return fromSSO({
99
ssoStartUrl: sso_start_url,
1010
ssoAccountId: sso_account_id,
11+
ssoSession: sso_session,
1112
ssoRegion: sso_region,
1213
ssoRoleName: sso_role_name,
1314
})();

packages/credential-provider-sso/src/fromSSO.ts

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ export interface SsoCredentialsParameters {
1313
*/
1414
ssoStartUrl: string;
1515

16+
/**
17+
* SSO session identifier.
18+
* Presence implies usage of the SSOTokenProvider.
19+
*/
20+
ssoSession?: string;
21+
1622
/**
1723
* The ID of the AWS account to use for temporary credentials.
1824
*/
@@ -36,35 +42,65 @@ export interface FromSSOInit extends SourceProfileInit {
3642
/**
3743
* Creates a credential provider that will read from a credential_process specified
3844
* in ini files.
45+
*
46+
* The SSO credential provider must support both
47+
*
48+
* 1. the legacy profile format,
49+
* @example
50+
* ```
51+
* [profile sample-profile]
52+
* sso_account_id = 012345678901
53+
* sso_region = us-east-1
54+
* sso_role_name = SampleRole
55+
* sso_start_url = https://www.....com/start
56+
* ```
57+
*
58+
* 2. and the profile format for SSO Token Providers.
59+
* @example
60+
* ```
61+
* [profile sso-profile]
62+
* sso_session = dev
63+
* sso_account_id = 012345678901
64+
* sso_role_name = SampleRole
65+
*
66+
* [sso-session dev]
67+
* sso_region = us-east-1
68+
* sso_start_url = https://www.....com/start
69+
* ```
3970
*/
4071
export const fromSSO =
4172
(init: FromSSOInit & Partial<SsoCredentialsParameters> = {}): CredentialProvider =>
4273
async () => {
43-
const { ssoStartUrl, ssoAccountId, ssoRegion, ssoRoleName, ssoClient } = init;
44-
if (!ssoStartUrl && !ssoAccountId && !ssoRegion && !ssoRoleName) {
74+
const { ssoStartUrl, ssoAccountId, ssoRegion, ssoRoleName, ssoClient, ssoSession } = init;
75+
if (!ssoStartUrl && !ssoAccountId && !ssoRegion && !ssoRoleName && !ssoSession) {
4576
// Load the SSO config from shared AWS config file.
4677
const profiles = await parseKnownFiles(init);
4778
const profileName = getProfileName(init);
4879
const profile = profiles[profileName];
4980

81+
// TODO(sso): merge [sso-session X] data into the profile if sso_session exists in it.
82+
// TODO(sso): if the sso profile and the sso-session both have region and start URL,
83+
// TODO(sso): they must match or an error shall be thrown.
84+
5085
if (!isSsoProfile(profile)) {
5186
throw new CredentialsProviderError(`Profile ${profileName} is not configured with SSO credentials.`);
5287
}
5388

54-
const { sso_start_url, sso_account_id, sso_region, sso_role_name } = validateSsoProfile(profile);
89+
const { sso_start_url, sso_account_id, sso_region, sso_role_name, sso_session } = validateSsoProfile(profile);
5590
return resolveSSOCredentials({
5691
ssoStartUrl: sso_start_url,
92+
ssoSession: sso_session,
5793
ssoAccountId: sso_account_id,
5894
ssoRegion: sso_region,
5995
ssoRoleName: sso_role_name,
6096
ssoClient: ssoClient,
6197
});
62-
} else if (!ssoStartUrl || !ssoAccountId || !ssoRegion || !ssoRoleName) {
98+
} else if (!ssoStartUrl || !ssoAccountId || !ssoRegion || !ssoRoleName || !ssoSession) {
6399
throw new CredentialsProviderError(
64-
'Incomplete configuration. The fromSSO() argument hash must include "ssoStartUrl",' +
65-
' "ssoAccountId", "ssoRegion", "ssoRoleName"'
100+
'Incomplete configuration. The fromSSO() argument hash must include "ssoAccountId",' +
101+
' "ssoRegion", "ssoRoleName", and one of "ssoStartUrl" or "ssoSession".'
66102
);
67103
} else {
68-
return resolveSSOCredentials({ ssoStartUrl, ssoAccountId, ssoRegion, ssoRoleName, ssoClient });
104+
return resolveSSOCredentials({ ssoStartUrl, ssoSession, ssoAccountId, ssoRegion, ssoRoleName, ssoClient });
69105
}
70106
};

packages/credential-provider-sso/src/isSsoProfile.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,6 @@ export const isSsoProfile = (arg: Profile): arg is Partial<SsoProfile> =>
99
arg &&
1010
(typeof arg.sso_start_url === "string" ||
1111
typeof arg.sso_account_id === "string" ||
12+
typeof arg.sso_session === "string" ||
1213
typeof arg.sso_region === "string" ||
1314
typeof arg.sso_role_name === "string");

packages/credential-provider-sso/src/resolveSSOCredentials.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ const SHOULD_FAIL_CREDENTIAL_CHAIN = false;
1717

1818
export const resolveSSOCredentials = async ({
1919
ssoStartUrl,
20+
ssoSession,
2021
ssoAccountId,
2122
ssoRegion,
2223
ssoRoleName,
@@ -25,6 +26,10 @@ export const resolveSSOCredentials = async ({
2526
let token: SSOToken;
2627
const refreshMessage = `To refresh this SSO session run aws sso login with the corresponding profile.`;
2728
try {
29+
// TODO(sso): if (ssoSession)
30+
// TODO(sso): { use SSOTokenProvider }
31+
32+
// TODO(sso): else
2833
token = await getSSOTokenFromFile(ssoStartUrl);
2934
} catch (e) {
3035
throw new CredentialsProviderError(

packages/credential-provider-sso/src/types.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ export interface SSOToken {
1616
* @internal
1717
*/
1818
export interface SsoProfile extends Profile {
19-
sso_start_url: string;
19+
sso_start_url?: string;
20+
sso_session?: string;
2021
sso_account_id: string;
2122
sso_region: string;
2223
sso_role_name: string;

packages/credential-provider-sso/src/validateSsoProfile.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ import { SsoProfile } from "./types";
66
* @internal
77
*/
88
export const validateSsoProfile = (profile: Partial<SsoProfile>): SsoProfile => {
9-
const { sso_start_url, sso_account_id, sso_region, sso_role_name } = profile;
10-
if (!sso_start_url || !sso_account_id || !sso_region || !sso_role_name) {
9+
const { sso_start_url, sso_account_id, sso_session, sso_region, sso_role_name } = profile;
10+
if ((!sso_start_url && !sso_session) || !sso_account_id || !sso_region || !sso_role_name) {
1111
throw new CredentialsProviderError(
12-
`Profile is configured with invalid SSO credentials. Required parameters "sso_account_id", "sso_region", ` +
13-
`"sso_role_name", "sso_start_url". Got ${Object.keys(profile).join(
14-
", "
15-
)}\nReference: https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sso.html`,
12+
`Profile is configured with invalid SSO credentials. Required parameters "sso_region", ` +
13+
`"sso_role_name", "sso_account_id", and one of "sso_start_url" or "sso_session". Got ${Object.keys(
14+
profile
15+
).join(", ")}\nReference: https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sso.html`,
1616
false
1717
);
1818
}

0 commit comments

Comments
 (0)