Checks and Approvals in Environments
Complete the full lesson to earn 25 points
Work through each section, then tap “Mark as Complete” on the last one.
✦ Skip the page breaks and see fewer ads — read each lesson on a single page with Pro
Designing and Implementing Pipelines: Checks and Approvals in Environments
Introduction: Why Gatekeeping Matters in Software Delivery
In modern software engineering, the speed of delivery is often prioritized, but the reliability of that delivery is what defines a successful organization. When we talk about "pipelines," we are referring to the automated sequence of steps that take source code from a developer’s workstation to a production environment. While automation is the goal, blind automation is a recipe for disaster. This is where checks and approvals come into play. They act as the "brakes" in your high-speed vehicle, ensuring that before code reaches a critical environment, it has been verified by the right people, tested against the right criteria, and authorized by the appropriate stakeholders.
Checks and approvals are not merely bureaucratic hurdles intended to slow down progress. Instead, they are critical safety mechanisms that prevent accidental outages, security breaches, and compliance failures. By implementing these gates, you create a trail of accountability and ensure that every release is a conscious decision rather than an automated accident. In this lesson, we will explore how to design these gates, how to implement them across various environments, and how to balance the need for speed with the necessity of risk management.
Understanding the Landscape: Environments and Gates
Before we dive into the technical implementation, it is vital to understand the concept of an "environment." In a typical software lifecycle, you might have environments like Development, Testing (or QA), Staging, and Production. Each of these environments serves a different purpose, and therefore, each requires a different level of scrutiny before code is deployed to it.
Development environments are usually ephemeral and low-risk. Here, you might want minimal checks to allow for rapid iteration. Conversely, a Production environment is high-stakes; a single bad deployment can result in financial loss, data corruption, or service downtime. Therefore, the "gate" between Staging and Production is almost always the most rigorous.
The Anatomy of a Pipeline Gate
A pipeline gate generally consists of three primary components:
- Automated Quality Gates: These are checks performed by machines. This includes unit tests, integration tests, static analysis (linting), and security vulnerability scanning.
- Compliance and Policy Checks: These are checks against organizational standards. For example, a check might verify that all required documentation is present or that a specific security patch level has been met.
- Human Approvals: These are manual interventions where a human reviewer confirms that the deployment is safe, necessary, and timed correctly.
Callout: Automated vs. Manual Gates The industry standard is to favor automated gates whenever possible. Automated gates are repeatable, consistent, and fast. Manual gates should be reserved for decisions that require human intuition, business context, or high-stakes risk assessment. If you find yourself manually checking if a unit test passed, you have a design flaw in your pipeline.
Designing Reusable Gate Templates
One of the biggest challenges in scaling pipeline infrastructure is avoiding "copy-paste" configurations. If you have fifty microservices, you do not want to define your approval logic fifty times. Instead, you should create reusable pipeline elements—often referred to as templates or reusable workflows—that encapsulate your check and approval logic.
When designing these, aim for a modular approach. Your pipeline definition should look like a series of function calls rather than a monolithic script. For instance, you might have a standard security-scan template that every team is required to include in their deployment pipeline.
Implementing Reusable Checks
Let’s look at a conceptual example using a YAML-based configuration, which is common in tools like GitHub Actions or GitLab CI.
# A reusable job definition for a standard security check
jobs:
security-scan:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Run Vulnerability Scanner
run: |
./scan-tool --target ./src --format json --output results.json
# Fail the job if critical vulnerabilities are found
if grep -q '"severity": "critical"' results.json; then
echo "Critical vulnerabilities detected!"
exit 1
fi
By defining this as a reusable job, you ensure that every team in your organization is using the same security standard. If the security team updates the scan-tool version, you only need to update it in one place, and all pipelines benefit from the change immediately.
Step-by-Step: Implementing Human Approvals
Human approvals are the most common point of friction in a pipeline. To implement these effectively, you must define who approves, when they are notified, and what they are approving.
1. Defining the Approver Group
Avoid assigning individual people to approval tasks. If a person goes on vacation or leaves the team, your pipeline will stall. Instead, assign approvals to a group or a role (e.g., "QA Leads" or "Release Managers").
2. Setting the Trigger
The approval step should occur immediately before the deployment to the target environment. You want the code to be fully built and tested before the approver sees it.
3. Providing Context
An approval request is useless if the reviewer doesn't know what they are approving. Your pipeline tool should provide a link to:
- The commit history since the last deployment.
- The results of the automated test suite.
- The deployment logs for the current build.
- A summary of the changes (e.g., Jira ticket links).
Note: Always include a "timeout" for manual approvals. If an approval is not granted within a certain timeframe (e.g., 24 hours), the deployment request should automatically expire. This prevents "stale" deployments where someone approves a build that is no longer relevant.
Best Practices for Pipeline Checks
To maintain a healthy pipeline, follow these industry-standard practices:
- Fail Fast: Ensure that your cheapest, fastest tests (like linting or unit tests) run first. If these fail, the pipeline should stop immediately, saving time and compute resources.
- Idempotency: Your deployment scripts must be idempotent. If a pipeline is interrupted by a manual approval wait, the deployment process should be able to resume or restart without leaving the environment in a broken state.
- Audit Logging: Every check and every approval must be logged. You need to be able to answer the question, "Who authorized this specific change to Production?" weeks or months after the fact.
- Environment Parity: The checks you run in Staging should be as close to the checks in Production as possible. If you test on different configurations, you will eventually encounter a bug that only appears in Production.
- Separation of Duties: The person who writes the code should not be the only person who can approve the deployment to Production. While this is less critical for small startups, it is a non-negotiable requirement for many compliance frameworks like SOC2 or HIPAA.
Common Pitfalls and How to Avoid Them
Even with the best intentions, teams often fall into traps when implementing pipeline gates. Here are the most frequent mistakes:
1. The "Approval Bottleneck"
This happens when you require too many people to approve a change. If you need approval from the VP of Engineering, the Lead Architect, and the Security Manager for every single release, your deployment velocity will grind to a halt.
- The Fix: Use automated checks to handle 90% of the validation. Only require human sign-off for exceptional changes or high-risk deployments. Consider "auto-approval" for minor changes if they pass all automated tests.
2. Ignoring the "Why"
Sometimes teams add checks because they saw them in a blog post, not because they solve a real problem. This adds unnecessary complexity to the pipeline.
- The Fix: Every gate should be tied to a specific risk. If you have a gate that checks for code formatting, ask if that is a safety risk or just a preference. If it's just a preference, move it to the developer's IDE, not the deployment pipeline.
3. Hardcoding Credentials
Never hardcode secrets or environment-specific configuration in your pipeline templates.
- The Fix: Use environment variables or secret management services. Your reusable templates should accept parameters, allowing them to remain generic while the data they work with remains environment-specific.
Comparison: Manual vs. Automated Gates
| Feature | Automated Gates | Manual Approvals |
|---|---|---|
| Speed | Extremely Fast | Slow (Human-dependent) |
| Consistency | High | Low (Subjective) |
| Cost | Low (Compute time) | High (Human time) |
| Best Used For | Unit tests, Security, Linting | Business logic, Risk assessment |
| Scalability | High | Low |
Practical Implementation: A Phased Approach
Let’s walk through a common scenario where you are deploying a new microservice. You want to ensure that it passes through a series of gates.
Phase 1: The Build and Unit Test Gate
Every commit triggers this. It is automated and mandatory. If this fails, the developer is notified immediately.
Phase 2: The Integration and Security Gate
This occurs when code is merged into the main branch. It deploys to an ephemeral "Integration" environment. Automated tests run against the service. If security scanners find a critical flaw, the pipeline halts.
Phase 3: The Staging Gate
This is where you might have your first manual gate. Before code is promoted from Integration to Staging, a QA representative must review the test results. This ensures that the service is actually functional before it hits the Staging environment where other teams might be working.
Phase 4: The Production Gate
This is the final hurdle. It requires a formal approval from a Release Manager. The pipeline displays the link to the Jira ticket, the test coverage report, and the security audit. Once the "Approve" button is clicked, the final deployment script executes.
Tip: If you are using a tool like Kubernetes, consider using "Blue-Green" or "Canary" deployments as part of your final gate. Even after an approval is given, you can deploy to a small subset of users (Canary) and verify that the error rate remains low before shifting all traffic.
Advanced Concepts: Policy as Code
One of the most powerful ways to manage checks is through "Policy as Code." Instead of hardcoding rules into your pipeline YAML files, you use a policy engine (such as Open Policy Agent or OPA).
With OPA, you define your rules in a declarative language. For example, you could write a rule that says: "No container image can be deployed to production if it is running as the 'root' user."
Your pipeline then simply asks the policy engine: "Can I deploy this?" The engine checks the configuration and returns a "Yes" or "No." This decouples your business logic from your pipeline configuration. It allows your security team to update policies without needing to touch the CI/CD pipeline code itself.
Troubleshooting Pipeline Failures
When a pipeline fails at a gate, it can be frustrating for developers. To minimize this, you must provide clear feedback. A failing gate should never just say "Failed." It should provide:
- The specific reason for failure: (e.g., "Unit test failed in
auth_service.pyat line 42"). - Actionable steps to fix it: (e.g., "Run
npm installandnpm testlocally to reproduce"). - Links to logs: Direct access to the console output that caused the failure.
If your developers have to spend thirty minutes hunting for why a pipeline failed, they will quickly lose trust in the automation. High-quality feedback is just as important as the gate itself.
Security Considerations
Checks and approvals are the front line of defense against supply chain attacks. You must ensure that the approval process itself cannot be bypassed.
- Protect your pipeline definitions: Only senior engineers or platform teams should have the ability to modify the pipeline templates.
- Use signed commits: Ensure that the code being deployed was actually authored by a known developer.
- Least Privilege: The service account that runs the deployment should only have the permissions necessary to deploy the application, not broad administrative access to the entire cluster or cloud account.
Callout: The "Human-in-the-Loop" Fallacy Do not assume that because a human approved a deployment, it is safe. Humans are prone to errors, fatigue, and social engineering. Always use human approval as a layer on top of automated verification, not as a replacement for it. The automated tests are your primary source of truth; the human approval is your final sanity check.
Integrating Approval Requests with Communication Tools
In modern development environments, you should not expect people to log into a CI/CD dashboard every day to check for approvals. Instead, push notifications to where the people already are.
Most modern pipeline tools integrate with Slack, Microsoft Teams, or other messaging platforms. When a deployment is waiting for approval, the pipeline can send a message to a dedicated channel:
"Deployment #1234 is pending approval for Production. Changes: PR #987, PR #988. Tests: 100% pass. Security: No critical vulnerabilities. [Approve] [Reject]"
This allows for much faster turnaround times while still maintaining the necessary human oversight.
Building a Culture of Responsibility
Ultimately, the best pipeline checks in the world will not save a team that doesn't care about quality. You need to foster a culture where developers understand why these gates exist. Explain to them that the approval process is not about policing them, but about protecting the service and their colleagues from the stress of a production incident.
When a deployment fails, perform a "blameless post-mortem." Don't ask, "Who approved this?" Ask, "What part of our testing or validation process failed to catch this issue?" This shifts the focus from individual blame to systemic improvement, which is the hallmark of a high-performing engineering organization.
Key Takeaways
- Gates are for Safety, Not Speed Bumps: View checks and approvals as essential protection for your environments, not as obstacles to delivery.
- Automate Everything Possible: Use automated tests and policy engines to handle the bulk of your validation. Save human effort for high-level risk assessments.
- Standardize with Templates: Use reusable pipeline elements to ensure consistency across teams and services. Avoid manual configuration drift by centralizing your gate logic.
- Context is Everything: Provide reviewers with all the data they need—test results, commit diffs, and security scans—so they can make informed decisions quickly.
- Fail Fast, Fail Loudly: Use clear, actionable feedback when a gate fails. If a pipeline is blocked, the developer should know exactly why and how to fix it within seconds.
- Secure the Pipeline: Treat your CI/CD pipeline code as production code. Protect it, audit it, and ensure that your approval process cannot be bypassed by unauthorized users.
- Embrace Policy as Code: As you scale, look into declarative policy engines to manage complex compliance requirements without cluttering your pipeline definitions.
FAQ: Common Questions
Q: How many people should be required to approve a production deployment? A: This depends on your team size and risk profile. For many, one person from a different team (or a senior member) is sufficient. For highly regulated industries, you might require two sign-offs to prevent collusion or accidental errors.
Q: What if I have a critical emergency and need to bypass the pipeline? A: You should have an "Emergency Break-Glass" procedure. This involves a documented process to bypass gates, which should trigger an immediate audit alert and require a post-incident review to explain why the bypass was necessary. Never make this the standard way of working.
Q: Should QA be the only ones approving deployments? A: No. Approval should be a shared responsibility. Depending on the change, you might need approval from a Product Manager (for feature launches), a Security Engineer (for infrastructure changes), or a Lead Developer (for architectural changes).
Q: How do I handle approvals for weekend or off-hours deployments? A: Try to avoid off-hours deployments entirely. If you must, ensure that your on-call engineers are the ones providing the approval. If your pipeline requires an approval that nobody is available to give, you will end up with "approval fatigue" and people will start rubber-stamping requests just to get them out of the way.
Q: Is it okay to skip gates for minor changes? A: It is better to have a "fast-track" for minor changes that pass all automated tests, rather than skipping gates entirely. If a change is truly minor and has passed all automated verification, it should be able to proceed without human intervention. If it hasn't passed verification, it should never be skipped.
By carefully designing your checks and approvals, you transform your pipeline from a simple automation tool into a robust governance framework. This allows your team to move quickly with confidence, knowing that every deployment has been vetted, verified, and authorized. Remember that the goal is not to stop change, but to ensure that change is safe, intentional, and sustainable.
Continue the course
Enjoying the courses?
Everything stays free. Pro shows fewer ads, doubles your daily points limit so you progress twice as fast, and lets you read each lesson on one page.
- ✓ Fewer advertisements
- ✓ 2× daily points limit
- ✓ Distraction-free lessons