singlestore-auth-iam 0.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- singlestore_auth_iam-0.4.0/.gitignore +184 -0
- singlestore_auth_iam-0.4.0/PKG-INFO +270 -0
- singlestore_auth_iam-0.4.0/README.md +232 -0
- singlestore_auth_iam-0.4.0/pyproject.toml +134 -0
- singlestore_auth_iam-0.4.0/src/s2iam/__init__.py +35 -0
- singlestore_auth_iam-0.4.0/src/s2iam/api.py +300 -0
- singlestore_auth_iam-0.4.0/src/s2iam/aws/__init__.py +271 -0
- singlestore_auth_iam-0.4.0/src/s2iam/azure/__init__.py +456 -0
- singlestore_auth_iam-0.4.0/src/s2iam/gcp/__init__.py +428 -0
- singlestore_auth_iam-0.4.0/src/s2iam/https.py +16 -0
- singlestore_auth_iam-0.4.0/src/s2iam/jwt.py +203 -0
- singlestore_auth_iam-0.4.0/src/s2iam/models.py +129 -0
- singlestore_auth_iam-0.4.0/tests/__init__.py +1 -0
- singlestore_auth_iam-0.4.0/tests/conftest.py +265 -0
- singlestore_auth_iam-0.4.0/tests/run_cloud_validation.sh +240 -0
- singlestore_auth_iam-0.4.0/tests/test_aws_irsa_detection.py +59 -0
- singlestore_auth_iam-0.4.0/tests/test_cloud_validation.py +311 -0
- singlestore_auth_iam-0.4.0/tests/test_fastpath.py +141 -0
- singlestore_auth_iam-0.4.0/tests/test_https.py +67 -0
- singlestore_auth_iam-0.4.0/tests/test_integration.py +275 -0
- singlestore_auth_iam-0.4.0/tests/test_models.py +130 -0
- singlestore_auth_iam-0.4.0/tests/test_production_server.py +153 -0
- singlestore_auth_iam-0.4.0/tests/test_server_utils.py +219 -0
- singlestore_auth_iam-0.4.0/tests/test_utils.py +86 -0
- singlestore_auth_iam-0.4.0/tests/testhelp.py +162 -0
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
*.egg-info/
|
|
24
|
+
.installed.cfg
|
|
25
|
+
*.egg
|
|
26
|
+
MANIFEST
|
|
27
|
+
|
|
28
|
+
# PyInstaller
|
|
29
|
+
# Usually these files are written by a python script from a template
|
|
30
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
31
|
+
*.manifest
|
|
32
|
+
*.spec
|
|
33
|
+
|
|
34
|
+
# Installer logs
|
|
35
|
+
pip-log.txt
|
|
36
|
+
pip-delete-this-directory.txt
|
|
37
|
+
|
|
38
|
+
# Unit test / coverage reports
|
|
39
|
+
htmlcov/
|
|
40
|
+
.tox/
|
|
41
|
+
.nox/
|
|
42
|
+
.coverage
|
|
43
|
+
.coverage.*
|
|
44
|
+
.cache
|
|
45
|
+
nosetests.xml
|
|
46
|
+
coverage.xml
|
|
47
|
+
*.cover
|
|
48
|
+
.hypothesis/
|
|
49
|
+
.pytest_cache/
|
|
50
|
+
|
|
51
|
+
# Translations
|
|
52
|
+
*.mo
|
|
53
|
+
*.pot
|
|
54
|
+
|
|
55
|
+
# Django stuff:
|
|
56
|
+
*.log
|
|
57
|
+
local_settings.py
|
|
58
|
+
db.sqlite3
|
|
59
|
+
|
|
60
|
+
# Flask stuff:
|
|
61
|
+
instance/
|
|
62
|
+
.webassets-cache
|
|
63
|
+
|
|
64
|
+
# Scrapy stuff:
|
|
65
|
+
.scrapy
|
|
66
|
+
|
|
67
|
+
# Sphinx documentation
|
|
68
|
+
docs/_build/
|
|
69
|
+
|
|
70
|
+
# PyBuilder
|
|
71
|
+
target/
|
|
72
|
+
|
|
73
|
+
# Jupyter Notebook
|
|
74
|
+
.ipynb_checkpoints
|
|
75
|
+
|
|
76
|
+
# IPython
|
|
77
|
+
profile_default/
|
|
78
|
+
ipython_config.py
|
|
79
|
+
|
|
80
|
+
# pyenv
|
|
81
|
+
.python-version
|
|
82
|
+
|
|
83
|
+
# celery beat schedule file
|
|
84
|
+
celerybeat-schedule
|
|
85
|
+
|
|
86
|
+
# SageMath parsed files
|
|
87
|
+
*.sage.py
|
|
88
|
+
|
|
89
|
+
# Environments
|
|
90
|
+
.env
|
|
91
|
+
.venv
|
|
92
|
+
env/
|
|
93
|
+
venv/
|
|
94
|
+
ENV/
|
|
95
|
+
env.bak/
|
|
96
|
+
venv.bak/
|
|
97
|
+
|
|
98
|
+
# Spyder project settings
|
|
99
|
+
.spyderproject
|
|
100
|
+
.spyproject
|
|
101
|
+
|
|
102
|
+
# Rope project settings
|
|
103
|
+
.ropeproject
|
|
104
|
+
|
|
105
|
+
# mkdocs documentation
|
|
106
|
+
/site
|
|
107
|
+
|
|
108
|
+
# mypy
|
|
109
|
+
.mypy_cache/
|
|
110
|
+
.dmypy.json
|
|
111
|
+
dmypy.json
|
|
112
|
+
|
|
113
|
+
# Pyre type checker
|
|
114
|
+
.pyre/
|
|
115
|
+
|
|
116
|
+
# Go specific
|
|
117
|
+
# Binaries for programs and plugins
|
|
118
|
+
*.exe
|
|
119
|
+
*.exe~
|
|
120
|
+
*.dll
|
|
121
|
+
*.so
|
|
122
|
+
*.dylib
|
|
123
|
+
|
|
124
|
+
# Test binary, built with `go test -c`
|
|
125
|
+
*.test
|
|
126
|
+
|
|
127
|
+
# Output of the go build program.
|
|
128
|
+
go/debug_gcp_assume_role/debug-gcp-assume-role
|
|
129
|
+
go/s2iam_example_server/s2iam-example-server
|
|
130
|
+
|
|
131
|
+
# Go module download cache
|
|
132
|
+
go/pkg/
|
|
133
|
+
go/bin/
|
|
134
|
+
|
|
135
|
+
# Dependency directories (remove the comment below to include it)
|
|
136
|
+
# vendor/
|
|
137
|
+
|
|
138
|
+
# IDE and editor files
|
|
139
|
+
.vscode/
|
|
140
|
+
.idea/
|
|
141
|
+
*.swp
|
|
142
|
+
*.swo
|
|
143
|
+
*~
|
|
144
|
+
|
|
145
|
+
# OS generated files
|
|
146
|
+
.DS_Store
|
|
147
|
+
.DS_Store?
|
|
148
|
+
._*
|
|
149
|
+
.Spotlight-V100
|
|
150
|
+
.Trashes
|
|
151
|
+
ehthumbs.db
|
|
152
|
+
Thumbs.db
|
|
153
|
+
|
|
154
|
+
# Temporary files
|
|
155
|
+
*.tmp
|
|
156
|
+
*.temp
|
|
157
|
+
.temporary/
|
|
158
|
+
|
|
159
|
+
# local evelopment-specific copilot instructions
|
|
160
|
+
.github/copilot-dev-guide.md
|
|
161
|
+
|
|
162
|
+
# Python-specific excludes
|
|
163
|
+
python/LICENSE
|
|
164
|
+
|
|
165
|
+
# === Project-specific ephemeral artifacts ===
|
|
166
|
+
*-log
|
|
167
|
+
|
|
168
|
+
# Coverage artifacts aggregated locally after remote download
|
|
169
|
+
go-coverage.out
|
|
170
|
+
python-coverage.xml
|
|
171
|
+
java-coverage.xml
|
|
172
|
+
go-coverage-*.out
|
|
173
|
+
python-coverage-*.xml
|
|
174
|
+
java-coverage-*.xml
|
|
175
|
+
|
|
176
|
+
# JaCoCo & Maven build outputs (Maven target/ already indirectly covered for python target but add explicit java target)
|
|
177
|
+
java/target/
|
|
178
|
+
|
|
179
|
+
# test junk
|
|
180
|
+
go/s2iam_test_server_info*.json
|
|
181
|
+
|
|
182
|
+
# Generated API docs (build with make docs-api-html or CI Pages deploy)
|
|
183
|
+
docs/api/api.html
|
|
184
|
+
docs/api/index.html
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: singlestore-auth-iam
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: SingleStore IAM authentication library for cloud providers
|
|
5
|
+
Project-URL: Homepage, https://github.com/singlestore-labs/singlestore-auth-iam
|
|
6
|
+
Project-URL: Repository, https://github.com/singlestore-labs/singlestore-auth-iam
|
|
7
|
+
Project-URL: Issues, https://github.com/singlestore-labs/singlestore-auth-iam/issues
|
|
8
|
+
Author: SingleStore Labs
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Requires-Python: >=3.9
|
|
20
|
+
Requires-Dist: aiohttp>=3.8.0
|
|
21
|
+
Requires-Dist: azure-identity>=1.12.0
|
|
22
|
+
Requires-Dist: boto3>=1.26.0
|
|
23
|
+
Requires-Dist: cryptography>=3.4.8
|
|
24
|
+
Requires-Dist: google-auth-oauthlib>=0.8.0
|
|
25
|
+
Requires-Dist: google-auth>=2.15.0
|
|
26
|
+
Requires-Dist: pyjwt>=2.6.0
|
|
27
|
+
Requires-Dist: requests>=2.28.0
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: black>=23.0.0; extra == 'dev'
|
|
30
|
+
Requires-Dist: flake8>=6.0.0; extra == 'dev'
|
|
31
|
+
Requires-Dist: isort>=5.12.0; extra == 'dev'
|
|
32
|
+
Requires-Dist: mypy>=1.0.0; extra == 'dev'
|
|
33
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
|
|
34
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
|
|
35
|
+
Requires-Dist: pytest>=7.0.0; extra == 'dev'
|
|
36
|
+
Requires-Dist: types-requests>=2.28.0; extra == 'dev'
|
|
37
|
+
Description-Content-Type: text/markdown
|
|
38
|
+
|
|
39
|
+
# SingleStore Auth IAM - Python Client Library
|
|
40
|
+
|
|
41
|
+
A Python client library for getting JWTs from SingleStore's IAM service when running in cloud environments (AWS, GCP, Azure).
|
|
42
|
+
|
|
43
|
+
## Installation
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
pip install singlestore-auth-iam
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Quick Start
|
|
50
|
+
|
|
51
|
+
```python
|
|
52
|
+
import asyncio
|
|
53
|
+
from s2iam import get_jwt_database
|
|
54
|
+
|
|
55
|
+
async def main():
|
|
56
|
+
# Get a JWT for database access
|
|
57
|
+
jwt = await get_jwt_database("your-workspace-group-id")
|
|
58
|
+
print(f"JWT: {jwt}")
|
|
59
|
+
|
|
60
|
+
# Or without workspace group ID
|
|
61
|
+
jwt = await get_jwt_database()
|
|
62
|
+
print(f"JWT: {jwt}")
|
|
63
|
+
|
|
64
|
+
if __name__ == "__main__":
|
|
65
|
+
asyncio.run(main())
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
For API gateway access:
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
import asyncio
|
|
72
|
+
from s2iam import get_jwt_api
|
|
73
|
+
|
|
74
|
+
async def main():
|
|
75
|
+
# Get a JWT for API gateway access
|
|
76
|
+
jwt = await get_jwt_api()
|
|
77
|
+
print(f"JWT: {jwt}")
|
|
78
|
+
|
|
79
|
+
if __name__ == "__main__":
|
|
80
|
+
asyncio.run(main())
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
That's it! The library automatically detects your cloud environment and gets the appropriate JWT.
|
|
84
|
+
|
|
85
|
+
## Configuration
|
|
86
|
+
|
|
87
|
+
### Environment Variables
|
|
88
|
+
|
|
89
|
+
- `S2IAM_SERVER_URL`: Custom authentication server URL (default: https://auth.singlestore.com)
|
|
90
|
+
- `S2IAM_DEBUGGING`: Set to "true" to enable debug logging
|
|
91
|
+
|
|
92
|
+
## Supported Environments
|
|
93
|
+
|
|
94
|
+
The library automatically detects and works in:
|
|
95
|
+
|
|
96
|
+
- **AWS**: EC2 instances, Lambda functions, ECS tasks
|
|
97
|
+
- **Google Cloud**: Compute Engine, Cloud Functions, Cloud Run
|
|
98
|
+
- **Azure**: Virtual Machines, Functions, Container Instances
|
|
99
|
+
|
|
100
|
+
## Error Handling
|
|
101
|
+
|
|
102
|
+
```python
|
|
103
|
+
from s2iam import get_jwt_database, CloudProviderNotFound
|
|
104
|
+
|
|
105
|
+
try:
|
|
106
|
+
jwt = await get_jwt_database("workspace-id")
|
|
107
|
+
except CloudProviderNotFound:
|
|
108
|
+
print("Not running in a supported cloud environment")
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Configuration
|
|
112
|
+
|
|
113
|
+
### Workspace Group ID
|
|
114
|
+
|
|
115
|
+
The `workspace_group_id` parameter is optional for `get_jwt_database()`. When provided, it scopes the JWT to a specific workspace group. When omitted (or `None`), the JWT may have broader access depending on your SingleStore configuration.
|
|
116
|
+
|
|
117
|
+
### Environment Variables
|
|
118
|
+
|
|
119
|
+
- `S2IAM_DEBUGGING`: Set to "true" to enable debug logging
|
|
120
|
+
- `S2IAM_SERVER_URL`: Custom authentication server URL (default: https://auth.singlestore.com)
|
|
121
|
+
|
|
122
|
+
### Provider-Specific Configuration
|
|
123
|
+
|
|
124
|
+
#### AWS
|
|
125
|
+
- Uses standard AWS SDK configuration (AWS_REGION, AWS_PROFILE, etc.)
|
|
126
|
+
- Supports IAM roles, EC2 instance profiles, and Lambda execution roles
|
|
127
|
+
|
|
128
|
+
#### GCP
|
|
129
|
+
- Uses Application Default Credentials (ADC)
|
|
130
|
+
- Supports service account impersonation via `GCE_METADATA_HOST`
|
|
131
|
+
|
|
132
|
+
#### Azure
|
|
133
|
+
- Uses Azure SDK configuration
|
|
134
|
+
- Supports managed identities and service principals
|
|
135
|
+
|
|
136
|
+
## API Reference
|
|
137
|
+
|
|
138
|
+
### Core Functions
|
|
139
|
+
|
|
140
|
+
#### `detect_provider(timeout=5.0, logger=None, clients=None)`
|
|
141
|
+
|
|
142
|
+
Automatically detect which cloud provider the application is running on.
|
|
143
|
+
|
|
144
|
+
**Parameters:**
|
|
145
|
+
- `timeout` (float): Detection timeout in seconds
|
|
146
|
+
- `logger` (Logger): Custom logger instance
|
|
147
|
+
- `clients` (List[CloudProviderClient]): Custom list of provider clients
|
|
148
|
+
|
|
149
|
+
**Returns:** `CloudProviderClient`
|
|
150
|
+
|
|
151
|
+
#### `get_jwt(jwt_type, workspace_group_id=None, server_url=None, **kwargs)`
|
|
152
|
+
|
|
153
|
+
Get a JWT from SingleStore's authentication service.
|
|
154
|
+
|
|
155
|
+
**Parameters:**
|
|
156
|
+
- `jwt_type` (JWTType): Type of JWT to request
|
|
157
|
+
- `workspace_group_id` (str): Workspace group ID
|
|
158
|
+
- `server_url` (str): Authentication server URL
|
|
159
|
+
- `**kwargs`: Additional provider-specific parameters
|
|
160
|
+
|
|
161
|
+
**Returns:** `str` (JWT)
|
|
162
|
+
|
|
163
|
+
### Cloud Provider Clients
|
|
164
|
+
|
|
165
|
+
All provider clients implement the `CloudProviderClient` interface:
|
|
166
|
+
|
|
167
|
+
#### Methods
|
|
168
|
+
|
|
169
|
+
- `detect()`: Test if running on this cloud provider
|
|
170
|
+
- `get_type()`: Get the provider type
|
|
171
|
+
- `assume_role(role_identifier)`: Assume a different role/identity
|
|
172
|
+
- `get_identity_headers(additional_params=None)`: Get authentication headers
|
|
173
|
+
|
|
174
|
+
### Models
|
|
175
|
+
|
|
176
|
+
#### `CloudIdentity`
|
|
177
|
+
|
|
178
|
+
Represents verified identity information:
|
|
179
|
+
|
|
180
|
+
```python
|
|
181
|
+
@dataclass
|
|
182
|
+
class CloudIdentity:
|
|
183
|
+
provider: CloudProviderType
|
|
184
|
+
identifier: str
|
|
185
|
+
account_id: str
|
|
186
|
+
region: str
|
|
187
|
+
resource_type: str
|
|
188
|
+
additional_claims: Dict[str, str]
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
#### `CloudProviderType`
|
|
192
|
+
|
|
193
|
+
Enum of supported cloud providers:
|
|
194
|
+
- `AWS`
|
|
195
|
+
- `GCP`
|
|
196
|
+
- `AZURE`
|
|
197
|
+
|
|
198
|
+
#### `JWTType`
|
|
199
|
+
|
|
200
|
+
Enum of JWT types:
|
|
201
|
+
- `DATABASE_ACCESS`
|
|
202
|
+
- `API_GATEWAY_ACCESS`
|
|
203
|
+
|
|
204
|
+
## Error Handling
|
|
205
|
+
|
|
206
|
+
The library defines several specific exceptions:
|
|
207
|
+
|
|
208
|
+
- `CloudProviderNotFound`: No cloud provider could be detected
|
|
209
|
+
- `ProviderNotDetected`: Provider not detected, call `detect()` first
|
|
210
|
+
- `ProviderIdentityUnavailable`: Provider detected but no identity available
|
|
211
|
+
- `AssumeRoleNotSupported`: Assume role not supported by provider
|
|
212
|
+
|
|
213
|
+
## Development
|
|
214
|
+
|
|
215
|
+
### Testing
|
|
216
|
+
|
|
217
|
+
Tests use the Go test server (`s2iam_test_server`) started with the new `--info-file` flag for deterministic startup (no stdout JSON parsing). Async tests require `pytest-asyncio` which is part of the `dev` extras.
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
# Install with dev dependencies
|
|
221
|
+
pip install -e .[dev]
|
|
222
|
+
|
|
223
|
+
# Run full test suite (cloud‑dependent tests skip outside cloud VMs)
|
|
224
|
+
pytest
|
|
225
|
+
|
|
226
|
+
# Coverage
|
|
227
|
+
pytest --cov=s2iam --cov-report=html
|
|
228
|
+
|
|
229
|
+
# Example: Just integration tests
|
|
230
|
+
pytest -k integration
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
Manual server run example (atomic startup):
|
|
234
|
+
|
|
235
|
+
```bash
|
|
236
|
+
go build -o s2iam_test_server ../go/cmd/s2iam_test_server
|
|
237
|
+
tmpfile=$(mktemp)
|
|
238
|
+
./s2iam_test_server --port=0 --info-file "$tmpfile" --shutdown-on-stdin-close &
|
|
239
|
+
while [ ! -s "$tmpfile" ]; do sleep 0.05; done
|
|
240
|
+
jq . "$tmpfile"
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### Code Quality
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
# Format
|
|
247
|
+
black src tests
|
|
248
|
+
isort src tests
|
|
249
|
+
|
|
250
|
+
# Static checks
|
|
251
|
+
flake8 src tests
|
|
252
|
+
mypy src
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## License
|
|
256
|
+
|
|
257
|
+
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
|
|
258
|
+
|
|
259
|
+
## Contributing
|
|
260
|
+
|
|
261
|
+
1. Fork the repository
|
|
262
|
+
2. Create a feature branch
|
|
263
|
+
3. Make your changes
|
|
264
|
+
4. Add tests for your changes
|
|
265
|
+
5. Run the test suite
|
|
266
|
+
6. Submit a pull request
|
|
267
|
+
|
|
268
|
+
## Support
|
|
269
|
+
|
|
270
|
+
For issues and questions, please use the [GitHub Issues](https://github.com/singlestore-labs/singlestore-auth-iam/issues) page.
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
# SingleStore Auth IAM - Python Client Library
|
|
2
|
+
|
|
3
|
+
A Python client library for getting JWTs from SingleStore's IAM service when running in cloud environments (AWS, GCP, Azure).
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install singlestore-auth-iam
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
import asyncio
|
|
15
|
+
from s2iam import get_jwt_database
|
|
16
|
+
|
|
17
|
+
async def main():
|
|
18
|
+
# Get a JWT for database access
|
|
19
|
+
jwt = await get_jwt_database("your-workspace-group-id")
|
|
20
|
+
print(f"JWT: {jwt}")
|
|
21
|
+
|
|
22
|
+
# Or without workspace group ID
|
|
23
|
+
jwt = await get_jwt_database()
|
|
24
|
+
print(f"JWT: {jwt}")
|
|
25
|
+
|
|
26
|
+
if __name__ == "__main__":
|
|
27
|
+
asyncio.run(main())
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
For API gateway access:
|
|
31
|
+
|
|
32
|
+
```python
|
|
33
|
+
import asyncio
|
|
34
|
+
from s2iam import get_jwt_api
|
|
35
|
+
|
|
36
|
+
async def main():
|
|
37
|
+
# Get a JWT for API gateway access
|
|
38
|
+
jwt = await get_jwt_api()
|
|
39
|
+
print(f"JWT: {jwt}")
|
|
40
|
+
|
|
41
|
+
if __name__ == "__main__":
|
|
42
|
+
asyncio.run(main())
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
That's it! The library automatically detects your cloud environment and gets the appropriate JWT.
|
|
46
|
+
|
|
47
|
+
## Configuration
|
|
48
|
+
|
|
49
|
+
### Environment Variables
|
|
50
|
+
|
|
51
|
+
- `S2IAM_SERVER_URL`: Custom authentication server URL (default: https://auth.singlestore.com)
|
|
52
|
+
- `S2IAM_DEBUGGING`: Set to "true" to enable debug logging
|
|
53
|
+
|
|
54
|
+
## Supported Environments
|
|
55
|
+
|
|
56
|
+
The library automatically detects and works in:
|
|
57
|
+
|
|
58
|
+
- **AWS**: EC2 instances, Lambda functions, ECS tasks
|
|
59
|
+
- **Google Cloud**: Compute Engine, Cloud Functions, Cloud Run
|
|
60
|
+
- **Azure**: Virtual Machines, Functions, Container Instances
|
|
61
|
+
|
|
62
|
+
## Error Handling
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
from s2iam import get_jwt_database, CloudProviderNotFound
|
|
66
|
+
|
|
67
|
+
try:
|
|
68
|
+
jwt = await get_jwt_database("workspace-id")
|
|
69
|
+
except CloudProviderNotFound:
|
|
70
|
+
print("Not running in a supported cloud environment")
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Configuration
|
|
74
|
+
|
|
75
|
+
### Workspace Group ID
|
|
76
|
+
|
|
77
|
+
The `workspace_group_id` parameter is optional for `get_jwt_database()`. When provided, it scopes the JWT to a specific workspace group. When omitted (or `None`), the JWT may have broader access depending on your SingleStore configuration.
|
|
78
|
+
|
|
79
|
+
### Environment Variables
|
|
80
|
+
|
|
81
|
+
- `S2IAM_DEBUGGING`: Set to "true" to enable debug logging
|
|
82
|
+
- `S2IAM_SERVER_URL`: Custom authentication server URL (default: https://auth.singlestore.com)
|
|
83
|
+
|
|
84
|
+
### Provider-Specific Configuration
|
|
85
|
+
|
|
86
|
+
#### AWS
|
|
87
|
+
- Uses standard AWS SDK configuration (AWS_REGION, AWS_PROFILE, etc.)
|
|
88
|
+
- Supports IAM roles, EC2 instance profiles, and Lambda execution roles
|
|
89
|
+
|
|
90
|
+
#### GCP
|
|
91
|
+
- Uses Application Default Credentials (ADC)
|
|
92
|
+
- Supports service account impersonation via `GCE_METADATA_HOST`
|
|
93
|
+
|
|
94
|
+
#### Azure
|
|
95
|
+
- Uses Azure SDK configuration
|
|
96
|
+
- Supports managed identities and service principals
|
|
97
|
+
|
|
98
|
+
## API Reference
|
|
99
|
+
|
|
100
|
+
### Core Functions
|
|
101
|
+
|
|
102
|
+
#### `detect_provider(timeout=5.0, logger=None, clients=None)`
|
|
103
|
+
|
|
104
|
+
Automatically detect which cloud provider the application is running on.
|
|
105
|
+
|
|
106
|
+
**Parameters:**
|
|
107
|
+
- `timeout` (float): Detection timeout in seconds
|
|
108
|
+
- `logger` (Logger): Custom logger instance
|
|
109
|
+
- `clients` (List[CloudProviderClient]): Custom list of provider clients
|
|
110
|
+
|
|
111
|
+
**Returns:** `CloudProviderClient`
|
|
112
|
+
|
|
113
|
+
#### `get_jwt(jwt_type, workspace_group_id=None, server_url=None, **kwargs)`
|
|
114
|
+
|
|
115
|
+
Get a JWT from SingleStore's authentication service.
|
|
116
|
+
|
|
117
|
+
**Parameters:**
|
|
118
|
+
- `jwt_type` (JWTType): Type of JWT to request
|
|
119
|
+
- `workspace_group_id` (str): Workspace group ID
|
|
120
|
+
- `server_url` (str): Authentication server URL
|
|
121
|
+
- `**kwargs`: Additional provider-specific parameters
|
|
122
|
+
|
|
123
|
+
**Returns:** `str` (JWT)
|
|
124
|
+
|
|
125
|
+
### Cloud Provider Clients
|
|
126
|
+
|
|
127
|
+
All provider clients implement the `CloudProviderClient` interface:
|
|
128
|
+
|
|
129
|
+
#### Methods
|
|
130
|
+
|
|
131
|
+
- `detect()`: Test if running on this cloud provider
|
|
132
|
+
- `get_type()`: Get the provider type
|
|
133
|
+
- `assume_role(role_identifier)`: Assume a different role/identity
|
|
134
|
+
- `get_identity_headers(additional_params=None)`: Get authentication headers
|
|
135
|
+
|
|
136
|
+
### Models
|
|
137
|
+
|
|
138
|
+
#### `CloudIdentity`
|
|
139
|
+
|
|
140
|
+
Represents verified identity information:
|
|
141
|
+
|
|
142
|
+
```python
|
|
143
|
+
@dataclass
|
|
144
|
+
class CloudIdentity:
|
|
145
|
+
provider: CloudProviderType
|
|
146
|
+
identifier: str
|
|
147
|
+
account_id: str
|
|
148
|
+
region: str
|
|
149
|
+
resource_type: str
|
|
150
|
+
additional_claims: Dict[str, str]
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
#### `CloudProviderType`
|
|
154
|
+
|
|
155
|
+
Enum of supported cloud providers:
|
|
156
|
+
- `AWS`
|
|
157
|
+
- `GCP`
|
|
158
|
+
- `AZURE`
|
|
159
|
+
|
|
160
|
+
#### `JWTType`
|
|
161
|
+
|
|
162
|
+
Enum of JWT types:
|
|
163
|
+
- `DATABASE_ACCESS`
|
|
164
|
+
- `API_GATEWAY_ACCESS`
|
|
165
|
+
|
|
166
|
+
## Error Handling
|
|
167
|
+
|
|
168
|
+
The library defines several specific exceptions:
|
|
169
|
+
|
|
170
|
+
- `CloudProviderNotFound`: No cloud provider could be detected
|
|
171
|
+
- `ProviderNotDetected`: Provider not detected, call `detect()` first
|
|
172
|
+
- `ProviderIdentityUnavailable`: Provider detected but no identity available
|
|
173
|
+
- `AssumeRoleNotSupported`: Assume role not supported by provider
|
|
174
|
+
|
|
175
|
+
## Development
|
|
176
|
+
|
|
177
|
+
### Testing
|
|
178
|
+
|
|
179
|
+
Tests use the Go test server (`s2iam_test_server`) started with the new `--info-file` flag for deterministic startup (no stdout JSON parsing). Async tests require `pytest-asyncio` which is part of the `dev` extras.
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
# Install with dev dependencies
|
|
183
|
+
pip install -e .[dev]
|
|
184
|
+
|
|
185
|
+
# Run full test suite (cloud‑dependent tests skip outside cloud VMs)
|
|
186
|
+
pytest
|
|
187
|
+
|
|
188
|
+
# Coverage
|
|
189
|
+
pytest --cov=s2iam --cov-report=html
|
|
190
|
+
|
|
191
|
+
# Example: Just integration tests
|
|
192
|
+
pytest -k integration
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Manual server run example (atomic startup):
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
go build -o s2iam_test_server ../go/cmd/s2iam_test_server
|
|
199
|
+
tmpfile=$(mktemp)
|
|
200
|
+
./s2iam_test_server --port=0 --info-file "$tmpfile" --shutdown-on-stdin-close &
|
|
201
|
+
while [ ! -s "$tmpfile" ]; do sleep 0.05; done
|
|
202
|
+
jq . "$tmpfile"
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Code Quality
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
# Format
|
|
209
|
+
black src tests
|
|
210
|
+
isort src tests
|
|
211
|
+
|
|
212
|
+
# Static checks
|
|
213
|
+
flake8 src tests
|
|
214
|
+
mypy src
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## License
|
|
218
|
+
|
|
219
|
+
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
|
|
220
|
+
|
|
221
|
+
## Contributing
|
|
222
|
+
|
|
223
|
+
1. Fork the repository
|
|
224
|
+
2. Create a feature branch
|
|
225
|
+
3. Make your changes
|
|
226
|
+
4. Add tests for your changes
|
|
227
|
+
5. Run the test suite
|
|
228
|
+
6. Submit a pull request
|
|
229
|
+
|
|
230
|
+
## Support
|
|
231
|
+
|
|
232
|
+
For issues and questions, please use the [GitHub Issues](https://github.com/singlestore-labs/singlestore-auth-iam/issues) page.
|