[SCRUM-622] refactor(auth): use Powertools secret retrieval for tokens from secrets manager - #212
Open
sh1un wants to merge 2 commits into
Open
Conversation
…ts manager (SCRUM-622)
[Auth Service] Preview Deployment Status
Test Results
🔍 Details
|
[RSVP Service] Preview Deployment Status
Test Results
🔍 Details
|
[Webhook Service] Preview Deployment Status
Test Results
🔍 Details
|
Comment on lines
42
to
49
| def _get_jwt_secret(): | ||
| global _jwt_secret_cache | ||
|
|
||
| if _jwt_secret_cache is not None: | ||
| return _jwt_secret_cache | ||
|
|
||
| jwt_secret_arn = os.getenv("JWT_SECRET_ARN") | ||
| if not jwt_secret_arn: | ||
| raise RuntimeError("JWT_SECRET_ARN environment variable is not set") | ||
|
|
||
| response = _secretsmanager_client.get_secret_value(SecretId=jwt_secret_arn) | ||
| secret_string = response.get("SecretString") | ||
| if not secret_string: | ||
| secret = get_secret(jwt_secret_arn) | ||
| if not secret: | ||
| raise RuntimeError("JWT secret is empty") |
Contributor
There was a problem hiding this comment.
Worth adding a logger for get_secret to get more info when there is an error:
sth like this:
try:
secret = get_secret(jwt_secret_arn)
except Exception as e:
logger.error("Failed to retrieve JWT secret: %s", e)
raise
Comment on lines
42
to
+51
| def _get_jwt_secret(): | ||
| global _jwt_secret_cache | ||
|
|
||
| if _jwt_secret_cache is not None: | ||
| return _jwt_secret_cache | ||
|
|
||
| jwt_secret_arn = os.getenv("JWT_SECRET_ARN") | ||
| if not jwt_secret_arn: | ||
| raise RuntimeError("JWT_SECRET_ARN environment variable is not set") | ||
|
|
||
| response = _secretsmanager_client.get_secret_value(SecretId=jwt_secret_arn) | ||
| secret_string = response.get("SecretString") | ||
| if not secret_string: | ||
| secret = get_secret(jwt_secret_arn) | ||
| if not secret: | ||
| raise RuntimeError("JWT secret is empty") | ||
|
|
||
| _jwt_secret_cache = secret_string | ||
| return _jwt_secret_cache | ||
| return secret |
Contributor
There was a problem hiding this comment.
Same here:
Worth adding a logger for get_secret to get more info when there is an error:
sth like this:
try:
secret = get_secret(jwt_secret_arn)
except Exception as e:
logger.error("Failed to retrieve JWT secret: %s", e)
raise
chungchihhan
approved these changes
Jul 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
This PR refactors all AWS Secrets Manager interactions across
webhook_service,auth_service, andrsvp_serviceto use AWS Lambda Powertools Parameters (v3.30.0) instead of raw boto3 calls.Motivation
Previously, each Lambda manually managed its own
boto3.client("secretsmanager")instance, handled JSON parsing, and in some cases implemented ad-hoc in-memory caching via global variables. This resulted in repeated boilerplate and inconsistency across services.Powertools Parameters provides:
transform="json"— eliminates manualjson.loads(response["SecretString"])GetParameterError) — makes exception handling predictableChanges per service
webhook_service/trigger_webhook/utils.py: RemovedSecretsManagerclass; replaced with module-levelget_access_token()usingget_secret(..., transform="json", force_fetch=True).force_fetch=Trueis intentional — access tokens are actively written byauth_serviceand must always be fetched fresh to avoid serving a stale token after rotation.email_service.py: Updated to import and call the newget_access_token()function directly; removedEmailService.__init__which previously existed solely to instantiateSecretsManager.auth_service/refresh_service_accounts_token/lambda_function.py: Replacedsecrets_client.get_secret_value()on the password read path withget_secret(..., transform="json"). Theupdate_secretwrite path remains on boto3 — Powertools Parameters is read-only. AddedGetParameterErrorto theexceptclause to properly catch Powertools-raised exceptions alongsideClientError.rsvp_service/get_rsvp_status/andrsvp_service/update_rsvp/jwt_util.py(both): Removed manualboto3.client("secretsmanager")instantiation and the global_jwt_secret_cachevariable. Replaced withget_secret(jwt_secret_arn)— Powertools handles caching transparently with the same effective behavior.Type of Change
Related Issues
SCRUM-622
Testing
previewenvironment via the CI/CD pipeline.webhook_servicewith a valid SurveyCake webhook payload and verify the email is sent successfully (confirmsget_access_tokenfetches a valid token).refresh_service_accounts_tokenLambda and verify the response shows"status": "success"for bothsurveycakeandpostmanaccounts (confirms password retrieval and token update still work).GET /rsvp/{run_id_participant_id}/statusandPATCH /rsvp/{run_id_participant_id}with a valid JWT and verify 200 responses (confirms JWT secret retrieval via Powertools).Screenshots/Videos
N/A — backend refactor with no API contract changes.
Checklist
console.logorprint()statements.Additional Notes
update_secretcall inauth_serviceintentionally remains on raw boto3 — Powertools Parameters does not support write operations.force_fetch=Trueinwebhook_servicebypasses the Powertools cache for access tokens only. This is necessary because these tokens are short-lived credentials written by a separate Lambda (auth_service) and must be read fresh on every invocation.