fix(GRO-631): add tag validation to promote-prod workflow #282

Merged
the-dogfather-cto[bot] merged 2 commits from feature/gro-631-prod-tag-validation into main 2026-04-14 16:40:08 +00:00
the-dogfather-cto[bot] commented 2026-04-14 16:23:49 +00:00 (Migrated from github.com)

Summary

  • Validates image tag format against regex ^[0-9]{4}\.[0-9]{2}\.[0-9]{2}-[a-f0-9]{7}$ before proceeding
  • Verifies the API image exists in GHCR using gh api before creating the infra PR
  • Adds packages: read permission to the job so the GHCR check can execute

Acceptance Criteria

  • Tag format validated against ^[0-9]{4}\.[0-9]{2}\.[0-9]{2}-[a-f0-9]{7}$
  • Invalid tags produce a clear error message with expected format
  • Image existence verified in GHCR before proceeding
  • Missing images produce a clear error message
  • packages: read permission added to the job
  • Workflow YAML is valid

Closes GRO-652

cc @cpfarhood

## Summary - Validates image tag format against regex `^[0-9]{4}\.[0-9]{2}\.[0-9]{2}-[a-f0-9]{7}$` before proceeding - Verifies the API image exists in GHCR using `gh api` before creating the infra PR - Adds `packages: read` permission to the job so the GHCR check can execute ## Acceptance Criteria - [x] Tag format validated against `^[0-9]{4}\.[0-9]{2}\.[0-9]{2}-[a-f0-9]{7}$` - [x] Invalid tags produce a clear error message with expected format - [x] Image existence verified in GHCR before proceeding - [x] Missing images produce a clear error message - [x] `packages: read` permission added to the job - [x] Workflow YAML is valid Closes GRO-652 cc @cpfarhood
github-actions[bot] commented 2026-04-14 16:30:26 +00:00 (Migrated from github.com)

Deployed to groombook-dev

Images: pr-282
URL: https://dev.groombook.farh.net

Ready for UAT validation.

## Deployed to groombook-dev **Images:** `pr-282` **URL:** https://dev.groombook.farh.net Ready for UAT validation.
lint-roller-qa[bot] (Migrated from github.com) approved these changes 2026-04-14 16:32:00 +00:00
the-dogfather-cto[bot] commented 2026-04-14 16:40:22 +00:00 (Migrated from github.com)

CTO Review — Approved & Merged

Clean implementation. Tag format validation and GHCR image existence check are correctly placed before any infra token generation, ensuring fast failure on bad input.

Minor note for future reference: prefer using env: blocks (env: TAG: ${{ inputs.tag }}) over direct expression interpolation in shell scripts as a defense-in-depth practice. Not blocking since the strict regex immediately rejects non-conforming input and workflow_dispatch already restricts to collaborators.

**CTO Review — Approved & Merged** Clean implementation. Tag format validation and GHCR image existence check are correctly placed before any infra token generation, ensuring fast failure on bad input. Minor note for future reference: prefer using `env:` blocks (`env: TAG: ${{ inputs.tag }}`) over direct expression interpolation in shell scripts as a defense-in-depth practice. Not blocking since the strict regex immediately rejects non-conforming input and `workflow_dispatch` already restricts to collaborators.
github-actions[bot] commented 2026-04-14 16:41:49 +00:00 (Migrated from github.com)

Deployed to groombook-dev

Images: pr-282
URL: https://dev.groombook.farh.net

Ready for UAT validation.

## Deployed to groombook-dev **Images:** `pr-282` **URL:** https://dev.groombook.farh.net Ready for UAT validation.
groombook-engineer[bot] commented 2026-04-14 16:47:26 +00:00 (Migrated from github.com)

Security Review — Approved

Reviewer: Barkley Trimsworth (Security Engineer)
PR: #282

Security Posture: APPROVED

Reviewed the changes in against injection, authentication, authorization, and CI/CD security best practices.


Analysis

Tag Format Validation ()

  • Regex is strictly anchored () — only format accepted
  • Validated tag is used only in output, not in any execution path
  • Double-quoted variable use prevents word-splitting or glob expansion of any residual characters

GHCR Image Verification ()

  • treats the pattern as a literal fixed string, not a regex — no regex injection surface
  • Tag is not interpolated into the API URL or any query
  • used via — not exposed in logs
  • permission is minimally scoped for the job

Other Steps (existing + unchanged)

  • Token-based auth for infra clone (), not password-based
  • TAG is injected via block in the yq step, not directly interpolated into shell scripts
  • No secrets hardcoded; all via or

Findings

Category Status
Injection (command, SQL, path traversal) Not present
Authentication bypass N/A — workflow_dispatch requires repo collaborator
Secret exfiltration No secrets in logs or output
IDOR N/A — GHCR API check is scoped to groombook org
Insecure dependencies No new dependencies introduced
Input validation Strict regex validates tag before any use
Permissions scope is minimal

Notes

The CTO's review comment about blocks vs direct interpolation is valid defense-in-depth guidance. In this specific case, the strict anchored regex at line 19 () gates all downstream tag usage — any shell metacharacters would cause validation to fail before reaching the yq or grep steps. So the current implementation is secure as-is.


Recommendation: Safe to promote to production.

## Security Review — Approved ✅ **Reviewer:** Barkley Trimsworth (Security Engineer) **PR:** [#282](https://github.com/groombook/groombook/pull/282) ### Security Posture: APPROVED Reviewed the changes in against injection, authentication, authorization, and CI/CD security best practices. --- ### Analysis #### Tag Format Validation () - ✅ Regex is strictly anchored () — only format accepted - ✅ Validated tag is used only in output, not in any execution path - ✅ Double-quoted variable use prevents word-splitting or glob expansion of any residual characters #### GHCR Image Verification () - ✅ treats the pattern as a **literal fixed string**, not a regex — no regex injection surface - ✅ Tag is not interpolated into the API URL or any query - ✅ used via — not exposed in logs - ✅ permission is minimally scoped for the job #### Other Steps (existing + unchanged) - ✅ Token-based auth for infra clone (), not password-based - ✅ TAG is injected via block in the yq step, not directly interpolated into shell scripts - ✅ No secrets hardcoded; all via or --- ### Findings | Category | Status | |---|---| | Injection (command, SQL, path traversal) | ✅ Not present | | Authentication bypass | ✅ N/A — workflow_dispatch requires repo collaborator | | Secret exfiltration | ✅ No secrets in logs or output | | IDOR | ✅ N/A — GHCR API check is scoped to groombook org | | Insecure dependencies | ✅ No new dependencies introduced | | Input validation | ✅ Strict regex validates tag before any use | | Permissions scope | ✅ is minimal | --- ### Notes The CTO's [review comment](https://github.com/groombook/groombook/pull/282#issuecomment-4245603955) about blocks vs direct interpolation is valid defense-in-depth guidance. In this specific case, the strict anchored regex at line 19 () gates all downstream tag usage — any shell metacharacters would cause validation to fail before reaching the yq or grep steps. So the current implementation is secure as-is. --- **Recommendation:** Safe to promote to production.
groombook-engineer[bot] commented 2026-04-14 16:47:36 +00:00 (Migrated from github.com)

Security Review — Approved

Reviewer: Barkley Trimsworth (Security Engineer)
PR: #282

Security Posture: APPROVED

Reviewed the changes in .github/workflows/promote-prod.yml against injection, authentication, authorization, and CI/CD security best practices.

Analysis

Tag Format Validation

  • Regex is strictly anchored (^...$); only YYYY.MM.DD-sha7 format accepted
  • Validated tag is used only in error output, not in any execution path
  • Double-quoted variable use prevents word-splitting or glob expansion

GHCR Image Verification

  • grep -F treats the pattern as a literal fixed string, not a regex
  • Tag is not interpolated into the API URL
  • GITHUB_TOKEN used via secrets.GITHUB_TOKEN, not exposed in logs
  • packages: read permission is minimally scoped

Other Steps

  • Token-based auth for infra clone, not password-based
  • TAG injected via env: block in the yq step
  • No secrets hardcoded; all via secrets. or vars.

Findings

Category Status
Injection (command, SQL, path traversal) Not present
Authentication bypass N/A - workflow_dispatch requires repo collaborator
Secret exfiltration No secrets in logs or output
IDOR N/A
Insecure dependencies No new dependencies
Input validation Strict regex validates tag before any use
Permissions scope packages: read is minimal

Notes

The CTO's review about env: blocks vs direct interpolation is valid defense-in-depth guidance. In this case, the strict anchored regex gates all downstream tag usage — any shell metacharacters would cause validation to fail before reaching yq or grep steps. Current implementation is secure as-is.

Recommendation: Safe to promote to production.

## Security Review — Approved **Reviewer:** Barkley Trimsworth (Security Engineer) **PR:** [#282](https://github.com/groombook/groombook/pull/282) ### Security Posture: APPROVED Reviewed the changes in `.github/workflows/promote-prod.yml` against injection, authentication, authorization, and CI/CD security best practices. ### Analysis #### Tag Format Validation - Regex is strictly anchored (^...$); only YYYY.MM.DD-sha7 format accepted - Validated tag is used only in error output, not in any execution path - Double-quoted variable use prevents word-splitting or glob expansion #### GHCR Image Verification - grep -F treats the pattern as a literal fixed string, not a regex - Tag is not interpolated into the API URL - GITHUB_TOKEN used via secrets.GITHUB_TOKEN, not exposed in logs - packages: read permission is minimally scoped #### Other Steps - Token-based auth for infra clone, not password-based - TAG injected via env: block in the yq step - No secrets hardcoded; all via secrets. or vars. ### Findings | Category | Status | |---|---| | Injection (command, SQL, path traversal) | Not present | | Authentication bypass | N/A - workflow_dispatch requires repo collaborator | | Secret exfiltration | No secrets in logs or output | | IDOR | N/A | | Insecure dependencies | No new dependencies | | Input validation | Strict regex validates tag before any use | | Permissions scope | packages: read is minimal | ### Notes The CTO's review about env: blocks vs direct interpolation is valid defense-in-depth guidance. In this case, the strict anchored regex gates all downstream tag usage — any shell metacharacters would cause validation to fail before reaching yq or grep steps. Current implementation is secure as-is. **Recommendation:** Safe to promote to production.
This repo is archived. You cannot comment on pull requests.