Local dev + Dependabot + SES infra fixes - #459
Conversation
LocalStack's unified image (2026.03.0+) requires an auth token. Pass it through from the environment and fail fast with actionable guidance when it's unset, instead of the cryptic exit-code-55 license error. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a pip ecosystem covering all six python_components manifests so their dependencies get update PRs and security alerts, closing the gap where only bundler/npm/actions were watched. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
| open-pull-requests-limit: 10 | ||
| cooldown: | ||
| default-days: 7 | ||
| - package-ecosystem: pip |
There was a problem hiding this comment.
Dependabot pip entries added without requiring or referencing lockfiles or hashed requirements; add/verify lockfiles (with hashes) for '/python_components/*' to prevent silent upgrades.
Details
✨ AI Reasoning
The added pip update block enables Dependabot for multiple python_components directories but does not enforce or reference lockfile usage or checksum verification (e.g., requirements.txt with hashes or Pipfile.lock). Enabling automated updates without ensuring lockfile/hash-based installs can allow silent upgrades that the rule aims to prevent. The change is confined to the new pip configuration lines in the dependabot.yml diff.
🔧 How do I fix it?
Include lockfiles in your repo and CI. Pin exact versions or SHAs in manifests. Enable checksum verification. Set ignore-scripts in npm or equivalent. Enforce a 72hr minimum package age policy to avoid newly published malicious packages.
Reply @AikidoSec feedback: [FEEDBACK] to get better review comments in the future.
Reply @AikidoSec ignore: [REASON] to ignore this issue.
More info
| module "ses" { | ||
| name = "${var.project_name}-${var.environment}-ses" | ||
| source = "github.com/cloudposse/terraform-aws-ses" | ||
| source = "github.com/cloudposse/terraform-aws-ses?ref=v0.25.2" |
There was a problem hiding this comment.
module source pinned to tag '?ref=v0.25.2' but not to an immutable commit SHA or checksum; prefer a commit SHA (or checksum) for stronger immutability.
Details
✨ AI Reasoning
The change sets module source to a GitHub ref query using a tag (v0.25.2) rather than an immutable commit SHA or including checksum verification. This aims to improve determinism over floating HEAD, but still allows the tag to be repointed or replaced in some workflows and lacks checksum validation. The edit occurs on the module source line and is the only change to the module's dependency declaration in this diff.
🔧 How do I fix it?
Include lockfiles in your repo and CI. Pin exact versions or SHAs in manifests. Enable checksum verification. Set ignore-scripts in npm or equivalent. Enforce a 72hr minimum package age policy to avoid newly published malicious packages.
Reply @AikidoSec feedback: [FEEDBACK] to get better review comments in the future.
Reply @AikidoSec ignore: [REASON] to ignore this issue.
More info
terraform/modules/ses/main.tf referenced cloudposse/terraform-aws-ses with no version ref (floating HEAD). An older module version created an auto-expiring SMTP access key (awsutils_expiring_iam_access_key, 30-day max_age); current upstream creates a plain non-rotating aws_iam_access_key. The floating ref made plans nondeterministic and triggered an expiring->regular key migration in CI that needs iam:DeleteAccessKey/ CreateAccessKey -- permissions the GitHub Actions role intentionally lacks. Pin to v0.25.2, which uses iam-system-user 1.2.1: a stable, non-rotating access key (iam_create_access_key defaults to true). No max_age knob is needed -- that variable does not exist in v0.25.2. Note: the expiring->regular switch is a one-time replacement requiring privileged IAM creds (not the CI role), and rotates the SMTP credentials, so SMTP_USER/SMTP_PASSWORD in Secrets Manager must be updated from the new key or outbound email breaks. After that single apply, CI deploys go green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
02fb5fc to
04c9666
Compare
|
Re: Aikido — "pip entries added without requiring/referencing lockfiles or hashed requirements." Acknowledged, and we're accepting this for now with the following rationale:
Net effect of this PR for the Python components: more visibility and alerting, no reduction in safety. |
Three small, independent infra/dev-tooling fixes.
1. LocalStack requires an auth token (local dev)
LocalStack's unified image (2026.03.0+) now requires
LOCALSTACK_AUTH_TOKEN.docker-compose.ymlnow passes it through and fails fast with actionable guidance when unset, instead of the cryptic exit-code-55 license error. Set it via a gitignored.envor your shell. (CfA qualifies for a free LocalStack OSS license.)2. Dependabot now monitors the Python components
Added a
pipecosystem covering all sixpython_components/*manifests (accessibility_scan,ci,classifier,crawler,document_inference,evaluation). Previously only bundler/npm/github-actions were watched, so Python deps got zero update PRs or security alerts.3. SES: pin module to stop key rotation
Root cause of the recurring red deploys:
terraform/modules/ses/main.tfreferencedcloudposse/terraform-aws-seswith no version ref (floating HEAD). An older module version created an auto-expiring SMTP access key (awsutils_expiring_iam_access_key, 30-daymax_age); current upstream creates a plain non-rotatingaws_iam_access_key. The floating ref made plans nondeterministic and triggered an expiring→regular key migration in CI that needsiam:DeleteAccessKey/iam:CreateAccessKey— permissions the GitHub Actions role intentionally lacks.Fix: pin to
v0.25.2, which usesiam-system-user1.2.1 — a stable, non-rotating access key (iam_create_access_keydefaults totrue, so the SMTP key is still created). Nomax_ageknob is needed; that variable does not exist in v0.25.2. The pin makes plans deterministic and matches what CI was already migrating toward. The old auto-rotation delivered no benefit anyway — it wrote to SSM, disconnected from the Secrets Manager values the app actually reads.Validation
max_ageargument (an earlieriam_access_key_max_age = 0attempt failedtofu planand was removed)🤖 Generated with Claude Code