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

6) Backup and rollback validation

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

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
This checklist works because every gate maps to a command, a tool, and a pass/fail decision — not a policy paragraph someone skims and forgets. I run it the same way every time: identity first, network second, logging proven before anything goes public. If a step can't produce evidence, the service doesn't ship. Hardening isn't a phase — it's the release criteria.