Skip to content

Commit b9adec8

Browse files
Merge pull request #93 from microsoft/psl-pipeline-security-fix
ci: fix pipeline vulnerabilities
2 parents bc1a333 + 112bd98 commit b9adec8

13 files changed

Lines changed: 892 additions & 110 deletions

.github/workflows/azure-dev.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
steps:
1616
- uses: actions/checkout@v4
1717

18-
- uses: microsoft/template-validation-action@Latest
18+
- uses: microsoft/template-validation-action@v0.4.3
1919
with:
2020
validateAzd: ${{ vars.AZD_VALIDATE }}
2121
useDevContainer: ${{ vars.AZD_USE_DEV_CONTAINER }}

.github/workflows/ci.yml

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
name: Validate Deployment
2+
3+
permissions:
4+
contents: read
5+
actions: read
6+
27
on:
38
push:
49
branches:
@@ -35,21 +40,20 @@ jobs:
3540
steps:
3641
- name: Checkout Code
3742
uses: actions/checkout@v4
38-
- name: Setup Azure CLI
39-
run: |
40-
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
41-
az --version
43+
4244
- name: Login to Azure
4345
run: |
4446
az login --service-principal -u ${{ secrets.AZURE_CLIENT_ID }} -p ${{ secrets.AZURE_CLIENT_SECRET }} --tenant ${{ secrets.AZURE_TENANT_ID }}
4547
- name: Run Quota Check
4648
id: quota-check
49+
env:
50+
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
51+
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
52+
AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET }}
53+
AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
54+
AZURE_REGIONS: ${{ vars.AZURE_REGIONS }}
55+
GPT_MIN_CAPACITY: ${{ env.GPT_MIN_CAPACITY }}
4756
run: |
48-
export AZURE_CLIENT_ID=${{ secrets.AZURE_CLIENT_ID }}
49-
export AZURE_TENANT_ID=${{ secrets.AZURE_TENANT_ID }}
50-
export AZURE_CLIENT_SECRET=${{ secrets.AZURE_CLIENT_SECRET }}
51-
export AZURE_SUBSCRIPTION_ID="${{ secrets.AZURE_SUBSCRIPTION_ID }}"
52-
export AZURE_REGIONS="${{ vars.AZURE_REGIONS }}"
5357
chmod +x scripts/checkquota.sh
5458
if ! scripts/checkquota.sh; then
5559
# If quota check fails due to insufficient quota, set the flag
@@ -168,10 +172,6 @@ jobs:
168172
env:
169173
RESOURCE_GROUP_NAME: ${{ needs.deploy.outputs.RESOURCE_GROUP_NAME }}
170174
steps:
171-
- name: Setup Azure CLI
172-
run: |
173-
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
174-
az --version
175175
- name: Login to Azure
176176
run: |
177177
az login --service-principal -u ${{ secrets.AZURE_CLIENT_ID }} -p ${{ secrets.AZURE_CLIENT_SECRET }} --tenant ${{ secrets.AZURE_TENANT_ID }}

.github/workflows/deploy-linux.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
name: Deploy-Test-Cleanup (v2) Linux
2+
3+
permissions:
4+
contents: read
5+
actions: read
6+
27
on:
38
push:
49
branches:

.github/workflows/deploy-orchestrator.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
name: Deployment orchestrator
22

3+
permissions:
4+
contents: read
5+
actions: read
6+
37
on:
48
workflow_call:
59
inputs:

.github/workflows/deploy-windows.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
name: Deploy-Test-Cleanup (v2) Windows
2+
3+
permissions:
4+
contents: read
5+
actions: read
6+
27
on:
38
# push:
49
# branches:

.github/workflows/docker-build-and-push.yml

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
name: Build and Push Docker Images
22

3+
permissions:
4+
contents: read
5+
actions: read
6+
37
on:
48
push:
59
branches: [main, dev, demo, hotfix]
@@ -37,12 +41,6 @@ jobs:
3741
id: date
3842
run: echo "date=$(date +'%Y-%m-%d')" >> $GITHUB_OUTPUT
3943

40-
- name: Setup Azure CLI
41-
run: |
42-
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
43-
az --version # Verify installation
44-
45-
4644
- name: Log in to Azure Container Registry
4745
if: ${{ (github.event_name == 'push' && (github.ref_name == 'main' || github.ref_name == 'dev' || github.ref_name == 'demo')) || (github.event_name == 'workflow_dispatch' && (github.ref_name == 'dependabotchanges'||github.ref_name == 'main' || github.ref_name == 'dev' || github.ref_name == 'demo')) }}
4846
uses: azure/docker-login@v2

.github/workflows/job-cleanup-deployment.yml

Lines changed: 148 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
name: Cleanup Deployment Job
2+
3+
permissions:
4+
contents: read
5+
actions: read
6+
27
on:
38
workflow_call:
49
inputs:
@@ -53,16 +58,133 @@ jobs:
5358
IMAGE_TAG: ${{ inputs.IMAGE_TAG }}
5459

5560
steps:
56-
- name: Checkout Code
57-
uses: actions/checkout@v4
58-
59-
- name: Setup Azure CLI
61+
- name: Validate Workflow Input Parameters
6062
shell: bash
63+
env:
64+
INPUT_TRIGGER_TYPE: ${{ inputs.trigger_type }}
65+
INPUT_RUNNER_OS: ${{ inputs.runner_os }}
66+
INPUT_CLEANUP_RESOURCES: ${{ inputs.cleanup_resources }}
67+
INPUT_EXISTING_WEBAPP_URL: ${{ inputs.existing_webapp_url }}
68+
INPUT_RESOURCE_GROUP_NAME: ${{ inputs.RESOURCE_GROUP_NAME }}
69+
INPUT_AZURE_LOCATION: ${{ inputs.AZURE_LOCATION }}
70+
INPUT_AZURE_ENV_OPENAI_LOCATION: ${{ inputs.AZURE_ENV_OPENAI_LOCATION }}
71+
INPUT_ENV_NAME: ${{ inputs.ENV_NAME }}
72+
INPUT_IMAGE_TAG: ${{ inputs.IMAGE_TAG }}
6173
run: |
62-
if [[ "${{ runner.os }}" == "Linux" ]]; then
63-
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
74+
echo "🔍 Validating workflow input parameters..."
75+
VALIDATION_FAILED=false
76+
77+
# Validate trigger_type (required - alphanumeric with underscores)
78+
if [[ -z "$INPUT_TRIGGER_TYPE" ]]; then
79+
echo "❌ ERROR: trigger_type is required but was not provided"
80+
VALIDATION_FAILED=true
81+
elif [[ ! "$INPUT_TRIGGER_TYPE" =~ ^[a-zA-Z0-9_]+$ ]]; then
82+
echo "❌ ERROR: trigger_type '$INPUT_TRIGGER_TYPE' is invalid. Must contain only alphanumeric characters and underscores"
83+
VALIDATION_FAILED=true
84+
else
85+
echo "✅ trigger_type: '$INPUT_TRIGGER_TYPE' is valid"
86+
fi
87+
88+
# Validate runner_os (required - must be specific values)
89+
ALLOWED_RUNNER_OS=("ubuntu-latest" "windows-latest")
90+
if [[ -z "$INPUT_RUNNER_OS" ]]; then
91+
echo "❌ ERROR: runner_os is required but was not provided"
92+
VALIDATION_FAILED=true
93+
elif [[ ! " ${ALLOWED_RUNNER_OS[@]} " =~ " ${INPUT_RUNNER_OS} " ]]; then
94+
echo "❌ ERROR: runner_os '$INPUT_RUNNER_OS' is invalid. Allowed values: ${ALLOWED_RUNNER_OS[*]}"
95+
VALIDATION_FAILED=true
96+
else
97+
echo "✅ runner_os: '$INPUT_RUNNER_OS' is valid"
98+
fi
99+
100+
# Validate cleanup_resources (boolean)
101+
if [[ "$INPUT_CLEANUP_RESOURCES" != "true" && "$INPUT_CLEANUP_RESOURCES" != "false" ]]; then
102+
echo "❌ ERROR: cleanup_resources must be 'true' or 'false', got: '$INPUT_CLEANUP_RESOURCES'"
103+
VALIDATION_FAILED=true
104+
else
105+
echo "✅ cleanup_resources: '$INPUT_CLEANUP_RESOURCES' is valid"
106+
fi
107+
108+
# Validate existing_webapp_url (must start with https)
109+
if [[ -n "$INPUT_EXISTING_WEBAPP_URL" ]]; then
110+
if [[ ! "$INPUT_EXISTING_WEBAPP_URL" =~ ^https:// ]]; then
111+
echo "❌ ERROR: existing_webapp_url must start with 'https://', got: '$INPUT_EXISTING_WEBAPP_URL'"
112+
VALIDATION_FAILED=true
113+
else
114+
echo "✅ existing_webapp_url: '$INPUT_EXISTING_WEBAPP_URL' is valid"
115+
fi
64116
fi
65-
az --version
117+
118+
# Validate RESOURCE_GROUP_NAME (required, Azure resource group naming convention)
119+
if [[ -z "$INPUT_RESOURCE_GROUP_NAME" ]]; then
120+
echo "❌ ERROR: RESOURCE_GROUP_NAME is required but was not provided"
121+
VALIDATION_FAILED=true
122+
elif [[ ! "$INPUT_RESOURCE_GROUP_NAME" =~ ^[a-zA-Z0-9._\(\)-]+$ ]] || [[ "$INPUT_RESOURCE_GROUP_NAME" =~ \.$ ]]; then
123+
echo "❌ ERROR: RESOURCE_GROUP_NAME '$INPUT_RESOURCE_GROUP_NAME' is invalid. Must contain only alphanumerics, periods, underscores, hyphens, and parentheses. Cannot end with period."
124+
VALIDATION_FAILED=true
125+
elif [[ ${#INPUT_RESOURCE_GROUP_NAME} -gt 90 ]]; then
126+
echo "❌ ERROR: RESOURCE_GROUP_NAME '$INPUT_RESOURCE_GROUP_NAME' exceeds 90 characters"
127+
VALIDATION_FAILED=true
128+
else
129+
echo "✅ RESOURCE_GROUP_NAME: '$INPUT_RESOURCE_GROUP_NAME' is valid"
130+
fi
131+
132+
# Validate AZURE_LOCATION (required, Azure region format)
133+
if [[ -z "$INPUT_AZURE_LOCATION" ]]; then
134+
echo "❌ ERROR: AZURE_LOCATION is required but was not provided"
135+
VALIDATION_FAILED=true
136+
elif [[ ! "$INPUT_AZURE_LOCATION" =~ ^[a-z0-9]+$ ]]; then
137+
echo "❌ ERROR: AZURE_LOCATION '$INPUT_AZURE_LOCATION' is invalid. Must contain only lowercase letters and numbers (e.g., 'australiaeast', 'westus2')"
138+
VALIDATION_FAILED=true
139+
else
140+
echo "✅ AZURE_LOCATION: '$INPUT_AZURE_LOCATION' is valid"
141+
fi
142+
143+
# Validate AZURE_ENV_OPENAI_LOCATION (required, Azure region format)
144+
if [[ -z "$INPUT_AZURE_ENV_OPENAI_LOCATION" ]]; then
145+
echo "❌ ERROR: AZURE_ENV_OPENAI_LOCATION is required but was not provided"
146+
VALIDATION_FAILED=true
147+
elif [[ ! "$INPUT_AZURE_ENV_OPENAI_LOCATION" =~ ^[a-z0-9]+$ ]]; then
148+
echo "❌ ERROR: AZURE_ENV_OPENAI_LOCATION '$INPUT_AZURE_ENV_OPENAI_LOCATION' is invalid. Must contain only lowercase letters and numbers (e.g., 'australiaeast', 'westus2')"
149+
VALIDATION_FAILED=true
150+
else
151+
echo "✅ AZURE_ENV_OPENAI_LOCATION: '$INPUT_AZURE_ENV_OPENAI_LOCATION' is valid"
152+
fi
153+
154+
# Validate ENV_NAME (required)
155+
if [[ -z "$INPUT_ENV_NAME" ]]; then
156+
echo "❌ ERROR: ENV_NAME is required but was not provided"
157+
VALIDATION_FAILED=true
158+
else
159+
echo "✅ ENV_NAME: '$INPUT_ENV_NAME' is valid"
160+
fi
161+
162+
# Validate IMAGE_TAG (required, Docker tag pattern)
163+
if [[ -z "$INPUT_IMAGE_TAG" ]]; then
164+
echo "❌ ERROR: IMAGE_TAG is required but was not provided"
165+
VALIDATION_FAILED=true
166+
elif [[ ! "$INPUT_IMAGE_TAG" =~ ^[a-zA-Z0-9_][a-zA-Z0-9._-]{0,127}$ ]]; then
167+
echo "❌ ERROR: IMAGE_TAG '$INPUT_IMAGE_TAG' is invalid. Must:"
168+
echo " - Start with alphanumeric or underscore"
169+
echo " - Contain only alphanumerics, underscores, periods, hyphens"
170+
echo " - Be max 128 characters"
171+
VALIDATION_FAILED=true
172+
else
173+
echo "✅ IMAGE_TAG: '$INPUT_IMAGE_TAG' is valid"
174+
fi
175+
176+
# Fail workflow if any validation failed
177+
if [[ "$VALIDATION_FAILED" == "true" ]]; then
178+
echo ""
179+
echo "❌ Parameter validation failed. Please correct the errors above and try again."
180+
exit 1
181+
fi
182+
183+
echo ""
184+
echo "✅ All input parameters validated successfully!"
185+
186+
- name: Checkout Code
187+
uses: actions/checkout@v4
66188

67189
- name: Setup Azure Developer CLI
68190
uses: Azure/setup-azd@v2
@@ -77,6 +199,10 @@ jobs:
77199
78200
- name: Select Environment
79201
shell: bash
202+
env:
203+
RESOURCE_GROUP_NAME: ${{ inputs.RESOURCE_GROUP_NAME }}
204+
AZURE_LOCATION: ${{ inputs.AZURE_LOCATION }}
205+
AZURE_ENV_OPENAI_LOCATION: ${{ inputs.AZURE_ENV_OPENAI_LOCATION }}
80206
run: |
81207
set -e
82208
# Try to select the environment if it exists, otherwise create a minimal environment for cleanup
@@ -87,10 +213,10 @@ jobs:
87213
else
88214
echo "Environment ${{ env.ENV_NAME }} not found, creating minimal environment for cleanup..."
89215
azd env new ${{ env.ENV_NAME }} --no-prompt
90-
azd env set AZURE_RESOURCE_GROUP "${{ inputs.RESOURCE_GROUP_NAME }}"
216+
azd env set AZURE_RESOURCE_GROUP "${RESOURCE_GROUP_NAME}"
91217
azd env set AZURE_SUBSCRIPTION_ID "${{ secrets.AZURE_SUBSCRIPTION_ID }}"
92-
azd env set AZURE_LOCATION="${{ inputs.AZURE_LOCATION }}"
93-
azd env set AZURE_AI_DEPLOYMENT_TYPE="${{ inputs.AZURE_ENV_OPENAI_LOCATION }}"
218+
azd env set AZURE_LOCATION="${AZURE_LOCATION}"
219+
azd env set AZURE_AI_DEPLOYMENT_TYPE="${AZURE_ENV_OPENAI_LOCATION}"
94220
fi
95221
96222
- name: Delete deployment using azd
@@ -113,22 +239,29 @@ jobs:
113239
- name: Generate Cleanup Job Summary
114240
if: always()
115241
shell: bash
242+
env:
243+
RESOURCE_GROUP_NAME: ${{ inputs.RESOURCE_GROUP_NAME }}
244+
DELETE_RG_OUTCOME: ${{ steps.delete_rg.outcome }}
116245
run: |
117246
echo "## 🧹 Cleanup Job Summary" >> $GITHUB_STEP_SUMMARY
118247
echo "" >> $GITHUB_STEP_SUMMARY
119248
echo "| Field | Value |" >> $GITHUB_STEP_SUMMARY
120249
echo "|-------|--------|" >> $GITHUB_STEP_SUMMARY
121-
echo "| **Resource Group deletion Status** | ${{ steps.delete_rg.outcome == 'success' && '✅ Success' || '❌ Failed' }} |" >> $GITHUB_STEP_SUMMARY
122-
echo "| **Resource Group** | \`${{ inputs.RESOURCE_GROUP_NAME }}\` |" >> $GITHUB_STEP_SUMMARY
250+
if [[ "${DELETE_RG_OUTCOME}" == "success" ]]; then
251+
echo "| **Resource Group deletion Status** | ✅ Success |" >> $GITHUB_STEP_SUMMARY
252+
else
253+
echo "| **Resource Group deletion Status** | ❌ Failed |" >> $GITHUB_STEP_SUMMARY
254+
fi
255+
echo "| **Resource Group** | \`${RESOURCE_GROUP_NAME}\` |" >> $GITHUB_STEP_SUMMARY
123256
echo "" >> $GITHUB_STEP_SUMMARY
124-
if [[ "${{ steps.delete_rg.outcome }}" == "success" ]]; then
257+
if [[ "${DELETE_RG_OUTCOME}" == "success" ]]; then
125258
echo "### ✅ Cleanup Details" >> $GITHUB_STEP_SUMMARY
126-
echo "- Successfully initiated deletion for Resource Group \`${{ inputs.RESOURCE_GROUP_NAME }}\`" >> $GITHUB_STEP_SUMMARY
259+
echo "- Successfully initiated deletion for Resource Group \`${RESOURCE_GROUP_NAME}\`" >> $GITHUB_STEP_SUMMARY
127260
echo "" >> $GITHUB_STEP_SUMMARY
128261
else
129262
echo "### ❌ Cleanup Failed" >> $GITHUB_STEP_SUMMARY
130263
echo "- Cleanup process encountered an error" >> $GITHUB_STEP_SUMMARY
131264
echo "- Manual cleanup may be required for:" >> $GITHUB_STEP_SUMMARY
132-
echo " - Resource Group: \`${{ env.RESOURCE_GROUP_NAME }}\`" >> $GITHUB_STEP_SUMMARY
265+
echo " - Resource Group: \`${RESOURCE_GROUP_NAME}\`" >> $GITHUB_STEP_SUMMARY
133266
echo "- Check the cleanup-deployment job logs for detailed error information" >> $GITHUB_STEP_SUMMARY
134267
fi

0 commit comments

Comments
 (0)