Appearance
Approval Gates
Azure DevOps Environments with deployment protection rules implement the approval gates for Microtec ERP pipelines. Each environment has defined approvers, timeouts, and branch policies that control when automated deployments can proceed.
Approval Gate Overview
Environment Configuration Reference
dev — No Approval Required
| Property | Value |
|---|---|
| Approvers | None |
| Auto-deploy | Yes |
| Timeout | N/A |
| Branch policy | develop, Sprint* |
| Pipeline | platforms-pipeline.yml and others auto-trigger |
Dev is fully automated. Every merge to a dev-targeting branch deploys immediately.
stage — Dev Team Approval
| Property | Value |
|---|---|
| Approvers | Any 1 of: Senior Developer, Lead Developer |
| Minimum approvers | 1 |
| Timeout | 4 hours |
| On timeout | Reject and notify |
| Branch policy | Must come from Stage branch |
| Excluded users | Pipeline service account cannot self-approve |
Configuration in ADO (Azure DevOps → Environments → stage → Approvals and Checks):
Type: Approvals
Approvers: [Senior Dev Group]
Required minimum number: 1
Allow approvers to approve their own runs: No
Timeout: 4 hours
On timeout: Rejectpreprod — Lead Required
| Property | Value |
|---|---|
| Approvers | Any 1 of: Lead DevOps, Lead Developer |
| Minimum approvers | 1 |
| Timeout | 8 hours |
| On timeout | Reject |
| Branch policy | Must come from PreProd or preprod branch |
| Pre-conditions | Stage smoke tests must be green (last 24 hours) |
Preprod also includes a Branch Control check:
Type: Branch Control
Allowed branches: refs/heads/PreProd, refs/heads/preprod
Ensure protection of branch: Yes (case-sensitive; both variants accepted)uat — QA Lead Required
| Property | Value |
|---|---|
| Approvers | QA Lead (required), any 1 additional approver optional |
| Minimum approvers | 1 (QA Lead mandatory) |
| Timeout | 24 hours |
| On timeout | Reject and notify QA Lead + Project Manager |
| Additional check | All CI quality gates pass (SonarCloud, Trivy, OWASP DC) |
UAT deployments also require a Manual Validation step after deployment completes — the QA Lead must sign off that UAT testing is complete before the pipeline marks the deployment successful.
yaml
# In production-release-pipeline.yml, post-UAT validation
- task: ManualValidation@0
displayName: 'QA Sign-off: UAT Testing Complete'
inputs:
notifyUsers: '$(qaLeadEmail)'
instructions: |
UAT deployment is complete.
Please verify the following before approving:
- [ ] All regression test suites pass
- [ ] Business Owner smoke test checklist complete
- [ ] No P1 or P2 bugs open against this release
onTimeout: reject
timeout: 1440 # 24 hoursproduction — Dual Approval
| Property | Value |
|---|---|
| Approvers | Release Manager AND CTO (both required) |
| Minimum approvers | 2 (both specific users) |
| Timeout | 8 hours |
| On timeout | Reject — must reschedule release window |
| Pre-conditions (automated) | Stage smoke tests green, no open P1 bugs, DB migrations reviewed |
| Post-condition | QA sign-off after extended smoke tests |
Production Approval is Non-Negotiable
Production deployments require both the Release Manager and the CTO to approve. There is no override. If a release must happen outside business hours, approvers must be contacted directly. Do NOT attempt to bypass the approval gate.
Automated pre-conditions (Branch Control + Status Checks):
yaml
# In production-release-pipeline.yml — Pre-flight checks before requesting approval
- stage: Preflight
jobs:
- job: CheckStageSmokeTests
steps:
- task: AzureCLI@2
displayName: 'Verify stage smoke tests (last 24h)'
inputs:
script: |
# Query ADO for last successful smoke test run on stage
LAST_SUCCESS=$(az pipelines runs list \
--pipeline-name "smoke-test-stage" \
--result succeeded \
--top 1 \
--query "[0].finishedDate" -o tsv)
AGE_HOURS=$(( ($(date +%s) - $(date -d "$LAST_SUCCESS" +%s)) / 3600 ))
if [ "$AGE_HOURS" -gt 24 ]; then
echo "FAIL: Stage smoke tests last ran $AGE_HOURS hours ago (threshold: 24h)"
exit 1
fi
echo "OK: Stage smoke tests ran $AGE_HOURS hours ago"Notification Configuration
When an approval is requested, ADO sends email notifications. Additional Teams channel alerts are configured via service hooks:
| Event | Teams Channel | Recipients |
|---|---|---|
| Production approval requested | #release-approvals | Release Manager, CTO |
| Production approval approved | #deployments | Engineering team |
| Approval timeout | #deployments | Requester + approvers |
| Rejection | #deployments | Requester |
Who Can Approve What
| Environment | Who | ADO Group |
|---|---|---|
| stage | Senior Developer, Lead Developer | [microtec-erp]\Senior Developers |
| preprod | Lead DevOps Engineer, Lead Developer | [microtec-erp]\Tech Leads |
| uat | QA Lead | [microtec-erp]\QA Leads |
| production | Release Manager | [microtec-erp]\Release Managers |
| production | CTO | Individual user (named) |
Self-Approval Disabled
In all environments, the person who triggered the pipeline cannot approve their own deployment. The Allow approvers to approve their own runs setting is set to No in every environment.
Rollback Approval
If a production deployment must be rolled back, the rollback itself also requires approval:
yaml
# rollback-production.yml — requires same dual approval
- deployment: RollbackProduction
environment: 'production' # Triggers same approval gate
displayName: 'Rollback Production to $(previousVersion)'Rollback is typically faster (3–5 minutes, image already in ACR) but follows the same governance process.
Audit Trail
All approval events are recorded in ADO's audit log:
bash
# View approval history for an environment via ADO REST API
curl -u :{PAT} \
"https://dev.azure.com/microtec/erp/_apis/audit/auditlog?api-version=7.1" \
| jq '.decoratedAuditLogEntries[] | select(.actionId | contains("Approval"))'Approval audit logs are retained for 2 years per the security policy.
Related Documentation
- Orchestrators — How deployment stages reference ADO environments
- Provision Infra — Infrastructure deployment approval flow
- Stage Templates —
ManualValidation@0task usage - Pipeline Stages — DevSecOps stages that must pass before approval