OAuth Timeout Tuning and IAM Key Rotation Documentation in Production Ops
What Was Done
During the 2026-07-03 nightly review, we made two significant changes to production ops infrastructure:
- Extended the interactive OAuth listener timeout in
repos/tools/reauth_jada_all.pyfrom 3 minutes to 2 hours - Documented IAM key rotation procedures in
jada-ops/decisions/2026-07-03-iam-key-rotation.md, with a critical security correction applied to redact active key IDs from committed documentation
Both changes address reliability and security in our manual operations workflow. The business operates a solo-operator charter booking system where infrastructure automation must be bulletproof—any downtime directly impacts client communications, payment processing, and scheduled deployments.
Technical Details: OAuth Listener Timeout
The reauth_jada_all.py tool manages OAuth token refresh across multiple service integrations used for client email and SMS dispatch. When manually invoked, it spawns a local HTTP listener to complete the OAuth code-exchange flow with third-party auth servers.
The original 3-minute timeout was too aggressive for real-world operator workflow. In practice:
- OAuth providers occasionally respond slowly (especially during regional outages)
- Operators may be interrupted mid-flow and return minutes later
- Network latency on residential connections can push exchange times to 2+ minutes
The 2-hour timeout allows operators to complete the full auth flow without racing the clock, while still expiring the listener before any unattended process runs indefinitely. This is safe because the tool is exclusively manual—it's not part of launchd crons or automated pipelines.
The change includes consistent updates to error messaging and exit paths. When the listener times out, it now clearly indicates the cause and suggests re-running the tool, rather than silently failing.
Infrastructure: Credential Management and IAM Key Rotation
Our AWS credential architecture separates production access keys across three profiles in ~/.aws/credentials:
- queenofsandiego — primary ops account for Lightsail instances, CloudFront cache invalidation, and Route53 DNS updates
- jada-client-comms — SQS queue credentials for async email/SMS dispatch to clients
- jada-payments — restricted scope for Stripe webhook verification and payment log auditing
The jada-ops/decisions/ directory documents rotation schedules and procedures. However, during the first implementation of this documentation, we initially committed the active access key ID for the primary profile. While key IDs alone are not cryptographic secrets (they're visible in CloudTrail logs), publishing them in git:
- Survives forever in repository history
- Is pushed to our Lightsail backup remote, spreading visibility
- Halves an attacker's search space if they obtain the secret access key from other sources
The corrected approach: reference keys by their rotation date and profile name (e.g., "the 2026-07-03 key in profile queenofsandiego") in all committed documentation. The actual key material lives exclusively in ~/.aws/credentials, which is:
- Git-ignored and never committed
- Stored locally on the ops machine with filesystem permissions (mode 0600)
- Not synced to Lightsail or any remote
- Rotated on a quarterly schedule with deactivation of old keys before deletion
Key Decisions
Why extend OAuth timeout rather than add retry logic? Retry loops in manual tools can mask real auth failures (provider outage, misconfigured secrets) and trick operators into re-invoking the tool repeatedly. A long timeout with clear error messaging is simpler and more operator-friendly.
Why separate key IDs from key material in documentation? This follows AWS security best practices for solo-operator shops: documentation can be shared (e.g., for future hire onboarding) without exposing live credentials. Key rotation dates are useful context; key IDs are not.
Why store credentials locally rather than in env vars or encrypted config files? The ~/.aws/credentials standard is battle-tested, tool-native (recognized by boto3, AWS CLI, Terraform), and makes credential inheritance deterministic. Splitting credentials across multiple files or environment-setting scripts creates foot-guns.
What's Next
The 2-hour OAuth timeout will be monitored over the next two weeks for any issues with unattended listeners. If no incidents arise, we'll consider extending launchd health-check intervals to match the new timeout window.
IAM key rotation documentation is now a living doc in jada-ops/decisions/, tracking each quarterly rotation and any profile-scope changes. The next scheduled rotation is 2026-10-03.
All client-communication dispatch (SMS via Twilio, email via SES) continues to run unchanged; these changes only affect the tooling that refreshes tokens upstream of those systems.