0
# AWS Requests Auth
1
2
AWS signature version 4 signing process implementation for Python requests library. Enables secure authentication to AWS services with comprehensive support for temporary credentials and automatic credential discovery through botocore integration.
3
4
## Package Information
5
6
- **Package Name**: aws-requests-auth
7
- **Language**: Python
8
- **Installation**: `pip install aws-requests-auth`
9
- **Dependencies**: requests >= 0.14.0
10
- **Optional Dependencies**: botocore (for automatic credential discovery)
11
12
## Core Imports
13
14
```python
15
from aws_requests_auth.aws_auth import AWSRequestsAuth
16
```
17
18
For automatic credential discovery:
19
20
```python
21
from aws_requests_auth.boto_utils import BotoAWSRequestsAuth, get_credentials
22
```
23
24
For low-level signing utilities (internal use):
25
26
```python
27
from aws_requests_auth.aws_auth import sign, getSignatureKey
28
```
29
30
## Basic Usage
31
32
### Manual Credential Authentication
33
34
```python
35
import requests
36
from aws_requests_auth.aws_auth import AWSRequestsAuth
37
38
# Create authentication instance with explicit credentials
39
auth = AWSRequestsAuth(
40
aws_access_key='YOUR_ACCESS_KEY',
41
aws_secret_access_key='YOUR_SECRET_KEY',
42
aws_host='search-service-example.us-east-1.es.amazonaws.com',
43
aws_region='us-east-1',
44
aws_service='es'
45
)
46
47
# Use with requests
48
response = requests.get(
49
'https://search-service-example.us-east-1.es.amazonaws.com',
50
auth=auth
51
)
52
```
53
54
### Automatic Credential Discovery
55
56
```python
57
import requests
58
from aws_requests_auth.boto_utils import BotoAWSRequestsAuth
59
60
# Credentials auto-discovered from environment, config files, or IAM role
61
auth = BotoAWSRequestsAuth(
62
aws_host='search-service-example.us-east-1.es.amazonaws.com',
63
aws_region='us-east-1',
64
aws_service='es'
65
)
66
67
response = requests.get(
68
'https://search-service-example.us-east-1.es.amazonaws.com',
69
auth=auth
70
)
71
```
72
73
### Integration with elasticsearch-py
74
75
```python
76
from aws_requests_auth.aws_auth import AWSRequestsAuth
77
from elasticsearch import Elasticsearch, RequestsHttpConnection
78
79
auth = AWSRequestsAuth(
80
aws_access_key='YOUR_ACCESS_KEY',
81
aws_secret_access_key='YOUR_SECRET_KEY',
82
aws_host='search-service-example.us-east-1.es.amazonaws.com',
83
aws_region='us-east-1',
84
aws_service='es'
85
)
86
87
es_client = Elasticsearch(
88
host='search-service-example.us-east-1.es.amazonaws.com',
89
port=443,
90
connection_class=RequestsHttpConnection,
91
http_auth=auth,
92
use_ssl=True
93
)
94
```
95
96
## Capabilities
97
98
### Manual Authentication
99
100
Primary authentication class for explicit credential management with full control over AWS signature version 4 signing process.
101
102
```python { .api }
103
class AWSRequestsAuth(requests.auth.AuthBase):
104
"""
105
Auth class for AWS services using signature version 4 signing process.
106
Implements requests.auth.AuthBase interface.
107
"""
108
109
def __init__(self, aws_access_key, aws_secret_access_key, aws_host,
110
aws_region, aws_service, aws_token=None):
111
"""
112
Initialize authentication with explicit credentials.
113
114
Parameters:
115
- aws_access_key (str): AWS access key ID
116
- aws_secret_access_key (str): AWS secret access key
117
- aws_host (str): AWS service hostname (e.g., 'service.region.amazonaws.com')
118
- aws_region (str): AWS region name (e.g., 'us-east-1')
119
- aws_service (str): AWS service name (e.g., 'es', 'execute-api')
120
- aws_token (str, optional): STS temporary credentials token
121
"""
122
123
def __call__(self, r):
124
"""
125
Adds AWS signature headers to request.
126
Called automatically by requests library.
127
128
Parameters:
129
- r (requests.Request): Request object to be signed
130
131
Returns:
132
requests.Request: Modified request with AWS signature headers
133
"""
134
135
def get_aws_request_headers_handler(self, r):
136
"""
137
Override point for custom credential handling.
138
Default implementation uses instance credentials.
139
140
Parameters:
141
- r (requests.Request): Request object
142
143
Returns:
144
dict: Dictionary of AWS authorization headers
145
"""
146
147
def get_aws_request_headers(self, r, aws_access_key, aws_secret_access_key,
148
aws_token=None):
149
"""
150
Generates AWS signature version 4 headers.
151
152
Parameters:
153
- r (requests.Request): Request object
154
- aws_access_key (str): AWS access key ID
155
- aws_secret_access_key (str): AWS secret access key
156
- aws_token (str, optional): STS token
157
158
Returns:
159
dict: Dictionary with Authorization, x-amz-date, x-amz-content-sha256 headers
160
"""
161
162
@classmethod
163
def get_canonical_path(cls, r):
164
"""
165
Creates canonical URI path for AWS signing.
166
Uses urllib quote with safe chars '/-_.~'
167
168
Parameters:
169
- r (requests.Request): Request object
170
171
Returns:
172
str: URL-encoded canonical path
173
"""
174
175
@classmethod
176
def get_canonical_querystring(cls, r):
177
"""
178
Creates canonical query string for AWS signing.
179
Assumes query parameters are already URL-encoded.
180
Sorts parameters by name as required by AWS.
181
182
Parameters:
183
- r (requests.Request): Request object
184
185
Returns:
186
str: Sorted, encoded query string
187
"""
188
```
189
190
### Automatic Credential Discovery
191
192
Authentication class that automatically discovers and refreshes AWS credentials using botocore's credential chain.
193
194
```python { .api }
195
class BotoAWSRequestsAuth(AWSRequestsAuth):
196
"""
197
Auto-refreshing authentication using botocore credential discovery.
198
Inherits from AWSRequestsAuth with automatic credential management.
199
Requires botocore package.
200
"""
201
202
def __init__(self, aws_host, aws_region, aws_service):
203
"""
204
Initialize with automatic credential discovery.
205
Credentials found via botocore credential chain:
206
- Environment variables
207
- AWS config files
208
- IAM role
209
- EC2 instance metadata
210
211
Parameters:
212
- aws_host (str): AWS service hostname
213
- aws_region (str): AWS region name
214
- aws_service (str): AWS service name
215
"""
216
217
def get_aws_request_headers_handler(self, r):
218
"""
219
Provides fresh credentials for each request.
220
Automatically refreshes expired credentials.
221
222
Parameters:
223
- r (requests.Request): Request object
224
225
Returns:
226
dict: Dictionary of AWS authorization headers with refreshed credentials
227
"""
228
229
def get_credentials(credentials_obj=None):
230
"""
231
Retrieves AWS credentials using botocore session.
232
233
Parameters:
234
- credentials_obj (botocore.credentials, optional): botocore credentials object
235
If None, creates new session
236
237
Returns:
238
dict: Dictionary with keys:
239
- aws_access_key (str): Access key ID
240
- aws_secret_access_key (str): Secret access key
241
- aws_token (str or None): Session token (None if not using temporary credentials)
242
"""
243
```
244
245
### Low-level Signing Utilities
246
247
Core signing functions used internally by AWSRequestsAuth. These are primarily for advanced users implementing custom AWS signature logic.
248
249
```python { .api }
250
def sign(key, msg):
251
"""
252
HMAC-SHA256 signing utility function.
253
Used internally for AWS signature generation.
254
255
Parameters:
256
- key (bytes): Signing key as bytes
257
- msg (str): Message to sign as string
258
259
Returns:
260
bytes: HMAC digest as bytes
261
"""
262
263
def getSignatureKey(key, dateStamp, regionName, serviceName):
264
"""
265
Creates AWS Signature Version 4 signing key.
266
Used internally for AWS signature generation.
267
268
Parameters:
269
- key (str): AWS secret access key
270
- dateStamp (str): Date stamp in YYYYMMDD format
271
- regionName (str): AWS region name
272
- serviceName (str): AWS service name
273
274
Returns:
275
bytes: Signing key as bytes
276
"""
277
```
278
279
## Common Use Cases
280
281
### AWS Elasticsearch Service
282
283
```python
284
from aws_requests_auth.aws_auth import AWSRequestsAuth
285
import requests
286
287
auth = AWSRequestsAuth(
288
aws_access_key='YOUR_KEY',
289
aws_secret_access_key='YOUR_SECRET',
290
aws_host='search-domain.us-east-1.es.amazonaws.com',
291
aws_region='us-east-1',
292
aws_service='es'
293
)
294
295
response = requests.get(
296
'https://search-domain.us-east-1.es.amazonaws.com/_cluster/health',
297
auth=auth
298
)
299
```
300
301
### AWS API Gateway with IAM Authentication
302
303
```python
304
from aws_requests_auth.boto_utils import BotoAWSRequestsAuth
305
import requests
306
307
auth = BotoAWSRequestsAuth(
308
aws_host='api.example.com',
309
aws_region='us-east-1',
310
aws_service='execute-api'
311
)
312
313
response = requests.post(
314
'https://api.example.com/prod/endpoint',
315
json={'data': 'value'},
316
auth=auth
317
)
318
```
319
320
### AWS Lambda with Environment Variables
321
322
```python
323
import os
324
from aws_requests_auth.aws_auth import AWSRequestsAuth
325
326
def lambda_handler(event, context):
327
auth = AWSRequestsAuth(
328
aws_access_key=os.environ['AWS_ACCESS_KEY_ID'],
329
aws_secret_access_key=os.environ['AWS_SECRET_ACCESS_KEY'],
330
aws_token=os.environ['AWS_SESSION_TOKEN'],
331
aws_host='service.region.amazonaws.com',
332
aws_region='us-east-1',
333
aws_service='es'
334
)
335
# Use auth with requests...
336
```
337
338
### Temporary Security Credentials (STS)
339
340
```python
341
from aws_requests_auth.aws_auth import AWSRequestsAuth
342
343
# Include aws_token for STS temporary credentials
344
auth = AWSRequestsAuth(
345
aws_access_key='TEMP_ACCESS_KEY',
346
aws_secret_access_key='TEMP_SECRET_KEY',
347
aws_token='SESSION_TOKEN', # Required for STS
348
aws_host='service.region.amazonaws.com',
349
aws_region='us-east-1',
350
aws_service='es'
351
)
352
```
353
354
## Error Handling
355
356
The authentication classes integrate with requests' error handling. Common issues:
357
358
- **Invalid credentials**: Results in HTTP 403 Forbidden responses
359
- **Incorrect region/service**: Results in HTTP 403 with AWS signature mismatch errors
360
- **Missing botocore**: ImportError when using BotoAWSRequestsAuth
361
- **Query parameter encoding**: Ensure parameters are URL-encoded before reaching canonical_querystring
362
363
## Cross-Platform Support
364
365
- **Python 2.7 and 3.x**: Full compatibility with automatic import handling
366
- **URL encoding**: Handles both Python 2 (urllib) and Python 3 (urllib.parse) imports
367
- **String encoding**: Proper handling of unicode strings across Python versions