fix(ci): pass deploy inputs via env, not shell interpolation

GitHub Actions expressions are substituted into a run body as text
before bash parses it, so a value carrying a quote, a command
substitution, or a newline becomes shell syntax rather than data.

cd-sam.yaml interpolated the parameter-overrides secret straight into
a shell test and an assignment, putting secret material into the script
body. cd-cdk.yaml interpolated the caller-supplied post-deploy-script
input into a bash invocation, which is caller-controlled command
injection rather than secret exposure.

Both now use env-var indirection, matching the STACKS precedent in the
CDK deploy step. PARAM_OVERRIDES is deliberately left unquoted at the
point of use: parameter-overrides carries multiple Key=Value pairs that
must reach sam deploy as separate argv entries, so quoting it would
collapse every override into one argument and break deploys that use
it. POST_DEPLOY_SCRIPT is a single path and is quoted.

Behaviour is otherwise unchanged. An empty parameter-overrides still
produces no --parameter-overrides flag at all, and an empty
post-deploy-script is still skipped by the step-level if condition,
which is a workflow expression and not shell.
This commit is contained in:
Adam Moussa 2026-07-28 12:35:00 -04:00
parent 3bdf11cd69
commit 7ece0b6c2a
No known key found for this signature in database
2 changed files with 13 additions and 3 deletions

View file

@ -134,7 +134,12 @@ jobs:
- name: Post-deploy script
if: ${{ inputs.post-deploy-script != '' }}
run: bash ${{ inputs.post-deploy-script }}
# Env-var indirection (not inline expression interpolation) so shell
# metacharacters in the input are never parsed as script; the input is a
# single script path, so $POST_DEPLOY_SCRIPT is quoted (no word-split).
env:
POST_DEPLOY_SCRIPT: ${{ inputs.post-deploy-script }}
run: bash "$POST_DEPLOY_SCRIPT"
- name: Post-deploy health check
if: ${{ inputs.stack-name != '' }}

View file

@ -80,10 +80,15 @@ jobs:
run: sam build --template ${{ inputs.sam-template }}
- name: SAM deploy
# Env-var indirection (not inline expression interpolation) so shell
# metacharacters in the secret are never parsed as script; unquoted
# $PARAM_OVERRIDES deliberately word-splits multiple Key=Value pairs.
env:
PARAM_OVERRIDES: ${{ secrets.parameter-overrides }}
run: |
PARAMS=""
if [ -n "${{ secrets.parameter-overrides }}" ]; then
PARAMS="--parameter-overrides ${{ secrets.parameter-overrides }}"
if [ -n "$PARAM_OVERRIDES" ]; then
PARAMS="--parameter-overrides $PARAM_OVERRIDES"
fi
sam deploy \
--stack-name ${{ inputs.stack-name }} \