Repository: boto/botocore
Pull request #2816 (2022-11-19 20:11:23)

Move signature version selection to use service model
## Overview

This PR will fix a long standing bug in Botocore, moving signature resolution off using `endpoints.json` as the source of truth.

In previous releases, Botocore has ignored the service model's configured `signatureVersion` ([example](https://github.com/boto/botocore/blob/2df5c5baf51325b16b8d2891b74e4731cdfea06f/botocore/data/lambda/2015-03-31/service-2.json#L9)). Instead, it relied on either a service-specific configuration in `endpoints.json` or falling back to the partition default (sigv4). While the partition-level fallback wasn't intended, it was masked from the testing infrastructure due to every active service supporting sigv4.

As we introduce new signing schemes such as the recently added `bearer` auth, we are seeing these schemes ignored at the service level. To address this, this patch will now prefer the service configured `signatureVersion`. It will still be possible to supplement these through the endpoints.json file, but this method is on the deprecation path and may be removed in a future release.

We'd advise anyone relying on this method to ensure any user-owned service models have an appropriately configured `signatureVersion` in the their metadata. Alternatively, you may use the botocore Config option, `signature_version` as [detailed in the docs](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/configuration.html#using-the-config-object) to choose specific signature versions per client.

## Testing

To ensure we're not introducing regressions around signing, we validated all existing models `signatureVersion`'s match what was previously resolved in `endpoints.json`.

**Before**
<details>

```json
{
   "accessanalyzer":"v4",
   "account":"v4",
   "acm":"v4",
   "acm-pca":"v4",
   "alexaforbusiness":"v4",
   "amp":"v4",
   "amplify":"v4",
   "amplifybackend":"v4",
   "amplifyuibuilder":"v4",
   "apigateway":"v4",
   "apigatewaymanagementapi":"v4",
   "apigatewayv2":"v4",
   "appconfig":"v4",
   "appconfigdata":"v4",
   "appflow":"v4",
   "appintegrations":"v4",
   "application-autoscaling":"v4",
   "application-insights":"v4",
   "applicationcostprofiler":"v4",
   "appmesh":"v4",
   "apprunner":"v4",
   "appstream":"v4",
   "appsync":"v4",
   "athena":"v4",
   "auditmanager":"v4",
   "autoscaling":"v4",
   "autoscaling-plans":"v4",
   "backup":"v4",
   "backup-gateway":"v4",
   "backupstorage":"v4",
   "batch":"v4",
   "billingconductor":"v4",
   "braket":"v4",
   "budgets":"v4",
   "ce":"v4",
   "chime":"v4",
   "chime-sdk-identity":"v4",
   "chime-sdk-media-pipelines":"v4",
   "chime-sdk-meetings":"v4",
   "chime-sdk-messaging":"v4",
   "cloud9":"v4",
   "cloudcontrol":"v4",
   "clouddirectory":"v4",
   "cloudformation":"v4",
   "cloudfront":"v4",
   "cloudhsm":"v4",
   "cloudhsmv2":"v4",
   "cloudsearch":"v4",
   "cloudsearchdomain":"v4",
   "cloudtrail":"v4",
   "cloudwatch":"v4",
   "codeartifact":"v4",
   "codebuild":"v4",
   "codecommit":"v4",
   "codedeploy":"v4",
   "codeguru-reviewer":"v4",
   "codeguruprofiler":"v4",
   "codepipeline":"v4",
   "codestar":"v4",
   "codestar-connections":"v4",
   "codestar-notifications":"v4",
   "cognito-identity":"v4",
   "cognito-idp":"v4",
   "cognito-sync":"v4",
   "comprehend":"v4",
   "comprehendmedical":"v4",
   "compute-optimizer":"v4",
   "config":"v4",
   "connect":"v4",
   "connect-contact-lens":"v4",
   "connectcampaigns":"v4",
   "connectcases":"v4",
   "connectparticipant":"v4",
   "controltower":"v4",
   "cur":"v4",
   "customer-profiles":"v4",
   "databrew":"v4",
   "dataexchange":"v4",
   "datapipeline":"v4",
   "datasync":"v4",
   "dax":"v4",
   "detective":"v4",
   "devicefarm":"v4",
   "devops-guru":"v4",
   "directconnect":"v4",
   "discovery":"v4",
   "dlm":"v4",
   "dms":"v4",
   "docdb":"v4",
   "drs":"v4",
   "ds":"v4",
   "dynamodb":"v4",
   "dynamodbstreams":"v4",
   "ebs":"v4",
   "ec2":"v4",
   "ec2-instance-connect":"v4",
   "ecr":"v4",
   "ecr-public":"v4",
   "ecs":"v4",
   "efs":"v4",
   "eks":"v4",
   "elastic-inference":"v4",
   "elasticache":"v4",
   "elasticbeanstalk":"v4",
   "elastictranscoder":"v4",
   "elb":"v4",
   "elbv2":"v4",
   "emr":"v4",
   "emr-containers":"v4",
   "emr-serverless":"v4",
   "es":"v4",
   "events":"v4",
   "evidently":"v4",
   "finspace":"v4",
   "finspace-data":"v4",
   "firehose":"v4",
   "fis":"v4",
   "fms":"v4",
   "forecast":"v4",
   "forecastquery":"v4",
   "frauddetector":"v4",
   "fsx":"v4",
   "gamelift":"v4",
   "gamesparks":"v4",
   "glacier":"v4",
   "globalaccelerator":"v4",
   "glue":"v4",
   "grafana":"v4",
   "greengrass":"v4",
   "greengrassv2":"v4",
   "groundstation":"v4",
   "guardduty":"v4",
   "health":"v4",
   "healthlake":"v4",
   "honeycode":"v4",
   "iam":"v4",
   "identitystore":"v4",
   "imagebuilder":"v4",
   "importexport":"v4",
   "inspector":"v4",
   "inspector2":"v4",
   "iot":"v4",
   "iot-data":"v4",
   "iot-jobs-data":"v4",
   "iot1click-devices":"v4",
   "iot1click-projects":"v4",
   "iotanalytics":"v4",
   "iotdeviceadvisor":"v4",
   "iotevents":"v4",
   "iotevents-data":"v4",
   "iotfleethub":"v4",
   "iotfleetwise":"v4",
   "iotsecuretunneling":"v4",
   "iotsitewise":"v4",
   "iotthingsgraph":"v4",
   "iottwinmaker":"v4",
   "iotwireless":"v4",
   "ivs":"v4",
   "ivschat":"v4",
   "kafka":"v4",
   "kafkaconnect":"v4",
   "kendra":"v4",
   "keyspaces":"v4",
   "kinesis":"v4",
   "kinesis-video-archived-media":"v4",
   "kinesis-video-media":"v4",
   "kinesis-video-signaling":"v4",
   "kinesisanalytics":"v4",
   "kinesisanalyticsv2":"v4",
   "kinesisvideo":"v4",
   "kms":"v4",
   "lakeformation":"v4",
   "lambda":"v4",
   "lex-models":"v4",
   "lex-runtime":"v4",
   "lexv2-models":"v4",
   "lexv2-runtime":"v4",
   "license-manager":"v4",
   "license-manager-user-subscriptions":"v4",
   "lightsail":"v4",
   "location":"v4",
   "logs":"v4",
   "lookoutequipment":"v4",
   "lookoutmetrics":"v4",
   "lookoutvision":"v4",
   "m2":"v4",
   "machinelearning":"v4",
   "macie":"v4",
   "macie2":"v4",
   "managedblockchain":"v4",
   "marketplace-catalog":"v4",
   "marketplace-entitlement":"v4",
   "marketplacecommerceanalytics":"v4",
   "mediaconnect":"v4",
   "mediaconvert":"v4",
   "medialive":"v4",
   "mediapackage":"v4",
   "mediapackage-vod":"v4",
   "mediastore":"v4",
   "mediastore-data":"v4",
   "mediatailor":"v4",
   "memorydb":"v4",
   "meteringmarketplace":"v4",
   "mgh":"v4",
   "mgn":"v4",
   "migration-hub-refactor-spaces":"v4",
   "migrationhub-config":"v4",
   "migrationhuborchestrator":"v4",
   "migrationhubstrategy":"v4",
   "mobile":"v4",
   "mq":"v4",
   "mturk":"v4",
   "mwaa":"v4",
   "neptune":"v4",
   "network-firewall":"v4",
   "networkmanager":"v4",
   "nimble":"v4",
   "opensearch":"v4",
   "opsworks":"v4",
   "opsworkscm":"v4",
   "organizations":"v4",
   "outposts":"v4",
   "panorama":"v4",
   "personalize":"v4",
   "personalize-events":"v4",
   "personalize-runtime":"v4",
   "pi":"v4",
   "pinpoint":"v4",
   "pinpoint-email":"v4",
   "pinpoint-sms-voice":"v4",
   "pinpoint-sms-voice-v2":"v4",
   "polly":"v4",
   "pricing":"v4",
   "privatenetworks":"v4",
   "proton":"v4",
   "qldb":"v4",
   "qldb-session":"v4",
   "quicksight":"v4",
   "ram":"v4",
   "rbin":"v4",
   "rds":"v4",
   "rds-data":"v4",
   "redshift":"v4",
   "redshift-data":"v4",
   "redshift-serverless":"v4",
   "rekognition":"v4",
   "resiliencehub":"v4",
   "resource-explorer-2":"v4",
   "resource-groups":"v4",
   "resourcegroupstaggingapi":"v4",
   "robomaker":"v4",
   "rolesanywhere":"v4",
   "route53":"v4",
   "route53-recovery-cluster":"v4",
   "route53-recovery-control-config":"v4",
   "route53-recovery-readiness":"v4",
   "route53domains":"v4",
   "route53resolver":"v4",
   "rum":"v4",
   "s3":"s3v4",
   "s3control":"s3v4",
   "s3outposts":"v4",
   "sagemaker":"v4",
   "sagemaker-a2i-runtime":"v4",
   "sagemaker-edge":"v4",
   "sagemaker-featurestore-runtime":"v4",
   "sagemaker-runtime":"v4",
   "savingsplans":"v4",
   "scheduler":"v4",
   "schemas":"v4",
   "sdb":"v2",
   "secretsmanager":"v4",
   "securityhub":"v4",
   "serverlessrepo":"v4",
   "service-quotas":"v4",
   "servicecatalog":"v4",
   "servicecatalog-appregistry":"v4",
   "servicediscovery":"v4",
   "ses":"v4",
   "sesv2":"v4",
   "shield":"v4",
   "signer":"v4",
   "sms":"v4",
   "sms-voice":"v4",
   "snow-device-management":"v4",
   "snowball":"v4",
   "sns":"v4",
   "sqs":"v4",
   "ssm":"v4",
   "ssm-contacts":"v4",
   "ssm-incidents":"v4",
   "sso":"v4",
   "sso-admin":"v4",
   "sso-oidc":"v4",
   "stepfunctions":"v4",
   "storagegateway":"v4",
   "sts":"v4",
   "support":"v4",
   "support-app":"v4",
   "swf":"v4",
   "synthetics":"v4",
   "textract":"v4",
   "timestream-query":"v4",
   "timestream-write":"v4",
   "transcribe":"v4",
   "transfer":"v4",
   "translate":"v4",
   "voice-id":"v4",
   "waf":"v4",
   "waf-regional":"v4",
   "wafv2":"v4",
   "wellarchitected":"v4",
   "wisdom":"v4",
   "workdocs":"v4",
   "worklink":"v4",
   "workmail":"v4",
   "workmailmessageflow":"v4",
   "workspaces":"v4",
   "workspaces-web":"v4",
   "xray":"v4"
}
```
</details>

**After**

<details>

```json
{
   "accessanalyzer":"v4",
   "account":"v4",
   "acm":"v4",
   "acm-pca":"v4",
   "alexaforbusiness":"v4",
   "amp":"v4",
   "amplify":"v4",
   "amplifybackend":"v4",
   "amplifyuibuilder":"v4",
   "apigateway":"v4",
   "apigatewaymanagementapi":"v4",
   "apigatewayv2":"v4",
   "appconfig":"v4",
   "appconfigdata":"v4",
   "appflow":"v4",
   "appintegrations":"v4",
   "application-autoscaling":"v4",
   "application-insights":"v4",
   "applicationcostprofiler":"v4",
   "appmesh":"v4",
   "apprunner":"v4",
   "appstream":"v4",
   "appsync":"v4",
   "athena":"v4",
   "auditmanager":"v4",
   "autoscaling":"v4",
   "autoscaling-plans":"v4",
   "backup":"v4",
   "backup-gateway":"v4",
   "backupstorage":"v4",
   "batch":"v4",
   "billingconductor":"v4",
   "braket":"v4",
   "budgets":"v4",
   "ce":"v4",
   "chime":"v4",
   "chime-sdk-identity":"v4",
   "chime-sdk-media-pipelines":"v4",
   "chime-sdk-meetings":"v4",
   "chime-sdk-messaging":"v4",
   "cloud9":"v4",
   "cloudcontrol":"v4",
   "clouddirectory":"v4",
   "cloudformation":"v4",
   "cloudfront":"v4",
   "cloudhsm":"v4",
   "cloudhsmv2":"v4",
   "cloudsearch":"v4",
   "cloudsearchdomain":"v4",
   "cloudtrail":"v4",
   "cloudwatch":"v4",
   "codeartifact":"v4",
   "codebuild":"v4",
   "codecommit":"v4",
   "codedeploy":"v4",
   "codeguru-reviewer":"v4",
   "codeguruprofiler":"v4",
   "codepipeline":"v4",
   "codestar":"v4",
   "codestar-connections":"v4",
   "codestar-notifications":"v4",
   "cognito-identity":"v4",
   "cognito-idp":"v4",
   "cognito-sync":"v4",
   "comprehend":"v4",
   "comprehendmedical":"v4",
   "compute-optimizer":"v4",
   "config":"v4",
   "connect":"v4",
   "connect-contact-lens":"v4",
   "connectcampaigns":"v4",
   "connectcases":"v4",
   "connectparticipant":"v4",
   "controltower":"v4",
   "cur":"v4",
   "customer-profiles":"v4",
   "databrew":"v4",
   "dataexchange":"v4",
   "datapipeline":"v4",
   "datasync":"v4",
   "dax":"v4",
   "detective":"v4",
   "devicefarm":"v4",
   "devops-guru":"v4",
   "directconnect":"v4",
   "discovery":"v4",
   "dlm":"v4",
   "dms":"v4",
   "docdb":"v4",
   "drs":"v4",
   "ds":"v4",
   "dynamodb":"v4",
   "dynamodbstreams":"v4",
   "ebs":"v4",
   "ec2":"v4",
   "ec2-instance-connect":"v4",
   "ecr":"v4",
   "ecr-public":"v4",
   "ecs":"v4",
   "efs":"v4",
   "eks":"v4",
   "elastic-inference":"v4",
   "elasticache":"v4",
   "elasticbeanstalk":"v4",
   "elastictranscoder":"v4",
   "elb":"v4",
   "elbv2":"v4",
   "emr":"v4",
   "emr-containers":"v4",
   "emr-serverless":"v4",
   "es":"v4",
   "events":"v4",
   "evidently":"v4",
   "finspace":"v4",
   "finspace-data":"v4",
   "firehose":"v4",
   "fis":"v4",
   "fms":"v4",
   "forecast":"v4",
   "forecastquery":"v4",
   "frauddetector":"v4",
   "fsx":"v4",
   "gamelift":"v4",
   "gamesparks":"v4",
   "glacier":"v4",
   "globalaccelerator":"v4",
   "glue":"v4",
   "grafana":"v4",
   "greengrass":"v4",
   "greengrassv2":"v4",
   "groundstation":"v4",
   "guardduty":"v4",
   "health":"v4",
   "healthlake":"v4",
   "honeycode":"v4",
   "iam":"v4",
   "identitystore":"v4",
   "imagebuilder":"v4",
   "importexport":"v2",
   "inspector":"v4",
   "inspector2":"v4",
   "iot":"v4",
   "iot-data":"v4",
   "iot-jobs-data":"v4",
   "iot1click-devices":"v4",
   "iot1click-projects":"v4",
   "iotanalytics":"v4",
   "iotdeviceadvisor":"v4",
   "iotevents":"v4",
   "iotevents-data":"v4",
   "iotfleethub":"v4",
   "iotfleetwise":"v4",
   "iotsecuretunneling":"v4",
   "iotsitewise":"v4",
   "iotthingsgraph":"v4",
   "iottwinmaker":"v4",
   "iotwireless":"v4",
   "ivs":"v4",
   "ivschat":"v4",
   "kafka":"v4",
   "kafkaconnect":"v4",
   "kendra":"v4",
   "keyspaces":"v4",
   "kinesis":"v4",
   "kinesis-video-archived-media":"v4",
   "kinesis-video-media":"v4",
   "kinesis-video-signaling":"v4",
   "kinesisanalytics":"v4",
   "kinesisanalyticsv2":"v4",
   "kinesisvideo":"v4",
   "kms":"v4",
   "lakeformation":"v4",
   "lambda":"v4",
   "lex-models":"v4",
   "lex-runtime":"v4",
   "lexv2-models":"v4",
   "lexv2-runtime":"v4",
   "license-manager":"v4",
   "license-manager-user-subscriptions":"v4",
   "lightsail":"v4",
   "location":"v4",
   "logs":"v4",
   "lookoutequipment":"v4",
   "lookoutmetrics":"v4",
   "lookoutvision":"v4",
   "m2":"v4",
   "machinelearning":"v4",
   "macie":"v4",
   "macie2":"v4",
   "managedblockchain":"v4",
   "marketplace-catalog":"v4",
   "marketplace-entitlement":"v4",
   "marketplacecommerceanalytics":"v4",
   "mediaconnect":"v4",
   "mediaconvert":"v4",
   "medialive":"v4",
   "mediapackage":"v4",
   "mediapackage-vod":"v4",
   "mediastore":"v4",
   "mediastore-data":"v4",
   "mediatailor":"v4",
   "memorydb":"v4",
   "meteringmarketplace":"v4",
   "mgh":"v4",
   "mgn":"v4",
   "migration-hub-refactor-spaces":"v4",
   "migrationhub-config":"v4",
   "migrationhuborchestrator":"v4",
   "migrationhubstrategy":"v4",
   "mobile":"v4",
   "mq":"v4",
   "mturk":"v4",
   "mwaa":"v4",
   "neptune":"v4",
   "network-firewall":"v4",
   "networkmanager":"v4",
   "nimble":"v4",
   "opensearch":"v4",
   "opsworks":"v4",
   "opsworkscm":"v4",
   "organizations":"v4",
   "outposts":"v4",
   "panorama":"v4",
   "personalize":"v4",
   "personalize-events":"v4",
   "personalize-runtime":"v4",
   "pi":"v4",
   "pinpoint":"v4",
   "pinpoint-email":"v4",
   "pinpoint-sms-voice":"v4",
   "pinpoint-sms-voice-v2":"v4",
   "polly":"v4",
   "pricing":"v4",
   "privatenetworks":"v4",
   "proton":"v4",
   "qldb":"v4",
   "qldb-session":"v4",
   "quicksight":"v4",
   "ram":"v4",
   "rbin":"v4",
   "rds":"v4",
   "rds-data":"v4",
   "redshift":"v4",
   "redshift-data":"v4",
   "redshift-serverless":"v4",
   "rekognition":"v4",
   "resiliencehub":"v4",
   "resource-explorer-2":"v4",
   "resource-groups":"v4",
   "resourcegroupstaggingapi":"v4",
   "robomaker":"v4",
   "rolesanywhere":"v4",
   "route53":"v4",
   "route53-recovery-cluster":"v4",
   "route53-recovery-control-config":"v4",
   "route53-recovery-readiness":"v4",
   "route53domains":"v4",
   "route53resolver":"v4",
   "rum":"v4",
   "s3":"s3v4",
   "s3control":"s3v4",
   "s3outposts":"v4",
   "sagemaker":"v4",
   "sagemaker-a2i-runtime":"v4",
   "sagemaker-edge":"v4",
   "sagemaker-featurestore-runtime":"v4",
   "sagemaker-runtime":"v4",
   "savingsplans":"v4",
   "scheduler":"v4",
   "schemas":"v4",
   "sdb":"v2",
   "secretsmanager":"v4",
   "securityhub":"v4",
   "serverlessrepo":"v4",
   "service-quotas":"v4",
   "servicecatalog":"v4",
   "servicecatalog-appregistry":"v4",
   "servicediscovery":"v4",
   "ses":"v4",
   "sesv2":"v4",
   "shield":"v4",
   "signer":"v4",
   "sms":"v4",
   "sms-voice":"v4",
   "snow-device-management":"v4",
   "snowball":"v4",
   "sns":"v4",
   "sqs":"v4",
   "ssm":"v4",
   "ssm-contacts":"v4",
   "ssm-incidents":"v4",
   "sso":"v4",
   "sso-admin":"v4",
   "sso-oidc":"v4",
   "stepfunctions":"v4",
   "storagegateway":"v4",
   "sts":"v4",
   "support":"v4",
   "support-app":"v4",
   "swf":"v4",
   "synthetics":"v4",
   "textract":"v4",
   "timestream-query":"v4",
   "timestream-write":"v4",
   "transcribe":"v4",
   "transfer":"v4",
   "translate":"v4",
   "voice-id":"v4",
   "waf":"v4",
   "waf-regional":"v4",
   "wafv2":"v4",
   "wellarchitected":"v4",
   "wisdom":"v4",
   "workdocs":"v4",
   "worklink":"v4",
   "workmail":"v4",
   "workmailmessageflow":"v4",
   "workspaces":"v4",
   "workspaces-web":"v4",
   "xray":"v4"
}
```
</details>


**Diff**
```diff
<    "importexport":"v4",
---
>    "importexport":"v2",
```

The only material change is `importexport` has been relying on the partition default to set itself to sigv4 instead of the deprecated sigv2 signing scheme. To resolve this, we've added a handler for this service to ensure it continues to map to sigv4.

codecov-commenter: # [Codecov](https://codecov.io/gh/boto/botocore/pull/2816?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=boto) Report
Base: **93.49**% // Head: **93.39**% // Decreases project coverage by **`-0.10%`** :warning:
> Coverage data is based on head [(`31e9ba8`)](https://codecov.io/gh/boto/botocore/pull/2816?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=boto) compared to base [(`191816f`)](https://codecov.io/gh/boto/botocore/commit/191816f776506cdbe228577119976883b6deb8c9?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=boto).
> Patch coverage: 46.66% of modified lines in pull request are covered.

<details><summary>Additional details and impacted files</summary>


```diff
@@             Coverage Diff             @@
##           develop    #2816      +/-   ##
===========================================
- Coverage    93.49%   93.39%   -0.11%     
===========================================
  Files           63       63              
  Lines        13346    13354       +8     
===========================================
- Hits         12478    12472       -6     
- Misses         868      882      +14     
```


| [Impacted Files](https://codecov.io/gh/boto/botocore/pull/2816?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=boto) | Coverage Δ | |
|---|---|---|
| [botocore/client.py](https://codecov.io/gh/boto/botocore/pull/2816/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=boto#diff-Ym90b2NvcmUvY2xpZW50LnB5) | `96.35% <46.66%> (-1.48%)` | :arrow_down: |
| [botocore/compat.py](https://codecov.io/gh/boto/botocore/pull/2816/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=boto#diff-Ym90b2NvcmUvY29tcGF0LnB5) | `91.33% <0.00%> (-1.34%)` | :arrow_down: |
| [botocore/hooks.py](https://codecov.io/gh/boto/botocore/pull/2816/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=boto#diff-Ym90b2NvcmUvaG9va3MucHk=) | `95.27% <0.00%> (-0.40%)` | :arrow_down: |
| [botocore/httpsession.py](https://codecov.io/gh/boto/botocore/pull/2816/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=boto#diff-Ym90b2NvcmUvaHR0cHNlc3Npb24ucHk=) | `91.40% <0.00%> (-0.40%)` | :arrow_down: |
| [botocore/utils.py](https://codecov.io/gh/boto/botocore/pull/2816/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=boto#diff-Ym90b2NvcmUvdXRpbHMucHk=) | `79.06% <0.00%> (-0.15%)` | :arrow_down: |
| [botocore/response.py](https://codecov.io/gh/boto/botocore/pull/2816/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=boto#diff-Ym90b2NvcmUvcmVzcG9uc2UucHk=) | `93.02% <0.00%> (-0.09%)` | :arrow_down: |
| [botocore/waiter.py](https://codecov.io/gh/boto/botocore/pull/2816/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=boto#diff-Ym90b2NvcmUvd2FpdGVyLnB5) | `98.28% <0.00%> (-0.01%)` | :arrow_down: |
| [botocore/paginate.py](https://codecov.io/gh/boto/botocore/pull/2816/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=boto#diff-Ym90b2NvcmUvcGFnaW5hdGUucHk=) | `97.80% <0.00%> (-0.01%)` | :arrow_down: |
| [botocore/auth.py](https://codecov.io/gh/boto/botocore/pull/2816/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=boto#diff-Ym90b2NvcmUvYXV0aC5weQ==) | `97.84% <0.00%> (-0.01%)` | :arrow_down: |
| [botocore/parsers.py](https://codecov.io/gh/boto/botocore/pull/2816/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=boto#diff-Ym90b2NvcmUvcGFyc2Vycy5weQ==) | `99.47% <0.00%> (-0.01%)` | :arrow_down: |

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=boto). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=boto)

</details>

[:umbrella: View full report at Codecov](https://codecov.io/gh/boto/botocore/pull/2816?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=boto).   
:loudspeaker: Do you have feedback about the report comment? [Let us know in this issue](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=boto).


Patch:
diff --git a/botocore/client.py b/botocore/client.py
index abf3be9c4..da92f3998 100644
--- a/botocore/client.py
+++ b/botocore/client.py
@@ -61,6 +61,18 @@ from botocore.utils import S3RegionRedirector  # noqa
 from botocore import UNSIGNED  # noqa
 
 
+_LEGACY_SIGNATURE_VERSIONS = frozenset(
+    (
+        'v2',
+        'v3',
+        'v3https',
+        'v4',
+        's3',
+        's3v4',
+    )
+)
+
+
 logger = logging.getLogger(__name__)
 history_recorder = get_global_history_recorder()
 
@@ -136,6 +148,9 @@ class ClientCreator:
             client_config,
             service_signing_name=service_model.metadata.get('signingName'),
             config_store=self._config_store,
+            service_signature_version=service_model.metadata.get(
+                'signatureVersion'
+            ),
         )
         client_args = self._get_client_args(
             service_model,
@@ -552,6 +567,7 @@ class ClientEndpointBridge:
         default_endpoint=None,
         service_signing_name=None,
         config_store=None,
+        service_signature_version=None,
     ):
         self.service_signing_name = service_signing_name
         self.endpoint_resolver = endpoint_resolver
@@ -559,6 +575,7 @@ class ClientEndpointBridge:
         self.client_config = client_config
         self.default_endpoint = default_endpoint or self.DEFAULT_ENDPOINT
         self.config_store = config_store
+        self.service_signature_version = service_signature_version
 
     def resolve(
         self, service_name, region_name=None, endpoint_url=None, is_secure=True
@@ -775,9 +792,18 @@ class ClientEndpointBridge:
         if configured_version is not None:
             return configured_version
 
+        potential_versions = resolved.get('signatureVersions', [])
+        if (
+            self.service_signature_version is not None
+            and self.service_signature_version
+            not in _LEGACY_SIGNATURE_VERSIONS
+        ):
+            # Prefer the service model as most specific
+            # source of truth for new signature versions.
+            potential_versions = [self.service_signature_version]
+
         # Pick a signature version from the endpoint metadata if present.
         if 'signatureVersions' in resolved:
-            potential_versions = resolved['signatureVersions']
             if service_name == 's3':
                 return 's3v4'
             if 'v4' in potential_versions:
@@ -788,7 +814,7 @@ class ClientEndpointBridge:
                 if known in AUTH_TYPE_MAPS:
                     return known
         raise UnknownSignatureVersionError(
-            signature_version=resolved.get('signatureVersions')
+            signature_version=potential_versions
         )
 
 


Test patch:
diff --git a/tests/functional/test_importexport.py b/tests/functional/test_importexport.py
new file mode 100644
index 000000000..eea885889
--- /dev/null
+++ b/tests/functional/test_importexport.py
@@ -0,0 +1,51 @@
+# Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+
+from tests import BaseSessionTest, ClientHTTPStubber
+
+
+class TestImportexport(BaseSessionTest):
+    def create_client_and_stubber(self, service_name, region_name=None):
+        if region_name is None:
+            region_name = 'us-west-2'
+
+        client = self.session.create_client(service_name, region_name)
+        http_stubber = ClientHTTPStubber(client)
+
+        return client, http_stubber
+
+    def test_importexport_signature_version(self):
+        """The importexport service has sigv2 registered as its "signature_version"
+        in the service model. While this was historically true, they migrated to
+        sigv4 with the introduction of endpoints.json.
+
+        This test ensures we always choose sigv4 regardless of what the model states.
+        """
+        client, stubber = self.create_client_and_stubber('importexport')
+        importexport_response = (
+            b'<?xml version="1.0" encoding="UTF-8"?>\n\n'
+            b"<CancelJobOutput>"
+            b"<CancelJobResult></CancelJobResult>"
+            b"</CancelJobOutput>"
+        )
+
+        # Confirm we've ignored the model signatureVersion and chosen v4
+        assert client.meta.config.signature_version == "v4"
+        with stubber:
+            stubber.add_response(body=importexport_response)
+            client.cancel_job(JobId="12345")
+
+        # Validate we actually signed with sigv4
+        auth_header = stubber.requests[0].headers.get('Authorization', '')
+        assert auth_header.startswith(b"AWS4-HMAC-SHA256")
+        assert b"aws4_request" in auth_header
diff --git a/tests/unit/test_client.py b/tests/unit/test_client.py
index 6a49f592f..c42920668 100644
--- a/tests/unit/test_client.py
+++ b/tests/unit/test_client.py
@@ -16,6 +16,7 @@ from contextlib import closing
 import botocore
 import botocore.config
 from botocore import client, exceptions, hooks
+from botocore.auth import AUTH_TYPE_MAPS, BaseSigner
 from botocore.client import ClientEndpointBridge
 from botocore.configprovider import (
     ChainProvider,
@@ -264,6 +265,20 @@ class TestAutoGeneratedClient(unittest.TestCase):
         )
         self.assertTrue(hasattr(service_client, 'test_operation'))
 
+    def test_client_with_nonstandard_signature_version(self):
+        self.service_description['metadata']['signatureVersion'] = 'foo'
+        creator = self.create_client_creator()
+        foo_signer = mock.Mock(spec=BaseSigner)
+
+        auth_types = AUTH_TYPE_MAPS.copy()
+        auth_types['foo'] = foo_signer
+
+        with mock.patch('botocore.client.AUTH_TYPE_MAPS', auth_types):
+            service_client = creator.create_client(
+                'myservice', 'us-west-2', credentials=self.credentials
+            )
+        assert service_client.meta.config.signature_version == 'foo'
+
     def test_client_method_docstring(self):
         creator = self.create_client_creator()
         service_client = creator.create_client(