<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Dhruv malaviya</title>
    <description>The latest articles on DEV Community by Dhruv malaviya (@dhruv_malaviya_cdcc71e595).</description>
    <link>https://dev.to/dhruv_malaviya_cdcc71e595</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3964043%2Ffbef3b8c-07dc-4123-b52d-7523c1088dec.jpg</url>
      <title>DEV Community: Dhruv malaviya</title>
      <link>https://dev.to/dhruv_malaviya_cdcc71e595</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dhruv_malaviya_cdcc71e595"/>
    <language>en</language>
    <item>
      <title>Cloud Infrastructure Security in 2025: Why I Started Treating Every App Like a Fortress</title>
      <dc:creator>Dhruv malaviya</dc:creator>
      <pubDate>Sat, 11 Jul 2026 10:51:57 +0000</pubDate>
      <link>https://dev.to/dhruv_malaviya_cdcc71e595/cloud-infrastructure-security-in-2025-why-i-started-treating-every-app-like-a-fortress-5dgb</link>
      <guid>https://dev.to/dhruv_malaviya_cdcc71e595/cloud-infrastructure-security-in-2025-why-i-started-treating-every-app-like-a-fortress-5dgb</guid>
      <description>&lt;p&gt;A practical look at container escape risks, public-IP scanning, and how Firecracker microVMs on &lt;strong&gt;Krova Cloud&lt;/strong&gt; changed how I think about cloud infrastructure security.&lt;/p&gt;

&lt;p&gt;The moment I stopped trusting my own stack&lt;br&gt;
A few months ago, I got that Slack message nobody wants:&lt;/p&gt;

&lt;p&gt;"One of our containers is acting weird. High CPU. Unknown process. Can you check?"&lt;/p&gt;

&lt;p&gt;It turned out to be a cryptominer. Not because someone hacked our app. Not because we leaked secrets. But because another tenant on the same host had a vulnerable container, and the attacker escaped into the shared kernel.&lt;/p&gt;

&lt;p&gt;We didn't do anything wrong. We followed the playbook: updated images, minimal privileges, read-only root filesystems. But we were still sitting on the same kernel as everyone else.&lt;/p&gt;

&lt;p&gt;That incident made me ask a question I'd never seriously considered:&lt;/p&gt;

&lt;p&gt;What if the real cloud security problem isn't our configuration - it's the architecture underneath?&lt;/p&gt;

&lt;p&gt;This post is the answer I found. It's about why I started thinking of every app as its own fortress, and how platforms like Krova Cloud make that practical.&lt;/p&gt;

&lt;p&gt;The two lies we tell ourselves about cloud security&lt;br&gt;
Lie #1: "Containers are isolated enough"&lt;br&gt;
Containers isolate processes. They don't isolate kernels.&lt;/p&gt;

&lt;p&gt;Every container on a host shares the same Linux kernel. That's by design — it's why containers are fast and lightweight. But it also means a single kernel vulnerability can compromise every container on that machine.&lt;/p&gt;

&lt;p&gt;Recent CVEs like Dirty Pipe, CVE-2022-0847, and privilege-escalation chains have shown this repeatedly. You don't need a zero-day. You need one kernel bug and one noisy neighbor.&lt;/p&gt;

&lt;p&gt;┌─────────────────────────────────────┐&lt;br&gt;
│           Host Kernel               │  ← one shared kernel&lt;br&gt;
├─────────────┬─────────────┬─────────┤&lt;br&gt;
│ Container 1 │ Container 2 │   Your  │&lt;br&gt;
│   (tenant)  │   (tenant)  │   app   │&lt;br&gt;
└─────────────┴─────────────┴─────────┘&lt;br&gt;
If an attacker breaks out of any container, they can potentially touch yours.&lt;/p&gt;

&lt;p&gt;Lie #2: "A public IP is just how servers work"&lt;br&gt;
The second lie is that every server needs a public IP address.&lt;/p&gt;

&lt;p&gt;It doesn't. But VPS providers hand them out by default because it's convenient. The problem? That IP is now on the internet 24/7, being scanned, brute-forced, and probed by bots.&lt;/p&gt;

&lt;p&gt;Within minutes of launching a typical VPS, you'll see:&lt;/p&gt;

&lt;p&gt;SSH brute-force attempts&lt;br&gt;
Port scans on every service&lt;br&gt;
Automated exploit attempts&lt;br&gt;
Your security model becomes: "I have a public address, and I hope my firewall rules are perfect."&lt;/p&gt;

&lt;p&gt;Spoiler: they usually aren't.&lt;/p&gt;

&lt;p&gt;What if isolation meant a real kernel?&lt;br&gt;
This is where microVMs come in.&lt;/p&gt;

&lt;p&gt;A microVM is a lightweight virtual machine. Unlike a container, each microVM boots its own kernel. Unlike a traditional VM, it starts in milliseconds - fast enough to spin up and tear down like a container.&lt;/p&gt;

&lt;p&gt;The technology behind this is Firecracker, the same isolation engine AWS uses for Lambda and Fargate. It's designed for:&lt;/p&gt;

&lt;p&gt;Strong isolation (full VM boundary)&lt;br&gt;
Fast startup (sub-second boot)&lt;br&gt;
Low overhead (minimal resource usage)&lt;br&gt;
High density (many VMs on one host)&lt;/p&gt;

&lt;p&gt;┌─────────────────────────────────────────────┐&lt;br&gt;
│              Host Hardware                  │&lt;br&gt;
├─────────────────┬───────────────────────────┤&lt;br&gt;
│   VM 1          │   VM 2        │   Your   │&lt;br&gt;
│  own kernel     │  own kernel   │   app    │&lt;br&gt;
└─────────────────┴───────────────┴──────────┘&lt;br&gt;
Each VM has its own kernel. A kernel bug in one can't reach another.&lt;/p&gt;

&lt;p&gt;How Krova Cloud turns microVMs into a security model&lt;br&gt;
That's the theory. Krova Cloud is the practice.&lt;/p&gt;

&lt;p&gt;Krova Cloud calls its microVMs Cubes. Each Cube is a Firecracker microVM with a few security-first design choices that directly solve the problems I mentioned:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcsavu8pqurjl05i2igfm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcsavu8pqurjl05i2igfm.png" alt=" " width="800" height="302"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But the part that matters most? It's not just secure , it's usable.&lt;/p&gt;

&lt;p&gt;Spinning up a Cube: from zero to root in seconds&lt;br&gt;
Here's what provisioning looks like with the Krova CLI:&lt;/p&gt;

&lt;p&gt;Bash&lt;/p&gt;

&lt;p&gt;`# Install the CLI&lt;br&gt;
npm i -g &lt;a class="mentioned-user" href="https://dev.to/krovacloud"&gt;@krovacloud&lt;/a&gt;/cli&lt;/p&gt;

&lt;h1&gt;
  
  
  Create a Cube
&lt;/h1&gt;

&lt;p&gt;krova cubes create web-1 \&lt;br&gt;
  --cpu 2 \&lt;br&gt;
  --ram 4 \&lt;br&gt;
  --disk 40 \&lt;br&gt;
  --image ubuntu-24.04&lt;/p&gt;

&lt;h1&gt;
  
  
  SSH in with full root access
&lt;/h1&gt;

&lt;p&gt;krova ssh web-1&lt;br&gt;
root@web-1:~#`&lt;br&gt;
No VPCs. No security groups. No IAM roles. No launch templates. Just a real VM, isolated by hardware virtualization, booted in under a second.&lt;/p&gt;

&lt;p&gt;If you prefer code, the REST API is just as simple:&lt;/p&gt;

&lt;p&gt;Bash&lt;/p&gt;

&lt;p&gt;&lt;code&gt;curl -X POST https://krova.cloud/api/v1/spaces/$SPACE/cubes \&lt;br&gt;
  -H "X-API-KEY: $KROVA_KEY" \&lt;br&gt;
  -H "Idempotency-Key: $(uuidgen)" \&lt;br&gt;
  -d '{&lt;br&gt;
    "name": "web-1",&lt;br&gt;
    "image": "ubuntu-24.04",&lt;br&gt;
    "resources": { "vcpu": 2, "ramGb": 4, "diskGb": 40 },&lt;br&gt;
    "sshPublicKey": "ssh-ed25519 AAAA...",&lt;br&gt;
    "region": "eu-central"&lt;br&gt;
  }'&lt;/code&gt;&lt;br&gt;
Same result: one isolated Cube, own kernel, no public IP.&lt;/p&gt;

&lt;p&gt;What "no public IP" actually means for security&lt;br&gt;
This is the part that took me a while to fully appreciate.&lt;/p&gt;

&lt;p&gt;When a Cube has no public IP, it literally doesn't exist on the public internet. There's no address to scan. No port to probe. No brute-force target.&lt;/p&gt;

&lt;p&gt;Inbound traffic only reaches your Cube through Krova Cloud's managed ingress layer:&lt;/p&gt;

&lt;p&gt;Web traffic enters through a TLS-terminated edge&lt;br&gt;
Your custom domain points to that edge, not to your Cube&lt;br&gt;
The Cube origin stays hidden&lt;br&gt;
Non-web services use explicit port mappings with IP allowlists&lt;br&gt;
text&lt;/p&gt;

&lt;p&gt;Internet  →  Krova Ingress (TLS, DDoS-mitigated)&lt;br&gt;
                  ↓&lt;br&gt;
            Hidden origin&lt;br&gt;
                  ↓&lt;br&gt;
            Your Cube (private IP)&lt;br&gt;
Compare that to a standard VPS:&lt;/p&gt;

&lt;p&gt;text&lt;/p&gt;

&lt;p&gt;Internet  →  Your public IP&lt;br&gt;
                  ↓&lt;br&gt;
            Your server (ssh, db, api all exposed)&lt;br&gt;
The difference is night and day. With no public IP, the attacker can't attack what they can't find.&lt;/p&gt;

&lt;p&gt;Mapping Krova's design to real cloud security principles&lt;br&gt;
Let's translate the Cube architecture into the security fundamentals we all know:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Defense in depth
A Cube isn't just one layer of isolation. It's several:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Hardware virtualization via KVM&lt;br&gt;
Separate kernel per VM&lt;br&gt;
Jailer sandbox around the hypervisor&lt;br&gt;
No public IP&lt;br&gt;
Stateful default-deny firewall&lt;br&gt;
IP-allowlisted port mappings&lt;br&gt;
Managed TLS ingress&lt;br&gt;
That's defense in depth without you configuring any of it.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Least privilege
By default, nothing is reachable. You have to explicitly open a port. And when you do, you can lock it to a specific IP range.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Bash&lt;/p&gt;

&lt;p&gt;&lt;code&gt;# Example: open SSH only from your office IP&lt;br&gt;
krova ports add web-1 \&lt;br&gt;
  --protocol tcp \&lt;br&gt;
  --port 22 \&lt;br&gt;
  --allowed-ips 203.0.113.0/24&lt;/code&gt;&lt;br&gt;
This is least privilege applied to networking.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Attack surface reduction
No public IP means no SSH brute-forcing. No open database ports scanned by Shodan. No accidental exposure because someone misconfigured a security group.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The attack surface is reduced by architecture, not by hoping humans never make mistakes.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Isolation of failure
If one Cube is compromised, the blast radius is that Cube. Not the host. Not other tenants. Not your entire stack.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When microVMs make sense (and when they don't)&lt;br&gt;
I'm not here to say containers are dead. They're not. But I think we overuse them for workloads that need real isolation.&lt;/p&gt;

&lt;p&gt;MicroVMs are a great fit for:&lt;br&gt;
User-submitted code (judge0-style platforms, coding interviews)&lt;br&gt;
AI agents that run arbitrary shell commands&lt;br&gt;
CI/CD runners that should start clean every time&lt;br&gt;
Multi-tenant SaaS where each customer needs isolation&lt;br&gt;
Databases and stateful services that benefit from a real kernel&lt;br&gt;
Anything handling untrusted data&lt;br&gt;
Containers are still fine for:&lt;br&gt;
Internal microservices with trusted code&lt;br&gt;
Development environments&lt;br&gt;
Workloads where density and speed matter more than isolation&lt;br&gt;
Teams already heavily invested in Kubernetes&lt;br&gt;
The key is choosing the right isolation model for the risk.&lt;/p&gt;

&lt;p&gt;A cloud security checklist for 2025&lt;br&gt;
Whether you use Krova Cloud, AWS, Azure, or a mix, here's my current checklist:&lt;/p&gt;

&lt;p&gt;Markdown&lt;/p&gt;

&lt;p&gt;□ Assume shared kernels can be compromised — isolate high-risk workloads&lt;br&gt;
□ Avoid public IPs unless absolutely necessary&lt;br&gt;
□ Use IP allowlists for any administrative access&lt;br&gt;
□ Enable MFA for all cloud consoles and SSH jump hosts&lt;br&gt;
□ Rotate access keys every 90 days (or use temporary credentials)&lt;br&gt;
□ Block public access on all storage buckets by default&lt;br&gt;
□ Scan repos for leaked secrets before every merge&lt;br&gt;
□ Centralize logs and set alerts for root login, IAM changes, and public exposure&lt;br&gt;
□ Test your incident response plan before you need it&lt;br&gt;
□ Review your architecture choices as often as your code&lt;br&gt;
The last one is the hardest — and the most important.&lt;/p&gt;

&lt;p&gt;Why this changed how I build&lt;br&gt;
Before the cryptominer incident, I thought cloud security was about configuration: the right IAM policies, the right firewall rules, the right patches.&lt;/p&gt;

&lt;p&gt;I still think those matter. But I now believe the foundation matters more.&lt;/p&gt;

&lt;p&gt;If your architecture assumes a shared kernel and a public IP, you're asking your configuration to be perfect forever. That's a losing game.&lt;/p&gt;

&lt;p&gt;If your architecture gives every workload its own kernel and hides it from the public internet, you've made security the default. That's a much better place to operate from.&lt;/p&gt;

&lt;p&gt;That's why I started using Krova Cloud for workloads where isolation matters. Not because it's a magic bullet, but because it aligns the default architecture with good security hygiene.&lt;/p&gt;

&lt;p&gt;Try it yourself&lt;br&gt;
If you're curious, you can spin up a Cube for free (signup doesn't require a card, and the first $5 top-up doubles to $10):&lt;/p&gt;

&lt;p&gt;Bash&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm i -g @krovacloud/cli&lt;br&gt;
krova signup&lt;br&gt;
krova cubes create security-test --cpu 1 --ram 2 --disk 20 --image ubuntu-24.04&lt;br&gt;
krova ssh security-test&lt;/code&gt;&lt;br&gt;
Once inside, run ss -tlnp and notice something beautiful: there are no public listening ports. Your server exists, but it's invisible to the internet.&lt;/p&gt;

&lt;p&gt;Final thoughts&lt;br&gt;
Cloud infrastructure security isn't just about tools and checklists. It's about architecture.&lt;/p&gt;

&lt;p&gt;Containers gave us speed. microVMs give us speed and isolation.&lt;/p&gt;

&lt;p&gt;Platforms like Krova Cloud make that isolation practical for everyday developers. And in a world where kernel bugs and automated scanning are constants, I think that's worth paying attention to.&lt;/p&gt;

&lt;p&gt;What's your take? Are you still comfortable with shared kernels for sensitive workloads? Or are you already exploring microVMs and Firecracker? Drop a comment — I'd love to hear what's working for you.&lt;/p&gt;

&lt;p&gt;Resources&lt;br&gt;
&lt;a href="//krova.cloud"&gt;Krova Cloud&lt;/a&gt;&lt;br&gt;
&lt;a href="https://krova.cloud/security" rel="noopener noreferrer"&gt;Krova Cloud Security&lt;/a&gt;&lt;br&gt;
&lt;a href="https://firecracker-microvm.github.io/" rel="noopener noreferrer"&gt;Firecracker microVMs&lt;/a&gt;&lt;br&gt;
&lt;a href="https://aws.amazon.com/blogs/aws/firecracker-lightweight-virtualization-for-serverless-computing/" rel="noopener noreferrer"&gt;AWS Lambda under the hood&lt;/a&gt;&lt;br&gt;
&lt;a href="https://csrc.nist.gov/publications/detail/sp/800-190/final" rel="noopener noreferrer"&gt;NIST SP 800-190: Application Container Security Guide&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks for reading. &lt;br&gt;
If you found this helpful, hit the ❤️ and follow for more cloud security and infrastructure posts.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>5 Cloud Security Mistakes That'll Get You Hacked (And How to Fix Them)</title>
      <dc:creator>Dhruv malaviya</dc:creator>
      <pubDate>Wed, 01 Jul 2026 09:14:17 +0000</pubDate>
      <link>https://dev.to/dhruv_malaviya_cdcc71e595/5-cloud-security-mistakes-thatll-get-you-hacked-and-how-to-fix-them-402a</link>
      <guid>https://dev.to/dhruv_malaviya_cdcc71e595/5-cloud-security-mistakes-thatll-get-you-hacked-and-how-to-fix-them-402a</guid>
      <description>&lt;p&gt;&lt;strong&gt;5 Cloud Security Mistakes That'll Get You Hacked&lt;br&gt;
A friend's startup got breached last month.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Cause? Public S3 bucket with customer data.&lt;/p&gt;

&lt;p&gt;Fix time? 5 minutes.&lt;/p&gt;

&lt;p&gt;Damage? $50K + lost customer trust.&lt;/p&gt;

&lt;p&gt;Don't be that startup. Here are the 5 mistakes I see every week&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Wildcard IAM Policies ❌&lt;/strong&gt;&lt;br&gt;
JSON&lt;/p&gt;

&lt;p&gt;&lt;code&gt;{ "Action": "*", "Resource": "*" }&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix — Be specific:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;{&lt;br&gt;
  "Action": ["s3:GetObject", "s3:PutObject"],&lt;br&gt;
  "Resource": "arn:aws:s3:::my-bucket/*"&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Public Storage Buckets ❌&lt;/strong&gt;&lt;br&gt;
Fix — Block public access:&lt;/p&gt;

&lt;p&gt;Bash&lt;/p&gt;

&lt;p&gt;&lt;code&gt;aws s3control put-public-access-block \&lt;br&gt;
    --account-id 123456789012 \&lt;br&gt;
    --public-access-block-configuration \&lt;br&gt;
    "BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. No Encryption ❌&lt;br&gt;
Fix — Enable default encryption:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;hcl&lt;/p&gt;

&lt;p&gt;`resource "aws_s3_bucket_server_side_encryption_configuration" "example" {&lt;br&gt;
  bucket = aws_s3_bucket.my_bucket.id&lt;/p&gt;

&lt;p&gt;rule {&lt;br&gt;
    apply_server_side_encryption_by_default {&lt;br&gt;
      sse_algorithm = "aws:kms"&lt;br&gt;
    }&lt;br&gt;
  }&lt;br&gt;
}`&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Missing MFA ❌&lt;br&gt;
Fix — Enforce via SCP:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;JSON&lt;/p&gt;

&lt;p&gt;&lt;code&gt;{&lt;br&gt;
  "Effect": "Deny",&lt;br&gt;
  "Action": "*",&lt;br&gt;
  "Resource": "*",&lt;br&gt;
  "Condition": {&lt;br&gt;
    "BoolIfExists": {"aws:MultiFactorAuthPresent": "false"}&lt;br&gt;
  }&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. No Monitoring ❌&lt;br&gt;
Fix — Quick security scan:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Bash&lt;/p&gt;

&lt;p&gt;`#!/bin/bash&lt;br&gt;
echo "🔍 Checking public S3 buckets..."&lt;br&gt;
aws s3api list-buckets --query 'Buckets[].Name' --output text | while read bucket; do&lt;br&gt;
    aws s3api get-public-access-block --bucket $bucket 2&amp;gt;/dev/null || echo "⚠️  $bucket: No public access block!"&lt;br&gt;
done&lt;/p&gt;

&lt;p&gt;echo "🔒 Checking open security groups..."&lt;br&gt;
aws ec2 describe-security-groups \&lt;br&gt;
    --filters "Name=ip-permission.cidr,Values=0.0.0.0/0" \&lt;br&gt;
    --query 'SecurityGroups[].GroupName' --output text&lt;/p&gt;

&lt;p&gt;echo "👤 Checking MFA..."&lt;br&gt;
aws iam list-users --query 'Users[].UserName' --output text | while read user; do&lt;br&gt;
    aws iam list-mfa-devices --user-name $user --query 'MFADevices' --output text | grep -q . || echo "⚠️  $user: No MFA!"&lt;br&gt;
done`&lt;/p&gt;

&lt;p&gt;**Quick Tools&lt;br&gt;
**Bash&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pip install prowler&lt;br&gt;
prowler aws --checks cis_2.0&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Do This NOW&lt;br&gt;
*&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; Enable S3 Block Public Access&lt;/li&gt;
&lt;li&gt; Turn on default encryption&lt;/li&gt;
&lt;li&gt; Enable MFA on root account&lt;/li&gt;
&lt;li&gt; Run Prowler scan
TL;DR: Least privilege + Encryption + MFA + Monitoring = 95% fewer breaches.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Like this? ❤️ Follow for more quick DevOps tips.&lt;/p&gt;

&lt;h1&gt;
  
  
  cloudsecurity #aws #devops
&lt;/h1&gt;

</description>
      <category>cloudsecurity</category>
      <category>aws</category>
      <category>devops</category>
      <category>cloudcomputing</category>
    </item>
    <item>
      <title>4 Shopify API &amp; Headless Gotchas Every Developer Hits (And How to Fix Them)</title>
      <dc:creator>Dhruv malaviya</dc:creator>
      <pubDate>Tue, 30 Jun 2026 10:35:00 +0000</pubDate>
      <link>https://dev.to/dhruv_malaviya_cdcc71e595/4-shopify-api-headless-gotchas-every-developer-hits-and-how-to-fix-them-4mfe</link>
      <guid>https://dev.to/dhruv_malaviya_cdcc71e595/4-shopify-api-headless-gotchas-every-developer-hits-and-how-to-fix-them-4mfe</guid>
      <description>&lt;p&gt;When you first start building a custom Shopify app or a headless Next.js storefront, the ecosystem feels like magic.&lt;/p&gt;

&lt;p&gt;Then you deploy to production, real customers start checking out, and your webhooks start silently failing at 2:00 AM.&lt;/p&gt;

&lt;p&gt;Unlike standard web apps, e-commerce development has zero room for unhandled exceptions—a broken API call literally means lost revenue. Before you push your next Shopify integration, make sure you aren't falling into these 4 developer traps:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Ignoring Webhook Idempotency (Duplicate Orders)&lt;/strong&gt;&lt;br&gt;
Shopify’s webhook delivery system guarantees at-least-once delivery. This means during high-traffic sales, Shopify will frequently fire the exact same ORDERS_CREATE webhook two or three times for a single purchase.&lt;/p&gt;

&lt;p&gt;If your backend unconditionally inserts records or triggers fulfillment emails, you will duplicate orders.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Fix:&lt;/strong&gt; Always grab the X-Shopify-Webhook-Id header and store it in Redis or your database with a 24-hour TTL before processing the payload:&lt;br&gt;
JavaScript&lt;/p&gt;

&lt;p&gt;const webhookId = req.headers['x-shopify-webhook-id'];&lt;/p&gt;

&lt;p&gt;&lt;code&gt;// Check if we already processed this exact webhook event&lt;br&gt;
const alreadyProcessed = await redis.get(&lt;/code&gt;webhook:${webhookId}`);&lt;br&gt;
if (alreadyProcessed) {&lt;br&gt;
  return res.status(200).send('Duplicate webhook ignored');&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;await redis.set(&lt;code&gt;webhook:${webhookId}&lt;/code&gt;, 'true', 'EX', 86400);&lt;br&gt;
// Now safe to process order...`&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Getting Throttled by GraphQL "Cost-Based" Limits&lt;/strong&gt;&lt;br&gt;
Unlike standard REST APIs that limit you to X requests per minute, Shopify’s GraphQL Admin API uses a Calculated Query Cost model (a leaky bucket holding 1,000 points).&lt;/p&gt;

&lt;p&gt;If you write a deeply nested query fetching 50 products, their variants, and their inventory quantities all at once, a single query can cost 800 points and instantly trigger a THROTTLED error.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Fix:&lt;/strong&gt; Request only the scalar fields you strictly need, and use pagination cursors (first: 10, after: $cursor) instead of requesting massive arrays.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Exposing Admin API Keys in Client Bundles&lt;/strong&gt;&lt;br&gt;
When building headless storefronts (Next.js, Remix, Nuxt), developers frequently confuse Shopify's two primary APIs:&lt;/p&gt;

&lt;p&gt;Storefront API: Public, unauthenticated (Safe for browser/client requests).&lt;br&gt;
Admin API: Highly privileged (Strictly server-side only).&lt;br&gt;
If you accidentally prefix your Admin API access token with NEXT_PUBLIC_ in your .env file, any user inspecting your site's JavaScript bundle can steal it and modify store products or customer data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Assuming All Currencies Have 2 Decimal Places&lt;/strong&gt;&lt;br&gt;
If you are writing custom frontend pricing logic and format prices by doing Math.round(amount * 100) / 100, your code will break the moment the store expands internationally.&lt;/p&gt;

&lt;p&gt;Currencies like the Japanese Yen (JPY) or South Korean Won (KRW) are zero-decimal currencies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Fix:&lt;/strong&gt; Never manually parse decimal placement. Delegate formatting to native JavaScript Intl.NumberFormat:&lt;br&gt;
JavaScript&lt;/p&gt;

&lt;p&gt;&lt;code&gt;const formattedPrice = new Intl.NumberFormat('en-US', {&lt;br&gt;
  style: 'currency',&lt;br&gt;
  currency: product.currencyCode, // e.g., 'USD' or 'JPY'&lt;br&gt;
}).format(product.amount);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🛡️ Quick Takeaway&lt;/strong&gt;&lt;br&gt;
When developing for Shopify, always program defensively against network duplicates, API cost throttling, and international edge cases.&lt;/p&gt;

&lt;p&gt;What was the most frustrating bug you ran into while building a Shopify app or theme? Drop your debugging war story in the comments below! 👇 (Hit 🦄 or 💖 if this saved your webhook logic).&lt;/p&gt;

</description>
      <category>api</category>
      <category>nextjs</category>
      <category>tutorial</category>
      <category>webdev</category>
    </item>
    <item>
      <title>4 AWS Infrastructure Gotchas That Will Get Your Account Hacked (And How to Fix Them in Terraform)</title>
      <dc:creator>Dhruv malaviya</dc:creator>
      <pubDate>Mon, 29 Jun 2026 13:03:23 +0000</pubDate>
      <link>https://dev.to/dhruv_malaviya_cdcc71e595/4-aws-infrastructure-gotchas-that-will-get-your-account-hacked-and-how-to-fix-them-in-terraform-3jm5</link>
      <guid>https://dev.to/dhruv_malaviya_cdcc71e595/4-aws-infrastructure-gotchas-that-will-get-your-account-hacked-and-how-to-fix-them-in-terraform-3jm5</guid>
      <description>&lt;p&gt;We’ve all heard the horror stories: a developer pushes a quick Terraform module on Friday afternoon, and wakes up Monday to a $14,000 AWS bill because bots turned their staging environment into a Monero mining cluster.&lt;/p&gt;

&lt;p&gt;The terrifying part about AWS security isn't sophisticated zero-day exploits—it’s default misconfigurations.&lt;/p&gt;

&lt;p&gt;Before you run terraform apply today, audit your code against these 4 bite-sized security fixes:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Kill Wildcard (*) IAM Permissions&lt;/strong&gt;&lt;br&gt;
When you hit a 403 Access Denied error, it’s tempting to test with "Action": "&lt;em&gt;", "Resource": "&lt;/em&gt;". If committed, a single app vulnerability lets attackers wipe your AWS account.&lt;/p&gt;

&lt;p&gt;The Fix: Always hardcode least-privilege API actions and scope down to exact resource ARNs:&lt;br&gt;
hcl&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Action   = ["dynamodb:GetItem", "dynamodb:Query"]&lt;br&gt;
Resource = "arn:aws:dynamodb:us-east-1:123456789012:table/prod-users"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Lock Down S3 Buckets Explicitly&lt;/strong&gt;&lt;br&gt;
Automated scanners enumerate millions of bucket names per hour. If you don't explicitly block public access, your uploads will be discovered and dumped.&lt;/p&gt;

&lt;p&gt;The Fix: Always attach an explicit public access block to every bucket:&lt;br&gt;
hcl&lt;/p&gt;

&lt;p&gt;&lt;code&gt;resource "aws_s3_bucket_public_access_block" "lockdown" {&lt;br&gt;
  bucket                  = aws_s3_bucket.app_bucket.id&lt;br&gt;
  block_public_acls       = true&lt;br&gt;
  block_public_policy     = true&lt;br&gt;
  ignore_public_acls      = true&lt;br&gt;
  restrict_public_buckets = true&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Never Open DB Ports to 0.0.0.0/0&lt;/strong&gt;&lt;br&gt;
Opening port 5432 (PostgreSQL) or 3306 (MySQL) to 0.0.0.0/0 so you can connect your local DB GUI invites automated brute-force bots within 10 minutes.&lt;/p&gt;

&lt;p&gt;The Fix: Keep databases in private subnets. Only allow ingress from your app server's Security Group ID:&lt;br&gt;
hcl&lt;/p&gt;

&lt;p&gt;&lt;code&gt;source_security_group_id = aws_security_group.app_server_sg.id&lt;/code&gt;&lt;br&gt;
(Need local GUI access? Use AWS SSM Port Forwarding to tunnel in without open inbound ports).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Ditch Static CI/CD Access Keys&lt;/strong&gt;&lt;br&gt;
Stop generating AWS IAM Users with static .env Secret Access Keys for GitHub Actions deployments.&lt;/p&gt;

&lt;p&gt;The Fix: Switch to OpenID Connect (OIDC) federation. Let GitHub Actions assume a temporary AWS IAM Role dynamically per run, generating short-lived tokens that expire immediately after deployment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🛡️ The 5-Second Pre-Commit Check&lt;/strong&gt;&lt;br&gt;
Catch these footguns automatically before pushing code by running an open-source scanner in your terminal:&lt;/p&gt;

&lt;p&gt;Bash&lt;/p&gt;

&lt;p&gt;&lt;code&gt;# Instantly flags open SGs, missing crypto, and wildcards&lt;br&gt;
trivy config ./terraform-dir&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;What is your favorite CLI tool for catching cloud infrastructure bugs? Drop it in the comments! 👇 (Hit 🦄 if this reminded you to check your security groups today).&lt;/p&gt;

</description>
      <category>aws</category>
      <category>terraform</category>
      <category>devops</category>
      <category>security</category>
    </item>
    <item>
      <title>I analyzed 30 winning dropshipping products. 7 patterns they all share.</title>
      <dc:creator>Dhruv malaviya</dc:creator>
      <pubDate>Fri, 26 Jun 2026 09:15:30 +0000</pubDate>
      <link>https://dev.to/dhruv_malaviya_cdcc71e595/i-analyzed-30-winning-dropshipping-products-7-patterns-they-all-share-2j2b</link>
      <guid>https://dev.to/dhruv_malaviya_cdcc71e595/i-analyzed-30-winning-dropshipping-products-7-patterns-they-all-share-2j2b</guid>
      <description>&lt;p&gt;Looked at 30 products running Meta + TikTok ads&lt;br&gt;
profitably. 7 patterns every single one had:&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;PRICE&lt;/strong&gt;: $25-$65&lt;br&gt;
Below = thin margins. Above = harder impulse.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;BUNDLE OPTIONS&lt;/strong&gt;&lt;br&gt;
"Buy 2 save 10% / Buy 3 save 15%" — every store had&lt;br&gt;
this. None were single-product only.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;VISUAL HOOK IN 3 SECONDS&lt;/strong&gt;&lt;br&gt;
Unique design, specific problem solved, or "wow factor."&lt;br&gt;
Generic products failed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;REAL REVIEWS WITH PHOTOS&lt;/strong&gt;&lt;br&gt;
Not 5-star spam. Real, mixed reviews. Even negatives&lt;br&gt;
build trust.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SHIPPING TIME ON PDP&lt;/strong&gt;&lt;br&gt;
Every store disclosed it directly. None hid it in FAQ.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;STICKY ADD-TO-CART ON MOBILE&lt;/strong&gt;&lt;br&gt;
All 30 had it. If your Add to Cart scrolls off-screen&lt;br&gt;
on mobile, you're losing sales.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;POST-PURCHASE UPSELL&lt;/strong&gt;&lt;br&gt;
"Add this for $X" / subscription / bulk refill.&lt;br&gt;
This is where AOV lives.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;WHAT THEY DIDN'T HAVE&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Live chat (only 4/30)&lt;/li&gt;
&lt;li&gt;Exit-intent popups (only 2/30)&lt;/li&gt;
&lt;li&gt;Countdown timers (only 3/30)&lt;/li&gt;
&lt;li&gt;Countdown timers (only 3/30 — most had REAL
shipping urgency instead)&lt;/li&gt;
&lt;li&gt;Multiple payment options visible on PDP (most just
had Shopify default)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The "guru tactics" aren't what winning stores use.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;3 QUICK WINS&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pick products with visual hooks&lt;/li&gt;
&lt;li&gt;Bundle by default&lt;/li&gt;
&lt;li&gt;Fix PDP before scaling ads&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>shopify</category>
      <category>webdev</category>
      <category>ecommerce</category>
      <category>website</category>
    </item>
    <item>
      <title>Why I Switched to Krova.cloud - Better Security, No Overselling, 40% Cheaper</title>
      <dc:creator>Dhruv malaviya</dc:creator>
      <pubDate>Thu, 11 Jun 2026 06:44:15 +0000</pubDate>
      <link>https://dev.to/dhruv_malaviya_cdcc71e595/why-i-switched-to-krovacloud-better-security-no-overselling-40-cheaper-23fm</link>
      <guid>https://dev.to/dhruv_malaviya_cdcc71e595/why-i-switched-to-krovacloud-better-security-no-overselling-40-cheaper-23fm</guid>
      <description>&lt;p&gt;Hey Devs 👋&lt;/p&gt;

&lt;p&gt;Tired of paying premium prices for oversold, shared-kernel cloud infrastructure? Same. Let me introduce you to Krova.cloud — here's why it caught my attention:&lt;/p&gt;

&lt;p&gt;🔐 No Shared Kernel Each VM (called a Cube) runs its own isolated kernel via Firecracker microVM technology - same tech behind AWS Lambda. No shared kernel = no cross-tenant risk. Real isolation, not container-level illusions.&lt;/p&gt;

&lt;p&gt;🌐 No Public IP Exposure Your Cube doesn't sit naked on the internet. &lt;/p&gt;

&lt;p&gt;💾 Backups Done Right&lt;/p&gt;

&lt;p&gt;✅ RAID 1 mirrored disks - drive failure won't kill your server&lt;br&gt;
✅ Snapshots built-in - not a paid add-on&lt;br&gt;
✅ Backups stored on separate redundant storage&lt;br&gt;
📊 RAM &amp;amp; Disk - Sold 1:1 Most providers thin-provision their hardware and oversell it. Krova sells every GB of RAM and disk 1:1 with actual hardware. What you pay for is genuinely yours. No noisy neighbors. No surprise slowdowns.&lt;/p&gt;

&lt;p&gt;💸 Price? 40%+ cheaper than AWS Lightsail, DigitalOcean &amp;amp; Vultr. Per-hour billing. No hidden fees. Custom-sized VMs - no forced bundles.&lt;/p&gt;

&lt;p&gt;Free $5 credits to start - no credit card needed 👉 krova.cloud 🙌&lt;/p&gt;

</description>
      <category>devops</category>
      <category>cloud</category>
      <category>security</category>
      <category>linux</category>
    </item>
    <item>
      <title>Krova: a security-first “VPS” where your server has no public IP by default</title>
      <dc:creator>Dhruv malaviya</dc:creator>
      <pubDate>Thu, 11 Jun 2026 05:19:33 +0000</pubDate>
      <link>https://dev.to/dhruv_malaviya_cdcc71e595/krova-a-security-first-vps-where-your-server-has-no-public-ip-by-default-55m1</link>
      <guid>https://dev.to/dhruv_malaviya_cdcc71e595/krova-a-security-first-vps-where-your-server-has-no-public-ip-by-default-55m1</guid>
      <description>&lt;p&gt;Most “I got hacked” (or “why is this box getting hammered?”) stories I’ve seen start with the same default: &lt;em&gt;every server gets a public IP&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I’ve been working on &lt;strong&gt;Krova&lt;/strong&gt; — cloud compute that flips that default.&lt;/p&gt;

&lt;p&gt;The 4 ideas (quick)&lt;br&gt;
1) &lt;strong&gt;No public IP per server by default&lt;/strong&gt;&lt;br&gt;
A Krova “Cube” (server) lives on a private NAT’d network. There isn’t a public IP sitting out there waiting to get scanned.&lt;/p&gt;

&lt;p&gt;2) &lt;strong&gt;No shared kernel&lt;/strong&gt;&lt;br&gt;
Each Cube runs as a &lt;strong&gt;Firecracker microVM&lt;/strong&gt; with its &lt;strong&gt;own kernel&lt;/strong&gt; - not shared-kernel containers.&lt;/p&gt;

&lt;p&gt;3) &lt;strong&gt;Snapshots + restore/rollback&lt;/strong&gt;&lt;br&gt;
Built-in snapshots so “snapshot before upgrade → rollback if needed” is a normal workflow.&lt;/p&gt;

&lt;p&gt;4) &lt;strong&gt;1:1 RAM + disk (no overselling)&lt;/strong&gt;&lt;br&gt;
If you provision 4GB RAM + 40GB disk, that’s &lt;strong&gt;reserved 1:1&lt;/strong&gt; on the host (no thin-provisioning surprises).&lt;/p&gt;

&lt;p&gt;What “using it” looks like&lt;br&gt;
1) Create a Cube (pick vCPU/RAM/disk) and SSH in as root.&lt;br&gt;
2) Deploy normally (systemd, Docker, packages -&lt;br&gt;
3) Expose only what you need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;attach &lt;code&gt;api.yourdomain.com&lt;/code&gt; → port &lt;code&gt;8080&lt;/code&gt; (HTTPS)&lt;/li&gt;
&lt;li&gt;open SSH (or Postgres) via a TCP mapping, allowlisted to your IP/VPN
4) Snapshot before risky changes. Restore if it breaks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you’re curious, the site is here:&lt;br&gt;
&lt;code&gt;https://krova.cloud/&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb7dtq76xng6tz9j835qj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb7dtq76xng6tz9j835qj.png" alt=" " width="800" height="383"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I’d love feedback from folks who run infra:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is “no public IP by default” a win, or does it break too many real-world workflows?&lt;/li&gt;
&lt;li&gt;What would you want to see from snapshots/backups before trusting a newer provider?&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>cloud</category>
      <category>devops</category>
      <category>vps</category>
      <category>security</category>
    </item>
    <item>
      <title>Why I built my cloud platform on micro-VMs instead of containers (a security story)</title>
      <dc:creator>Dhruv malaviya</dc:creator>
      <pubDate>Wed, 03 Jun 2026 07:55:21 +0000</pubDate>
      <link>https://dev.to/dhruv_malaviya_cdcc71e595/why-i-built-my-cloud-platform-on-micro-vms-instead-of-containers-a-security-story-6lm</link>
      <guid>https://dev.to/dhruv_malaviya_cdcc71e595/why-i-built-my-cloud-platform-on-micro-vms-instead-of-containers-a-security-story-6lm</guid>
      <description>&lt;p&gt;Containers are great until you remember they all share one kernel. For a lot of workloads that's fine. But the moment you're running untrusted code, multi-tenant jobs, or anything you wouldn't want leaking into its neighbours, a single kernel exploit is the whole game. That worry is exactly why I made an early architecture call for my platform, Krova &lt;a href="//krova.cloud"&gt;krova&lt;/a&gt;: no shared-kernel containers.&lt;/p&gt;

&lt;p&gt;Enter Firecracker&lt;br&gt;
Firecracker is the open-source micro-VM monitor AWS built to run Lambda and Fargate. Each instance is a real hardware-virtualized VM (KVM under the hood) with its own kernel, but it boots in around 125ms and carries almost none of the weight of a traditional VM. You get the isolation boundary of a VM with something close to the start-up feel of a container.&lt;/p&gt;

&lt;p&gt;That trade-off is perfect for security-minded, ephemeral work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hypervisor-level isolation. Tenants are separated at the virtualization boundary, not by namespaces over a shared kernel.&lt;/li&gt;
&lt;li&gt;Tiny attack surface. Firecracker deliberately ships a minimal device model, far less exposed than a full VM stack.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;How Krova uses it&lt;/p&gt;

&lt;p&gt;Every machine on Krova (a "Cube") is its own Firecracker micro-VM with its own kernel. They get private internal networking rather than a public IP each, ingress is explicit port mapping, and you can sleep or destroy a Cube the instant you're done. So "run something untrusted, then make it vanish" is the default path, not a thing you bolt on.&lt;/p&gt;

&lt;p&gt;And because they boot in about a second and keep their disk between sleeps, the security model doesn't cost you convenience, which is usually the part that makes people skip isolation in the first place.&lt;/p&gt;

</description>
      <category>security</category>
      <category>aws</category>
      <category>cloud</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
