We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
STS calls to use regional endpoints instead of global endpoint
Change STS api calls to use regional STS endpoints to gain the benefits of "reduce latency, build in redundancy, and increase session token validity" as documented at https://docs.aws.amazon.com/general/latest/gr/rande.html#sts_region

This will also enable leveraging a VPC Endpoint for STS, if provisioned.  

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `c7n/credentials.py`
Content:
```
1 # Copyright 2016-2017 Capital One Services, LLC
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 """
15 Authentication utilities
16 """
17 from __future__ import absolute_import, division, print_function, unicode_literals
18 
19 import os
20 
21 from botocore.credentials import RefreshableCredentials
22 from botocore.session import get_session
23 from boto3 import Session
24 
25 from c7n.version import version
26 from c7n.utils import get_retry
27 
28 
29 class SessionFactory(object):
30 
31     def __init__(self, region, profile=None, assume_role=None, external_id=None):
32         self.region = region
33         self.profile = profile
34         self.assume_role = assume_role
35         self.external_id = external_id
36         self.user_agent_name = "CloudCustodian"
37         self.session_name = "CloudCustodian"
38         if 'C7N_SESSION_SUFFIX' in os.environ:
39             self.session_name = "%s@%s" % (
40                 self.session_name, os.environ['C7N_SESSION_SUFFIX'])
41         self._subscribers = []
42 
43     def _set_policy_name(self, name):
44         self.user_agent_name = ("CloudCustodian(%s)" % name).strip()
45 
46     policy_name = property(None, _set_policy_name)
47 
48     def __call__(self, assume=True, region=None):
49         if self.assume_role and assume:
50             session = Session(profile_name=self.profile)
51             session = assumed_session(
52                 self.assume_role, self.session_name, session,
53                 region or self.region, self.external_id)
54         else:
55             session = Session(
56                 region_name=region or self.region, profile_name=self.profile)
57 
58         return self.update(session)
59 
60     def update(self, session):
61         session._session.user_agent_name = self.user_agent_name
62         session._session.user_agent_version = version
63 
64         for s in self._subscribers:
65             s(session)
66 
67         return session
68 
69     def set_subscribers(self, subscribers):
70         self._subscribers = subscribers
71 
72 
73 def assumed_session(role_arn, session_name, session=None, region=None, external_id=None):
74     """STS Role assume a boto3.Session
75 
76     With automatic credential renewal.
77 
78     Args:
79       role_arn: iam role arn to assume
80       session_name: client session identifier
81       session: an optional extant session, note session is captured
82       in a function closure for renewing the sts assumed role.
83 
84     :return: a boto3 session using the sts assumed role credentials
85 
86     Notes: We have to poke at botocore internals a few times
87     """
88     if session is None:
89         session = Session()
90 
91     retry = get_retry(('Throttling',))
92 
93     def refresh():
94 
95         parameters = {"RoleArn": role_arn, "RoleSessionName": session_name}
96 
97         if external_id is not None:
98             parameters['ExternalId'] = external_id
99 
100         credentials = retry(
101             session.client('sts').assume_role, **parameters)['Credentials']
102         return dict(
103             access_key=credentials['AccessKeyId'],
104             secret_key=credentials['SecretAccessKey'],
105             token=credentials['SessionToken'],
106             # Silly that we basically stringify so it can be parsed again
107             expiry_time=credentials['Expiration'].isoformat())
108 
109     session_credentials = RefreshableCredentials.create_from_metadata(
110         metadata=refresh(),
111         refresh_using=refresh,
112         method='sts-assume-role')
113 
114     # so dirty.. it hurts, no clean way to set this outside of the
115     # internals poke. There's some work upstream on making this nicer
116     # but its pretty baroque as well with upstream support.
117     # https://github.com/boto/boto3/issues/443
118     # https://github.com/boto/botocore/issues/761
119 
120     s = get_session()
121     s._credentials = session_credentials
122     if region is None:
123         region = s.get_config_variable('region') or 'us-east-1'
124     s.set_config_variable('region', region)
125     return Session(botocore_session=s)
126
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/c7n/credentials.py b/c7n/credentials.py
--- a/c7n/credentials.py
+++ b/c7n/credentials.py
@@ -26,6 +26,10 @@
 from c7n.utils import get_retry
 
 
+# 0.8.45.1 compatibility with global only sts endpoints, out of caution, remove in 0.8.46.1
+USE_STS_GLOBAL = os.environ.get('C7N_USE_STS_GLOBAL', '').lower() in ('yes', 'true')
+
+
 class SessionFactory(object):
 
     def __init__(self, region, profile=None, assume_role=None, external_id=None):
@@ -98,7 +102,8 @@
             parameters['ExternalId'] = external_id
 
         credentials = retry(
-            session.client('sts').assume_role, **parameters)['Credentials']
+            get_sts_client(
+                session, region).assume_role, **parameters)['Credentials']
         return dict(
             access_key=credentials['AccessKeyId'],
             secret_key=credentials['SecretAccessKey'],
@@ -123,3 +128,20 @@
         region = s.get_config_variable('region') or 'us-east-1'
     s.set_config_variable('region', region)
     return Session(botocore_session=s)
+
+
+def get_sts_client(session, region):
+    """Get the AWS STS endpoint specific for the given region.
+
+    Returns the global endpoint if region is not specified.
+
+    For the list of regional endpoints, see https://amzn.to/2ohJgtR
+    """
+    if region and not USE_STS_GLOBAL:
+        endpoint_url = "https://sts.{}.amazonaws.com".format(region)
+        region_name = region
+    else:
+        endpoint_url = "https://sts.amazonaws.com"
+        region_name = None
+    return session.client(
+        'sts', endpoint_url=endpoint_url, region_name=region_name)

{"golden_diff": "diff --git a/c7n/credentials.py b/c7n/credentials.py\n--- a/c7n/credentials.py\n+++ b/c7n/credentials.py\n@@ -26,6 +26,10 @@\n from c7n.utils import get_retry\n \n \n+# 0.8.45.1 compatibility with global only sts endpoints, out of caution, remove in 0.8.46.1\n+USE_STS_GLOBAL = os.environ.get('C7N_USE_STS_GLOBAL', '').lower() in ('yes', 'true')\n+\n+\n class SessionFactory(object):\n \n     def __init__(self, region, profile=None, assume_role=None, external_id=None):\n@@ -98,7 +102,8 @@\n             parameters['ExternalId'] = external_id\n \n         credentials = retry(\n-            session.client('sts').assume_role, **parameters)['Credentials']\n+            get_sts_client(\n+                session, region).assume_role, **parameters)['Credentials']\n         return dict(\n             access_key=credentials['AccessKeyId'],\n             secret_key=credentials['SecretAccessKey'],\n@@ -123,3 +128,20 @@\n         region = s.get_config_variable('region') or 'us-east-1'\n     s.set_config_variable('region', region)\n     return Session(botocore_session=s)\n+\n+\n+def get_sts_client(session, region):\n+    \"\"\"Get the AWS STS endpoint specific for the given region.\n+\n+    Returns the global endpoint if region is not specified.\n+\n+    For the list of regional endpoints, see https://amzn.to/2ohJgtR\n+    \"\"\"\n+    if region and not USE_STS_GLOBAL:\n+        endpoint_url = \"https://sts.{}.amazonaws.com\".format(region)\n+        region_name = region\n+    else:\n+        endpoint_url = \"https://sts.amazonaws.com\"\n+        region_name = None\n+    return session.client(\n+        'sts', endpoint_url=endpoint_url, region_name=region_name)\n", "issue": "STS calls to use regional endpoints instead of global endpoint\nChange STS api calls to use regional STS endpoints to gain the benefits of \"reduce latency, build in redundancy, and increase session token validity\" as documented at https://docs.aws.amazon.com/general/latest/gr/rande.html#sts_region\r\n\r\nThis will also enable leveraging a VPC Endpoint for STS, if provisioned.  \n", "before_files": [{"content": "# Copyright 2016-2017 Capital One Services, LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\"\"\"\nAuthentication utilities\n\"\"\"\nfrom __future__ import absolute_import, division, print_function, unicode_literals\n\nimport os\n\nfrom botocore.credentials import RefreshableCredentials\nfrom botocore.session import get_session\nfrom boto3 import Session\n\nfrom c7n.version import version\nfrom c7n.utils import get_retry\n\n\nclass SessionFactory(object):\n\n    def __init__(self, region, profile=None, assume_role=None, external_id=None):\n        self.region = region\n        self.profile = profile\n        self.assume_role = assume_role\n        self.external_id = external_id\n        self.user_agent_name = \"CloudCustodian\"\n        self.session_name = \"CloudCustodian\"\n        if 'C7N_SESSION_SUFFIX' in os.environ:\n            self.session_name = \"%s@%s\" % (\n                self.session_name, os.environ['C7N_SESSION_SUFFIX'])\n        self._subscribers = []\n\n    def _set_policy_name(self, name):\n        self.user_agent_name = (\"CloudCustodian(%s)\" % name).strip()\n\n    policy_name = property(None, _set_policy_name)\n\n    def __call__(self, assume=True, region=None):\n        if self.assume_role and assume:\n            session = Session(profile_name=self.profile)\n            session = assumed_session(\n                self.assume_role, self.session_name, session,\n                region or self.region, self.external_id)\n        else:\n            session = Session(\n                region_name=region or self.region, profile_name=self.profile)\n\n        return self.update(session)\n\n    def update(self, session):\n        session._session.user_agent_name = self.user_agent_name\n        session._session.user_agent_version = version\n\n        for s in self._subscribers:\n            s(session)\n\n        return session\n\n    def set_subscribers(self, subscribers):\n        self._subscribers = subscribers\n\n\ndef assumed_session(role_arn, session_name, session=None, region=None, external_id=None):\n    \"\"\"STS Role assume a boto3.Session\n\n    With automatic credential renewal.\n\n    Args:\n      role_arn: iam role arn to assume\n      session_name: client session identifier\n      session: an optional extant session, note session is captured\n      in a function closure for renewing the sts assumed role.\n\n    :return: a boto3 session using the sts assumed role credentials\n\n    Notes: We have to poke at botocore internals a few times\n    \"\"\"\n    if session is None:\n        session = Session()\n\n    retry = get_retry(('Throttling',))\n\n    def refresh():\n\n        parameters = {\"RoleArn\": role_arn, \"RoleSessionName\": session_name}\n\n        if external_id is not None:\n            parameters['ExternalId'] = external_id\n\n        credentials = retry(\n            session.client('sts').assume_role, **parameters)['Credentials']\n        return dict(\n            access_key=credentials['AccessKeyId'],\n            secret_key=credentials['SecretAccessKey'],\n            token=credentials['SessionToken'],\n            # Silly that we basically stringify so it can be parsed again\n            expiry_time=credentials['Expiration'].isoformat())\n\n    session_credentials = RefreshableCredentials.create_from_metadata(\n        metadata=refresh(),\n        refresh_using=refresh,\n        method='sts-assume-role')\n\n    # so dirty.. it hurts, no clean way to set this outside of the\n    # internals poke. There's some work upstream on making this nicer\n    # but its pretty baroque as well with upstream support.\n    # https://github.com/boto/boto3/issues/443\n    # https://github.com/boto/botocore/issues/761\n\n    s = get_session()\n    s._credentials = session_credentials\n    if region is None:\n        region = s.get_config_variable('region') or 'us-east-1'\n    s.set_config_variable('region', region)\n    return Session(botocore_session=s)\n", "path": "c7n/credentials.py"}], "after_files": [{"content": "# Copyright 2016-2017 Capital One Services, LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\"\"\"\nAuthentication utilities\n\"\"\"\nfrom __future__ import absolute_import, division, print_function, unicode_literals\n\nimport os\n\nfrom botocore.credentials import RefreshableCredentials\nfrom botocore.session import get_session\nfrom boto3 import Session\n\nfrom c7n.version import version\nfrom c7n.utils import get_retry\n\n\n# 0.8.45.1 compatibility with global only sts endpoints, out of caution, remove in 0.8.46.1\nUSE_STS_GLOBAL = os.environ.get('C7N_USE_STS_GLOBAL', '').lower() in ('yes', 'true')\n\n\nclass SessionFactory(object):\n\n    def __init__(self, region, profile=None, assume_role=None, external_id=None):\n        self.region = region\n        self.profile = profile\n        self.assume_role = assume_role\n        self.external_id = external_id\n        self.user_agent_name = \"CloudCustodian\"\n        self.session_name = \"CloudCustodian\"\n        if 'C7N_SESSION_SUFFIX' in os.environ:\n            self.session_name = \"%s@%s\" % (\n                self.session_name, os.environ['C7N_SESSION_SUFFIX'])\n        self._subscribers = []\n\n    def _set_policy_name(self, name):\n        self.user_agent_name = (\"CloudCustodian(%s)\" % name).strip()\n\n    policy_name = property(None, _set_policy_name)\n\n    def __call__(self, assume=True, region=None):\n        if self.assume_role and assume:\n            session = Session(profile_name=self.profile)\n            session = assumed_session(\n                self.assume_role, self.session_name, session,\n                region or self.region, self.external_id)\n        else:\n            session = Session(\n                region_name=region or self.region, profile_name=self.profile)\n\n        return self.update(session)\n\n    def update(self, session):\n        session._session.user_agent_name = self.user_agent_name\n        session._session.user_agent_version = version\n\n        for s in self._subscribers:\n            s(session)\n\n        return session\n\n    def set_subscribers(self, subscribers):\n        self._subscribers = subscribers\n\n\ndef assumed_session(role_arn, session_name, session=None, region=None, external_id=None):\n    \"\"\"STS Role assume a boto3.Session\n\n    With automatic credential renewal.\n\n    Args:\n      role_arn: iam role arn to assume\n      session_name: client session identifier\n      session: an optional extant session, note session is captured\n      in a function closure for renewing the sts assumed role.\n\n    :return: a boto3 session using the sts assumed role credentials\n\n    Notes: We have to poke at botocore internals a few times\n    \"\"\"\n    if session is None:\n        session = Session()\n\n    retry = get_retry(('Throttling',))\n\n    def refresh():\n\n        parameters = {\"RoleArn\": role_arn, \"RoleSessionName\": session_name}\n\n        if external_id is not None:\n            parameters['ExternalId'] = external_id\n\n        credentials = retry(\n            get_sts_client(\n                session, region).assume_role, **parameters)['Credentials']\n        return dict(\n            access_key=credentials['AccessKeyId'],\n            secret_key=credentials['SecretAccessKey'],\n            token=credentials['SessionToken'],\n            # Silly that we basically stringify so it can be parsed again\n            expiry_time=credentials['Expiration'].isoformat())\n\n    session_credentials = RefreshableCredentials.create_from_metadata(\n        metadata=refresh(),\n        refresh_using=refresh,\n        method='sts-assume-role')\n\n    # so dirty.. it hurts, no clean way to set this outside of the\n    # internals poke. There's some work upstream on making this nicer\n    # but its pretty baroque as well with upstream support.\n    # https://github.com/boto/boto3/issues/443\n    # https://github.com/boto/botocore/issues/761\n\n    s = get_session()\n    s._credentials = session_credentials\n    if region is None:\n        region = s.get_config_variable('region') or 'us-east-1'\n    s.set_config_variable('region', region)\n    return Session(botocore_session=s)\n\n\ndef get_sts_client(session, region):\n    \"\"\"Get the AWS STS endpoint specific for the given region.\n\n    Returns the global endpoint if region is not specified.\n\n    For the list of regional endpoints, see https://amzn.to/2ohJgtR\n    \"\"\"\n    if region and not USE_STS_GLOBAL:\n        endpoint_url = \"https://sts.{}.amazonaws.com\".format(region)\n        region_name = region\n    else:\n        endpoint_url = \"https://sts.amazonaws.com\"\n        region_name = None\n    return session.client(\n        'sts', endpoint_url=endpoint_url, region_name=region_name)\n", "path": "c7n/credentials.py"}]}