Cloud Security Best Practices: Securing Your Infrastructure in 2026
Why Cloud Security Matters More in 2026
I learned cloud security the hard way — by getting a $4,000 bill from AWS after a compromised S3 bucket spawned compute instances to mine cryptocurrency. That was three years ago. Since then, I've worked as a contractor helping startups secure their cloud infrastructure, and I've seen the same mistakes over and over.
Cloud security isn't just about preventing breaches. It's about preventing the kind of breach that costs you your job, your客户's data, or your startup's runway. In 2026, with AI-driven attacks becoming more sophisticated and compliance requirements getting stricter (SOC 2, ISO 27001, GDPR), securing your cloud infrastructure is no longer optional — it's a business requirement.
Here are the practices I now apply to every cloud deployment, whether it's a side project on Cloudflare Workers or a multi-region AWS setup handling customer data.
1. The Principle of Least Privilege — Actually Enforce It
Everyone talks about least privilege. Almost nobody actually practices it. I've audited over 20 cloud accounts this year, and 80% of them had IAM users or service accounts with full administrator access "just in case."
Here's what I do instead:
# AWS IAM policy — grant ONLY what's needed { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:GetObject", "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::my-production-bucket", "arn:aws:s3:::my-production-bucket/*" ] } ] } The same applies to Cloudflare Workers. When I created the API token for deploying this blog, I used the Workers deployment template — not the "All Zones" template. That token can only deploy Workers to one account, nothing else.
Key rules I follow:
- Every service account gets a custom policy scoped to exactly one job
- I create separate tokens for development, staging, and production
- Tokens get rotated every 90 days (calendar reminder, non-negotiable)
- If a service needs to talk to another service, I use IAM roles, not shared credentials
The one exception: for personal projects where I'm the only operator, I still create scoped tokens. It takes 30 seconds and prevents disasters when you inevitably make a mistake.
2. Encryption Everywhere — In Transit and At Rest
By 2026, there's no excuse for plaintext traffic. TLS 1.3 is the minimum. Let's Encrypt made certificates free. Cloudflare, AWS, and every major provider offer free TLS termination.
But encryption at rest is where I see gaps. People assume their cloud provider handles it. They sort-of do — but the defaults aren't great.
# Enable S3 bucket encryption with KMS (not SSE-S3) aws s3api put-bucket-encryption \ --bucket my-production-data \ --server-side-encryption-configuration '{ "Rules": [{ "ApplyServerSideEncryptionByDefault": { "SSEAlgorithm": "aws:kms", "KMSMasterKeyID": "alias/my-data-key" } }] }' Why KMS over SSE-S3? SSE-S3 uses AWS-managed keys, which means AWS can technically decrypt your data. KMS with a customer-managed key gives you control over who can decrypt, automatic key rotation, and audit logs of every decryption request.
For our Cloudflare Workers blog, all traffic is encrypted via Cloudflare's edge (TLS 1.3). Worker responses are also encrypted at Cloudflare's edge. For KV storage, use the built-at encryption — but don't store secrets there.
Quick checklist:
- TLS 1.2 minimum, 1.3 preferred — enforce it at the load balancer
- Cloud storage (S3, R2, GCS) — enable KMS encryption, not just default
- Databases — enable encryption at rest (RDS, DynamoDB, etc.)
- API keys and secrets — use a vault, not environment variables or config files
- Backups — encrypt them too. A backup is just a copy of your data
3. Network Segmentation — Don't Trust Your Own Network
I once audited a startup where the production database was on the same VPC subnet as the staging environment. A developer accidentally ran a migration script pointed at the production database. Twenty minutes of downtime later, they implemented proper network segmentation.
Here's my standard VPC layout:
# AWS VPC with public and private subnets # Public subnets: load balancers, NAT gateways # Private subnets: application servers # Database subnets: RDS, ElastiCache (no internet access) # Security group for web tier resource "aws_security_group" "web" { name = "web-tier" ingress { from_port = 443 to_port = 443 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } } # Security group for app tier — only accepts traffic from web resource "aws_security_group" "app" { name = "app-tier" ingress { from_port = 3000 to_port = 3000 protocol = "tcp" security_groups = [aws_security_group.web.id] } } For serverless architectures like Cloudflare Workers, network segmentation looks different — you can't control the underlying network. Instead, you use:
- Service tokens for authenticating between Workers (internal only)
- WAF rules to block traffic from known bad IPs
- Durable Object namespaces to isolate data between environments
On Cloudflare, I use separate Workers for dev (workers.dev subdomain) and production (custom domain). They share nothing — not KV namespaces, not environment variables.
4. Monitoring and Logging — What You Can't See Can Hurt You
The crypto miner attack I mentioned earlier? I only discovered it when the AWS bill arrived. I had zero monitoring set up. The attacker had been running compute instances for 11 days before I noticed.
Now I monitor everything. Here's what I consider non-negotiable:
# CloudWatch metric alarm for unusual spend aws cloudwatch put-metric-alarm \ --alarm-name "Daily-Spend-Abnormal" \ --metric-name "EstimatedCharges" \ --namespace "AWS/Billing" \ --statistic "Maximum" \ --period 86400 \ --threshold 50.0 \ --comparison-operator "GreaterThanThreshold" \ --evaluation-periods 1 \ --alarm-actions "arn:aws:sns:us-east-1:123456789012:billing-alert" On Cloudflare, I use the built-in Web Analytics (which we have set up for this blog) and Workers Analytics. The key metrics I track daily:
- Request volume spikes — sudden increase could mean a DDoS or a misconfigured client
- Error rates — 5xx errors above 1% trigger investigation
- Cost anomalies — any day with CPU time >2x the 7-day average
- New IPs accessing admin endpoints — could indicate credential stuffing
5. Secrets Management — Stop Putting Keys in Code
In 2026, this should go without saying. Yet I still find API keys hardcoded in GitHub repos weekly. Just last month, I found a startup's AWS secret key in a public GitHub repo — the key had full DynamoDB admin access.
Here's my secrets hierarchy:
- Cloudflare Workers: Use environment variables in wrangler.toml (encrypted at rest) and Workers Secrets for sensitive values
- AWS: Use Secrets Manager or Parameter Store with automatic rotation
- Local development: Use .env files (added to .gitignore — check yours NOW)
- GitHub Actions: Use repository secrets, never plaintext
# In wrangler.toml for this blog [vars] API_ENDPOINT = "https://api.example.com" # Sensitive values set via CLI (never in the file) # npx wrangler secret put DATABASE_URL I rotate credentials on a schedule. Every 90 days for API tokens, every 30 days for database passwords. I built a small script that sends me a Slack reminder, but a calendar invite works too.
6. Regular Security Audits — Automate What You Can
Manual security reviews are important, but they don't scale. I automate as much as possible:
# Automated security audit with Prowler (open source) # Scans AWS accounts against CIS benchmarks prowler aws --checks s3_bucket_level_public_access_block \ s3_bucket_policy_public_write_access \ iam_user_hardware_mfa_enabled \ cloudtrail_enabled \ guardduty_enabled For Cloudflare, I run these checks weekly:
- Are all zones using Universal SSL? (enable it)
- Are there any API tokens with "All Zones" access? (rotate and restrict)
- Is WAF enabled and logging? (it should be)
- Are cached responses properly configured? (no sensitive data in edge cache)
I also use a simple cron job that checks for common misconfigurations — it emails me if anything looks off. The same cron that monitors AdSense forums also runs a quick security check on the blog.
7. Incident Response Plan — Hope for the Best, Plan for the Worst
An incident response plan doesn't need to be a 50-page document. Mine fits on one page:
- Detect: Monitoring alerts me (CloudWatch / Cloudflare Analytics)
- Isolate: Remove affected resources from the network. Revoke compromised credentials
- Assess: What was accessed? What data was exposed? How did they get in?
- Contain: Rotate all credentials. Block the attacker's IP range. Patch the vulnerability
- Recover: Restore from clean backups. Verify integrity
- Post-mortem: Write down what happened. Fix the root cause. Update the plan
The most important step people skip is #6. If you don't learn from an incident, you're guaranteed to repeat it. I keep a "security incidents" doc for every project I run.
The Bottom Line
Cloud security isn't a destination — it's a practice. You don't "get secure" and stop. You build habits that reduce your risk every day.
If you're working on a side project (like this blog), start with the basics:
- Least privilege — scoped tokens for every service
- Encryption — TLS everywhere, KMS for data at rest
- Monitoring — know what's normal so you spot abnormal
- Secrets — never in code, in a vault, rotated regularly
For production systems, add network segmentation and a proper incident response plan. These 7 practices won't make you unhackable — but they'll make you a much harder target than the 90% of cloud deployments that skip them entirely.
Got a cloud security story or tip of your own? I'd love to hear it.