Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(core/httpAuthSchemes): set configuration sources for sigv4a signingRegionSet #6368

Merged
merged 1 commit into from
Aug 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
// smithy-typescript generated code
import {
AwsSdkSigV4AAuthInputConfig,
AwsSdkSigV4AAuthResolvedConfig,
AwsSdkSigV4APreviouslyResolved,
AwsSdkSigV4AuthInputConfig,
AwsSdkSigV4AuthResolvedConfig,
AwsSdkSigV4PreviouslyResolved,
resolveAwsSdkSigV4AConfig,
resolveAwsSdkSigV4Config,
} from "@aws-sdk/core";
import { signatureV4CrtContainer } from "@aws-sdk/signature-v4-multi-region";
Expand Down Expand Up @@ -297,7 +301,7 @@ export const defaultCloudFrontKeyValueStoreHttpAuthSchemeProvider: CloudFrontKey
/**
* @internal
*/
export interface HttpAuthSchemeInputConfig extends AwsSdkSigV4AuthInputConfig {
export interface HttpAuthSchemeInputConfig extends AwsSdkSigV4AuthInputConfig, AwsSdkSigV4AAuthInputConfig {
/**
* Configuration of HttpAuthSchemes for a client which provides default identity providers and signers per auth scheme.
* @internal
Expand All @@ -314,7 +318,7 @@ export interface HttpAuthSchemeInputConfig extends AwsSdkSigV4AuthInputConfig {
/**
* @internal
*/
export interface HttpAuthSchemeResolvedConfig extends AwsSdkSigV4AuthResolvedConfig {
export interface HttpAuthSchemeResolvedConfig extends AwsSdkSigV4AuthResolvedConfig, AwsSdkSigV4AAuthResolvedConfig {
/**
* Configuration of HttpAuthSchemes for a client which provides default identity providers and signers per auth scheme.
* @internal
Expand All @@ -332,10 +336,11 @@ export interface HttpAuthSchemeResolvedConfig extends AwsSdkSigV4AuthResolvedCon
* @internal
*/
export const resolveHttpAuthSchemeConfig = <T>(
config: T & HttpAuthSchemeInputConfig & AwsSdkSigV4PreviouslyResolved
config: T & HttpAuthSchemeInputConfig & AwsSdkSigV4PreviouslyResolved & AwsSdkSigV4APreviouslyResolved
): T & HttpAuthSchemeResolvedConfig => {
const config_0 = resolveAwsSdkSigV4Config(config);
const config_1 = resolveAwsSdkSigV4AConfig(config_0);
return {
...config_0,
...config_1,
} as T & HttpAuthSchemeResolvedConfig;
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// @ts-ignore: package.json will be imported from dist folders
import packageInfo from "../package.json"; // eslint-disable-line

import { emitWarningIfUnsupportedVersion as awsCheckVersion } from "@aws-sdk/core";
import { NODE_SIGV4A_CONFIG_OPTIONS, emitWarningIfUnsupportedVersion as awsCheckVersion } from "@aws-sdk/core";
import { defaultProvider as credentialDefaultProvider } from "@aws-sdk/credential-provider-node";
import { defaultUserAgent } from "@aws-sdk/util-user-agent-node";
import {
Expand Down Expand Up @@ -52,6 +52,7 @@ export const getRuntimeConfig = (config: CloudFrontKeyValueStoreClientConfig) =>
default: async () => (await defaultConfigProvider()).retryMode || DEFAULT_RETRY_MODE,
}),
sha256: config?.sha256 ?? Hash.bind(null, "sha256"),
sigv4aSigningRegionSet: config?.sigv4aSigningRegionSet ?? loadNodeConfig(NODE_SIGV4A_CONFIG_OPTIONS),
streamCollector: config?.streamCollector ?? streamCollector,
useDualstackEndpoint: config?.useDualstackEndpoint ?? loadNodeConfig(NODE_USE_DUALSTACK_ENDPOINT_CONFIG_OPTIONS),
useFipsEndpoint: config?.useFipsEndpoint ?? loadNodeConfig(NODE_USE_FIPS_ENDPOINT_CONFIG_OPTIONS),
Expand Down
13 changes: 9 additions & 4 deletions clients/client-eventbridge/src/auth/httpAuthSchemeProvider.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
// smithy-typescript generated code
import {
AwsSdkSigV4AAuthInputConfig,
AwsSdkSigV4AAuthResolvedConfig,
AwsSdkSigV4APreviouslyResolved,
AwsSdkSigV4AuthInputConfig,
AwsSdkSigV4AuthResolvedConfig,
AwsSdkSigV4PreviouslyResolved,
resolveAwsSdkSigV4AConfig,
resolveAwsSdkSigV4Config,
} from "@aws-sdk/core";
import { signatureV4CrtContainer } from "@aws-sdk/signature-v4-multi-region";
Expand Down Expand Up @@ -279,7 +283,7 @@ export const defaultEventBridgeHttpAuthSchemeProvider: EventBridgeHttpAuthScheme
/**
* @internal
*/
export interface HttpAuthSchemeInputConfig extends AwsSdkSigV4AuthInputConfig {
export interface HttpAuthSchemeInputConfig extends AwsSdkSigV4AuthInputConfig, AwsSdkSigV4AAuthInputConfig {
/**
* Configuration of HttpAuthSchemes for a client which provides default identity providers and signers per auth scheme.
* @internal
Expand All @@ -296,7 +300,7 @@ export interface HttpAuthSchemeInputConfig extends AwsSdkSigV4AuthInputConfig {
/**
* @internal
*/
export interface HttpAuthSchemeResolvedConfig extends AwsSdkSigV4AuthResolvedConfig {
export interface HttpAuthSchemeResolvedConfig extends AwsSdkSigV4AuthResolvedConfig, AwsSdkSigV4AAuthResolvedConfig {
/**
* Configuration of HttpAuthSchemes for a client which provides default identity providers and signers per auth scheme.
* @internal
Expand All @@ -314,10 +318,11 @@ export interface HttpAuthSchemeResolvedConfig extends AwsSdkSigV4AuthResolvedCon
* @internal
*/
export const resolveHttpAuthSchemeConfig = <T>(
config: T & HttpAuthSchemeInputConfig & AwsSdkSigV4PreviouslyResolved
config: T & HttpAuthSchemeInputConfig & AwsSdkSigV4PreviouslyResolved & AwsSdkSigV4APreviouslyResolved
): T & HttpAuthSchemeResolvedConfig => {
const config_0 = resolveAwsSdkSigV4Config(config);
const config_1 = resolveAwsSdkSigV4AConfig(config_0);
return {
...config_0,
...config_1,
} as T & HttpAuthSchemeResolvedConfig;
};
3 changes: 2 additions & 1 deletion clients/client-eventbridge/src/runtimeConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// @ts-ignore: package.json will be imported from dist folders
import packageInfo from "../package.json"; // eslint-disable-line

import { emitWarningIfUnsupportedVersion as awsCheckVersion } from "@aws-sdk/core";
import { NODE_SIGV4A_CONFIG_OPTIONS, emitWarningIfUnsupportedVersion as awsCheckVersion } from "@aws-sdk/core";
import { defaultProvider as credentialDefaultProvider } from "@aws-sdk/credential-provider-node";
import { defaultUserAgent } from "@aws-sdk/util-user-agent-node";
import {
Expand Down Expand Up @@ -52,6 +52,7 @@ export const getRuntimeConfig = (config: EventBridgeClientConfig) => {
default: async () => (await defaultConfigProvider()).retryMode || DEFAULT_RETRY_MODE,
}),
sha256: config?.sha256 ?? Hash.bind(null, "sha256"),
sigv4aSigningRegionSet: config?.sigv4aSigningRegionSet ?? loadNodeConfig(NODE_SIGV4A_CONFIG_OPTIONS),
streamCollector: config?.streamCollector ?? streamCollector,
useDualstackEndpoint: config?.useDualstackEndpoint ?? loadNodeConfig(NODE_USE_DUALSTACK_ENDPOINT_CONFIG_OPTIONS),
useFipsEndpoint: config?.useFipsEndpoint ?? loadNodeConfig(NODE_USE_FIPS_ENDPOINT_CONFIG_OPTIONS),
Expand Down
13 changes: 9 additions & 4 deletions clients/client-s3/src/auth/httpAuthSchemeProvider.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
// smithy-typescript generated code
import {
AwsSdkSigV4AAuthInputConfig,
AwsSdkSigV4AAuthResolvedConfig,
AwsSdkSigV4APreviouslyResolved,
AwsSdkSigV4AuthInputConfig,
AwsSdkSigV4AuthResolvedConfig,
AwsSdkSigV4PreviouslyResolved,
resolveAwsSdkSigV4AConfig,
resolveAwsSdkSigV4Config,
} from "@aws-sdk/core";
import { signatureV4CrtContainer } from "@aws-sdk/signature-v4-multi-region";
Expand Down Expand Up @@ -281,7 +285,7 @@ export const defaultS3HttpAuthSchemeProvider: S3HttpAuthSchemeProvider = createE
/**
* @internal
*/
export interface HttpAuthSchemeInputConfig extends AwsSdkSigV4AuthInputConfig {
export interface HttpAuthSchemeInputConfig extends AwsSdkSigV4AuthInputConfig, AwsSdkSigV4AAuthInputConfig {
/**
* Configuration of HttpAuthSchemes for a client which provides default identity providers and signers per auth scheme.
* @internal
Expand All @@ -298,7 +302,7 @@ export interface HttpAuthSchemeInputConfig extends AwsSdkSigV4AuthInputConfig {
/**
* @internal
*/
export interface HttpAuthSchemeResolvedConfig extends AwsSdkSigV4AuthResolvedConfig {
export interface HttpAuthSchemeResolvedConfig extends AwsSdkSigV4AuthResolvedConfig, AwsSdkSigV4AAuthResolvedConfig {
/**
* Configuration of HttpAuthSchemes for a client which provides default identity providers and signers per auth scheme.
* @internal
Expand All @@ -316,10 +320,11 @@ export interface HttpAuthSchemeResolvedConfig extends AwsSdkSigV4AuthResolvedCon
* @internal
*/
export const resolveHttpAuthSchemeConfig = <T>(
config: T & HttpAuthSchemeInputConfig & AwsSdkSigV4PreviouslyResolved
config: T & HttpAuthSchemeInputConfig & AwsSdkSigV4PreviouslyResolved & AwsSdkSigV4APreviouslyResolved
): T & HttpAuthSchemeResolvedConfig => {
const config_0 = resolveAwsSdkSigV4Config(config);
const config_1 = resolveAwsSdkSigV4AConfig(config_0);
return {
...config_0,
...config_1,
} as T & HttpAuthSchemeResolvedConfig;
};
3 changes: 2 additions & 1 deletion clients/client-s3/src/runtimeConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// @ts-ignore: package.json will be imported from dist folders
import packageInfo from "../package.json"; // eslint-disable-line

import { emitWarningIfUnsupportedVersion as awsCheckVersion } from "@aws-sdk/core";
import { NODE_SIGV4A_CONFIG_OPTIONS, emitWarningIfUnsupportedVersion as awsCheckVersion } from "@aws-sdk/core";
import { defaultProvider as credentialDefaultProvider } from "@aws-sdk/credential-provider-node";
import { NODE_USE_ARN_REGION_CONFIG_OPTIONS } from "@aws-sdk/middleware-bucket-endpoint";
import { NODE_DISABLE_S3_EXPRESS_SESSION_AUTH_OPTIONS } from "@aws-sdk/middleware-sdk-s3";
Expand Down Expand Up @@ -62,6 +62,7 @@ export const getRuntimeConfig = (config: S3ClientConfig) => {
}),
sha1: config?.sha1 ?? Hash.bind(null, "sha1"),
sha256: config?.sha256 ?? Hash.bind(null, "sha256"),
sigv4aSigningRegionSet: config?.sigv4aSigningRegionSet ?? loadNodeConfig(NODE_SIGV4A_CONFIG_OPTIONS),
streamCollector: config?.streamCollector ?? streamCollector,
streamHasher: config?.streamHasher ?? streamHasher,
useArnRegion: config?.useArnRegion ?? loadNodeConfig(NODE_USE_ARN_REGION_CONFIG_OPTIONS),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,16 @@ public static boolean isSigV4Service(ServiceShape serviceShape) {
}

public static boolean isSigV4AsymmetricService(Model model, TypeScriptSettings settings) {
if (ENDPOINT_RULESET_HTTP_AUTH_SCHEME_SERVICES.contains(settings.getService())) {
return isSigV4AsymmetricService(model, settings.getService(model));
}

public static boolean isSigV4AsymmetricService(Model model, ServiceShape service) {
if (ENDPOINT_RULESET_HTTP_AUTH_SCHEME_SERVICES.contains(service.getId())) {
return true;
}

return ServiceIndex.of(model)
.getEffectiveAuthSchemes(settings.getService(), ServiceIndex.AuthSchemeMode.NO_AUTH_AWARE)
.getEffectiveAuthSchemes(service, ServiceIndex.AuthSchemeMode.NO_AUTH_AWARE)
.containsKey(SigV4ATrait.ID);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.function.Consumer;
import software.amazon.smithy.aws.traits.auth.SigV4ATrait;
import software.amazon.smithy.aws.traits.auth.SigV4Trait;
Expand Down Expand Up @@ -104,7 +105,8 @@ public Map<String, Consumer<TypeScriptWriter>> getRuntimeConfigWriters(
}
case NODE:
if (isAwsService(service)) {
return MapUtils.of(
Map<String, Consumer<TypeScriptWriter>> map = new TreeMap<String, Consumer<TypeScriptWriter>>();
map.put(
"credentialDefaultProvider", writer -> {
writer
.addDependency(AwsDependency.CREDENTIAL_PROVIDER_NODE)
Expand All @@ -114,6 +116,23 @@ public Map<String, Consumer<TypeScriptWriter>> getRuntimeConfigWriters(
AwsCredentialProviderUtils.addAwsCredentialProviderDependencies(service, writer);
}
);
if (isSigV4AsymmetricService(model, settings)) {
map.put(
"sigv4aSigningRegionSet", writer -> {
writer.addDependency(TypeScriptDependency.NODE_CONFIG_PROVIDER);
writer.addDependency(AwsDependency.AWS_SDK_CORE);
writer.addImport("loadConfig", "loadNodeConfig",
TypeScriptDependency.NODE_CONFIG_PROVIDER);
writer.addImport(
"NODE_SIGV4A_CONFIG_OPTIONS",
null,
AwsDependency.AWS_SDK_CORE
);
writer.write("loadNodeConfig(NODE_SIGV4A_CONFIG_OPTIONS)");
}
);
}
return map;
}
default:
return Collections.emptyMap();
Expand Down Expand Up @@ -180,6 +199,28 @@ public void customizeSupportedHttpAuthSchemes(
.getHttpAuthScheme(SigV4Trait.ID)
.toBuilder()
.schemeId(SigV4ATrait.ID)
.addResolveConfigFunction(ResolveConfigFunction.builder()
.resolveConfigFunction(Symbol.builder()
.name("resolveAwsSdkSigV4AConfig")
.namespace(AwsDependency.AWS_SDK_CORE.getPackageName(), "/")
.addDependency(AwsDependency.AWS_SDK_CORE)
.build())
.inputConfig(Symbol.builder()
.name("AwsSdkSigV4AAuthInputConfig")
.namespace(AwsDependency.AWS_SDK_CORE.getPackageName(), "/")
.addDependency(AwsDependency.AWS_SDK_CORE)
.build())
.previouslyResolved(Symbol.builder()
.name("AwsSdkSigV4APreviouslyResolved")
.namespace(AwsDependency.AWS_SDK_CORE.getPackageName(), "/")
.addDependency(AwsDependency.AWS_SDK_CORE)
.build())
.resolvedConfig(Symbol.builder()
.name("AwsSdkSigV4AAuthResolvedConfig")
.namespace(AwsDependency.AWS_SDK_CORE.getPackageName(), "/")
.addDependency(AwsDependency.AWS_SDK_CORE)
.build())
.build())
.putDefaultSigner(LanguageTarget.SHARED, w -> w
.addDependency(AwsDependency.AWS_SDK_CORE)
.addImport("AwsSdkSigV4ASigner", null, AwsDependency.AWS_SDK_CORE)
Expand Down
1 change: 1 addition & 0 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
"dependencies": {
"@smithy/core": "^2.3.2",
"@smithy/node-config-provider": "^3.1.4",
"@smithy/property-provider": "^3.1.3",
"@smithy/protocol-http": "^4.1.0",
"@smithy/signature-v4": "^4.1.0",
"@smithy/smithy-client": "^3.1.12",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,13 @@ export class AwsSdkSigV4ASigner extends AwsSdkSigV4Signer {
const { config, signer, signingRegion, signingRegionSet, signingName } = await validateSigningProperties(
signingProperties
);
const multiRegionOverride: string | undefined = signingRegionSet?.join?.(",") ?? signingRegion;

const configResolvedSigningRegionSet = await config.sigv4aSigningRegionSet?.();

const multiRegionOverride: string | undefined = (
configResolvedSigningRegionSet ??
signingRegionSet ?? [signingRegion]
).join(",");

const signedRequest = await signer.sign(httpRequest, {
signingDate: getSkewCorrectedDate(config.systemClockOffset),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
} from "@smithy/types";

import { getDateHeader, getSkewCorrectedDate, getUpdatedSystemClockOffset } from "../utils";
import { AwsSdkSigV4AAuthResolvedConfig } from "./resolveAwsSdkSigV4AConfig";

/**
* @internal
Expand All @@ -25,7 +26,7 @@ const throwSigningPropertyError = <T>(name: string, property: T | undefined): T
/**
* @internal
*/
interface AwsSdkSigV4Config {
interface AwsSdkSigV4Config extends AwsSdkSigV4AAuthResolvedConfig {
systemClockOffset: number;
signer: (authScheme?: AuthScheme) => Promise<RequestSigner>;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { AwsSdkSigV4Signer, AWSSDKSigV4Signer, validateSigningProperties } from "./AwsSdkSigV4Signer";
export { AwsSdkSigV4ASigner } from "./AwsSdkSigV4ASigner";
export * from "./resolveAwsSdkSigV4AConfig";
export * from "./resolveAwsSdkSigV4Config";
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { normalizeProvider } from "@smithy/core";
import { LoadedConfigSelectors } from "@smithy/node-config-provider";
import { ProviderError } from "@smithy/property-provider";
import { Profile, Provider } from "@smithy/types";

/**
* @public
*/
export interface AwsSdkSigV4AAuthInputConfig {
/**
* This option will override the AWS sigv4a
* signing regionSet from any other source.
*
* The lookup order is:
* 1. this value
* 2. configuration file value of sigv4a_signing_region_set.
* 3. environment value of AWS_SIGV4A_SIGNING_REGION_SET.
* 4. signingRegionSet given by endpoint resolution.
* 5. the singular region of the SDK client.
*/
sigv4aSigningRegionSet?: string[] | undefined | Provider<string[] | undefined>;
}

/**
* @internal
*/
export interface AwsSdkSigV4APreviouslyResolved {}

/**
* @internal
*/
export interface AwsSdkSigV4AAuthResolvedConfig {
sigv4aSigningRegionSet: Provider<string[] | undefined>;
}

/**
* @internal
*/
export const resolveAwsSdkSigV4AConfig = <T>(
config: T & AwsSdkSigV4AAuthInputConfig & AwsSdkSigV4APreviouslyResolved
): T & AwsSdkSigV4AAuthResolvedConfig => {
config.sigv4aSigningRegionSet = normalizeProvider(config.sigv4aSigningRegionSet ?? []);
return config as T & AwsSdkSigV4AAuthResolvedConfig;
};

/**
* @internal
*/
export const NODE_SIGV4A_CONFIG_OPTIONS: LoadedConfigSelectors<string[] | undefined> = {
environmentVariableSelector(env: Record<string, string | undefined>): string[] | undefined {
if (env.AWS_SIGV4A_SIGNING_REGION_SET) {
return env.AWS_SIGV4A_SIGNING_REGION_SET.split(",").map((_) => _.trim());
}
throw new ProviderError("AWS_SIGV4A_SIGNING_REGION_SET not set in env.", {
tryNextLink: true,
});
},
configFileSelector(profile: Profile): string[] | undefined {
if (profile.sigv4a_signing_region_set) {
return ((profile.sigv4a_signing_region_set as string) ?? "").split(",").map((_) => _.trim());
}
throw new ProviderError("sigv4a_signing_region_set not set in profile.", {
tryNextLink: true,
});
},
default: undefined,
};
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ export const initializeWithMaximalConfiguration = () => {
useGlobalEndpoint: false,
signingEscapePath: false,
bucketEndpoint: false,
sigv4aSigningRegionSet: [],
};

const s3 = new S3Client(config);
Expand Down
Loading