Before exposing any service, I run a tooling-first hardening sequence. The goal is simple: launch decisions based on verifiable controls, not assumptions. The checklist below is operator-oriented and maps directly to AWS, Azure, and GCP workflows.
1) Identity and authentication controls first
I lock identity before network exposure. If access ownership is unclear, release is blocked.
# AWS: inspect attached policies
aws iam list-attached-user-policies --user-name <user>
# Azure: list role assignments
az role assignment list --all --query "[].{principal:principalName,role:roleDefinitionName,scope:scope}"
# GCP: inspect IAM bindings
gcloud projects get-iam-policy <project-id> --format=json
2) Network edge restrictions with explicit allow rules
Any public endpoint is scanned quickly. Ingress policy must be deliberate and minimal.
# AWS: SGs open to world
aws ec2 describe-security-groups \
--query "SecurityGroups[?IpPermissions[?IpRanges[?CidrIp=='0.0.0.0/0']]].{GroupId:GroupId,Name:GroupName}"
# Azure: list NSGs
az network nsg list -o table
# GCP: firewall rules
gcloud compute firewall-rules list --format="table(name,direction,sourceRanges,allowed)"
Abuse resistance gate: verify WAF/API rate limiting (AWS WAF rate-based rules, Azure WAF policy, Cloud Armor / API throttling) before public release.
3) Logging and telemetry enabled before go-live
If investigation is impossible, launch is not approved.
# AWS: verify CloudTrail trail status
aws cloudtrail get-trail-status --name <trail>
# Azure: verify Defender for Cloud pricing tiers/status
az security pricing list -o table
# GCP: verify audit logging config
gcloud logging sinks list
Alert routing must be proven end-to-end (e.g., GuardDuty/Defender/SCC critical finding to PagerDuty/Teams/Slack).
4) Secrets and runtime config handling
Secrets do not belong in repos, image layers, or startup scripts.
# Create secret (AWS)
aws secretsmanager create-secret --name prod/app/db_password --secret-string 'REDACTED'
# Verify rotation enabled
aws secretsmanager describe-secret --secret-id prod/app/db_password --query RotationEnabled
# Azure Key Vault create
az keyvault secret set --vault-name <vault> --name db-password --value "REDACTED"
# GCP Secret Manager create
echo -n "REDACTED" | gcloud secrets create db-password --data-file=-
Operational check: verify application runtime can retrieve secret via role/identity, not embedded key material.
5) Policy and posture validation (CSPM + IaC checks)
# IaC scan in CI
checkov -d ./infra
tfsec ./infra
# AWS config conformance packs
aws configservice describe-conformance-packs
- AWS Config + Security Hub controls
- Azure Policy + Defender recommendations
- GCP SCC findings + org policy constraints
6) Backup and rollback validation
- Known-good config snapshot
- Data backup and restore path verified
- Rollback command tested before release
7) External validation tooling pass
# External service discovery
nmap -sV -Pn <public-host-or-ip> -oG - > actual-ports.txt
# Compare with expected exposure baseline
diff expected-ports.txt actual-ports.txt
# TLS and headers quick pass
openssl s_client -connect <host>:443 -servername <host>
curl -I https://<host> | egrep -i "strict-transport-security|content-security-policy|x-frame-options"
8) Final release gate scorecard + operator workflow
- Identity controls verified
- Network exposure justified and minimized
- Logs + alerts proven end-to-end
- Secrets externalized and rotation-owned
- Posture/IaC checks clean or exception-approved
- Container/image scan passed (
trivy image <image>or cloud-native equivalent) - Rollback path tested
Operator sequence:
1) Validate IAM and auth controls
2) Validate ingress/edge policy + rate limiting
3) Validate telemetry + alert routing
4) Run IaC/posture checks
5) Run image scan gate
6) Confirm backup/rollback readiness
7) Run external validation
8) Approve or block release