Repository navigation
Add Python toolkit with IAM auth token generator - #1
Conversation
…emove redundant newlines
…kage - Add Python 3.14 to the supported/tested versions (classifier + CI matrix). - Rename provider class ElastiCacheIAMAuth -> ElastiCacheIAMAuthTokenProvider for clarity and parity with the Java package. - Validate user_id against the ElastiCache user-id format (allowing the service-managed default.iam-user), and lowercase it before signing so a mixed-case id no longer yields a token the server rejects as WRONGPASS. - Consolidate bad-value validation into a single InvalidParameterError that names the offending parameter (botocore-style), keep TargetRequiredError distinct as a missing-required error, and collapse the region/credentials cases into one ConfigurationError. - Add known-answer signature tests asserting the exact signed token for both serverless and node-based caches, with the signing clock frozen; signatures cross-checked against botocore independently. - Raise the botocore floor to >=1.43.0 so the advertised minimum matches the API the test suite relies on.
|
|
||
| print("Token generated successfully!\n") | ||
| print(f"Token length: {len(token)} chars") | ||
| print(f"Token preview: {token[:80]}...") |
There was a problem hiding this comment.
Nit - I think it would be useful to display details from the resolved credentials in one of the examples. Could be a followup.
- Rename the base exception to ToolkitInputError so the name fits both CLI and programmatic use, and consolidate user errors to two: InvalidParameterError (bad value or parameter combination) and ConfigurationError (missing region or credentials), both inheriting the base. - Unify cache-name and user-id checks into one validate-and-normalize helper so every validator normalizes and returns consistently; derive the failure message from the accepted pattern instead of a hand-maintained description. - Trim comments that restated the code, keeping the ones that explain why.
| Install from source: | ||
|
|
||
| ```bash | ||
| python3 -m pip install -e ".[dev]" |
There was a problem hiding this comment.
should we add here the install from github instructions while we are working on publishing to pip?
| IAM authentication for ElastiCache requires presenting a short-lived | ||
| SigV4-signed token (valid for 15 minutes) as the connection password. This tool | ||
| handles the signing, eliminating the boilerplate and the several non-obvious | ||
| details that otherwise surface as an opaque `WRONGPASS` at connect time: | ||
|
|
||
| - The token is signed against the **cache name** (or replication group id), not | ||
| the connection endpoint DNS. | ||
| - Serverless caches sign `ResourceType=ServerlessCache`; node-based replication | ||
| groups omit it. The resource type is part of the signature, so it cannot be | ||
| corrected after the fact. | ||
| - Cache names are lowercased at creation time, so they must be signed in | ||
| lowercase. | ||
|
|
||
| A fresh token is signed on demand each time one is requested, so there is no | ||
| background refresh thread to manage and no stale-token window. Credentials are | ||
| re-read from the default AWS credential chain on every call, so rotated | ||
| credentials are picked up automatically. |
There was a problem hiding this comment.
The first paragraph as well as the bullet points are specific to implementation details, and IMO not relevant as part of a user-facing documentation. I'd rather explain the required input arguments, where the credentials are coming from, how the credentials provider prioritizes credentials, etc.
| ``` | ||
|
|
||
| The token is a bearer credential. Pass it via the client's password parameter or | ||
| `VALKEYCLI_AUTH` / `REDISCLI_AUTH`. |
There was a problem hiding this comment.
can we specify which Valkey client version supports VALKEYCLI_AUTH?
| ## Status | ||
|
|
||
| Proof of concept |
There was a problem hiding this comment.
I think we can remove this as well
- Accept an optional "default." prefix on the user_id pattern rather than the single literal "default.iam-user", so a new service-managed default.* user needs no code change. - Stop echoing the caller's value in InvalidParameterError; name the parameter and the accepted pattern only. Add a test that the value is never in the message. - Rewrite the README for a customer audience: separate install requirements from runtime requirements, document the arguments and the credential resolution order, note that VALKEYCLI_AUTH needs valkey-cli 9.0+ while REDISCLI_AUTH works with both clients, and drop implementation detail.
| - IAM-enabled user that has access to to the cache. | ||
| - AWS credentials on the default credential chain (environment variables, shared | ||
| config files, or an instance/container role), for an identity with the | ||
| `elasticache:Connect` permission to the cache. |
There was a problem hiding this comment.
Connect requires cache and user as resources in the policy.
What
Adds the
python/package of the Developer Toolkit for Amazon ElastiCache, with its first tool: ElastiCache IAM authentication tokens, available as a library and as a CLI.This PR is Python-only. The
java/package will follow in a separate PR.Why
IAM auth requires presenting a short-lived SigV4-signed token as the connection password. The signing has several non-obvious details that otherwise surface only as an opaque
WRONGPASSat connect time, so the tool encapsulates them:ResourceType=ServerlessCache; node-based replication groups omit it. It is part of the signature, so it cannot be corrected after the fact.Design notes
Token readiness. Tokens are signed on demand, Credentials are re-read from the default AWS credential chain on every call, so rotated credentials (SSO, assume-role, container, instance metadata) are picked up automatically.
Region resolution is explicit argument →
AWS_REGION→ session (AWS_DEFAULT_REGIONor config profile).AWS_REGIONis handled by this package because botocore does not read it — theawsCLI and the JS, Go, and Java SDKs all do, so without this a user whose region is set only there would have a workingawsCLI and an inexplicably failing toolkit.ToolkitUserErroris the contract between the tools and the CLI. Raising a subclass reports a single-line message and exit 1; anything else keeps its traceback as a toolkit bug. A second tool therefore needs only a subparser, with no CLI change.Packaging and CI
requires-python >= 3.10; tested on 3.10–3.13 across Linux, macOS, and Windows (8 test jobs + lint)setuptools >= 77for the PEP 639 license expressionpy.typedso the annotations are visible to consumersPrivate :: Do Not Upload— this is not ready to publish, and that classifier makes PyPI reject any uploadTesting
ruff checkandruff format --checkcleantwine checkpasses on bothpy.typedverified end-to-end: mypy in a separate venv resolves the annotations from the installed wheelStatus
Proof of concept — not yet ready for production use.
Licensed under Apache-2.0.