API & Integration

How Two SQL Statements Could Have Prevented Moltbook's API Key Disaster

Michael Roberts

Michael Roberts

February 06, 2026

11 min read 31 views

When Moltbook's 770,000-agent platform exposed every single API key through a Supabase misconfiguration, the security community realized how easily this could happen to anyone. The fix? Two SQL statements that should be in every developer's toolkit.

code, coding, computer, data, developing, development, ethernet, html, programmer, programming, screen, software, technology, work, code, code

The Nightmare That Woke Up the Backend Community

Picture this: you've built a platform handling 770,000 AI agents. You're using Supabase—PostgreSQL with a nice API wrapper—because it's 2026 and everyone's doing it. Then you wake up to the realization that every single API key on your platform has been exposed. Not some. Not most. Every. Single. One.

That's exactly what happened to Moltbook earlier this year. The security researcher who found it described it as "trivial" to exploit. And the worst part? The fix was literally two SQL statements. Two. That's what keeps me up at night—not sophisticated zero-days, but basic misconfigurations that could have been prevented with a few minutes of attention.

In this article, we're going to walk through exactly what went wrong, why it matters for anyone using Supabase (or really any database-as-a-service), and how you can make sure you're not making the same mistakes. I've seen this pattern before—it's why I now audit every Supabase project I touch for these exact issues.

What Actually Happened at Moltbook

Let's break down the technical details without the jargon. Moltbook was using Supabase to store API keys for their AI agents. These weren't just any keys—they were the keys that gave access to various AI services, potentially including paid APIs where exposure could mean financial loss.

The researcher discovered they could query the database directly through Supabase's auto-generated REST API. No authentication needed. No special permissions. Just a simple HTTP request that returned everything. And when I say everything, I mean they could get every API key for every agent on the platform.

Here's what made this particularly scary: Supabase creates these APIs automatically. It's a feature, not a bug. The platform gives you instant CRUD endpoints for your tables. But if you don't lock them down—and I mean really lock them down—you're essentially putting your database on the public internet with a "help yourself" sign.

The community reaction was a mix of horror and recognition. As one Reddit commenter put it: "I've definitely made similar mistakes when rushing to get something working. This is a wake-up call." Another noted: "The scary part is how many other platforms might have this exact issue right now."

The Two SQL Statements That Would Have Saved Everything

Okay, here's where it gets interesting. The fix wasn't some complex security overhaul. It was two PostgreSQL statements that should be in every Supabase user's playbook.

First, enabling Row Level Security (RLS) on the table:

ALTER TABLE api_keys ENABLE ROW LEVEL SECURITY;

Second, creating a policy that actually restricts access:

CREATE POLICY "Users can only view their own API keys" 
ON api_keys 
FOR SELECT 
USING (auth.uid() = user_id);

That's it. Seriously. The entire breach could have been prevented with those two statements.

But here's what most tutorials don't tell you: RLS is disabled by default on new tables in Supabase. You have to explicitly turn it on. And in the rush to build something—especially when you're dealing with 770,000 agents and presumably scaling challenges—it's easy to forget. Or worse, to think "I'll add security later" and then never get back to it.

I've worked with teams who assumed Supabase handled this automatically. They figured the platform would have sensible defaults. But security defaults are often a balancing act between safety and convenience, and in 2026, we're still seeing platforms err on the side of convenience.

Why Row Level Security Isn't Just a Checkbox

technology, computer, code, javascript, developer, programming, programmer, jquery, css, html, website, technology, technology, computer, code, code

Here's where things get nuanced. Enabling RLS is step one, but it's the policies that actually do the work. And writing good policies requires understanding your data model and access patterns.

Take Moltbook's case. They needed policies for:

  • Agents reading their own API keys
  • System processes that might need to validate keys
  • Administrative access for support or debugging
  • Potentially, key rotation or regeneration processes

Each of these requires a different policy. And policies can get complex quickly. What happens when an agent belongs to a team? What about service accounts? What if you need to join across tables?

One commenter in the original discussion pointed out something crucial: "The problem isn't just RLS. It's understanding the mental model of declarative security versus imperative security." In traditional applications, you check permissions in your application code. With RLS, you're declaring them at the database level. It's a paradigm shift that many developers aren't prepared for.

I've seen teams struggle with this transition. They'll enable RLS, write a basic policy, and think they're done. Then they hit edge cases—batch operations, background jobs, reporting queries—and either disable RLS or create overly permissive policies. Neither is a good solution.

The Supabase Security Model: Convenience vs. Safety

Let's talk about Supabase specifically, because this incident highlights a tension in their design philosophy. Supabase aims to make PostgreSQL accessible to frontend developers. That's a great goal—PostgreSQL is incredibly powerful but has a steep learning curve.

Want a portfolio website?

Showcase your work professionally on Fiverr

Find Freelancers on Fiverr

The auto-generated APIs are part of this accessibility. They let you build applications without writing backend code. But as the Moltbook incident shows, this convenience comes with risks.

Here's what I tell every team using Supabase: treat the auto-generated APIs as prototyping tools, not production endpoints. Once you're moving to production, you should be using:

  1. Custom Edge Functions for business logic
  2. Proper authentication middleware
  3. Rate limiting and monitoring
  4. Regular security audits of your RLS policies

One Reddit commenter made an excellent point: "Supabase should really have a 'production mode' that forces RLS on all tables and requires explicit policies." I agree. In fact, I'd go further—there should be warnings in the dashboard, maybe even requiring you to acknowledge the risks before creating a table without RLS.

But ultimately, security is the developer's responsibility. Tools can help, but they can't replace understanding. And in 2026, with AI-generated code and low-code platforms becoming more common, that understanding is becoming a rare commodity.

Beyond RLS: Defense in Depth for Your API Keys

RLS is crucial, but it shouldn't be your only line of defense. Here's what a robust API key management system should include:

Key encryption at rest: Even if someone gets database access, encrypted keys add another layer. PostgreSQL has great encryption support—use it.

Key rotation policies: How often are keys rotated? Is it automated? What's your process for compromised keys?

Access logging: Every key usage should be logged. Not just successful uses, but failed attempts too. This helps with detection and forensics.

Rate limiting per key: This prevents a single compromised key from being used to exhaustion.

Key scoping: Can keys be limited to specific operations or data? The principle of least privilege applies here too.

One approach I've seen work well is using a dedicated secrets management service alongside your database. Yes, it adds complexity, but for sensitive data like API keys, it's worth it. These services are built specifically for this purpose and often include features like automatic rotation, detailed audit logs, and fine-grained access controls.

Another Reddit commenter suggested: "For something as critical as API keys, I wouldn't store them in the same database as application data at all." That's a valid approach too—separation of concerns can improve security, though it does increase operational complexity.

Testing Your Security: The Checklist Every Developer Needs

coding, computer, hacker, hacking, html, programmer, programming, script, scripting, source code, coding, coding, coding, coding, computer, computer

After the Moltbook incident, I created a security checklist for Supabase projects. Here's what I test for every time:

1. RLS audit: Script that checks every table for RLS status and policies. No table should be without both.

2. Policy testing: Actually test policies with different user roles. Can a regular user access admin data? Can they access other users' data?

3. API endpoint testing: Try accessing auto-generated endpoints without authentication. Try with different levels of authentication. What happens?

4. Secret scanning: Check for hardcoded credentials, exposed environment variables, or keys in client-side code.

5. Dependency audit: Are you using the latest Supabase client? Are there known vulnerabilities in your dependencies?

Here's a pro tip: create a test user with minimal permissions and try to break your own application. See what data you can access that you shouldn't. Better you find it than a security researcher—or worse, a malicious actor.

I also recommend regular penetration testing. If you don't have the budget for professional services, consider bug bounty programs or even just asking other developers to review your setup. Fresh eyes often spot things you've become blind to.

Featured Apify Actor

Similarweb scraper

Need to analyze competitor websites at scale but dread manual SimilarWeb checks? This actor automates the whole process....

6.0M runs 1.6K users
Try This Actor

Common Mistakes (and How to Avoid Them)

Based on the Reddit discussion and my own experience, here are the most common Supabase security mistakes:

"I'll add security later": This is the most dangerous mindset. Security should be part of your initial design, not an afterthought.

Overly permissive policies: Using `true` in a policy because you're not sure how to write the correct condition. This essentially disables RLS for that operation.

Forgetting about joins: RLS policies apply to the table they're defined on. If you join to another table without RLS, you might leak data through the join.

Service account confusion: How do background jobs or system processes authenticate? They need service accounts with appropriate permissions, not admin access.

Ignoring the dashboard: The Supabase dashboard can bypass RLS. Who has access to it? Is MFA enabled? Are access logs reviewed?

One commenter shared a horror story: "We had RLS enabled but forgot that anyone with the anon key could call functions. Our function returned all user emails." This highlights another important point: RLS protects tables, but functions and stored procedures need their own security considerations.

The Human Factor: Security in a Fast-Moving World

Let's be honest for a minute. The Moltbook team wasn't trying to be insecure. They were probably under pressure to deliver features, scale their platform, and manage 770,000 agents. Security often gets deprioritized when you're fighting fires.

But here's the thing: security incidents like this can destroy trust overnight. Users don't care about your scaling challenges when their API keys are exposed.

So how do we balance velocity and security in 2026? A few approaches:

Security as code: Define your RLS policies in migration files. Review them in pull requests. Treat them like any other important code.

Automated checks: CI/CD pipelines should check for common security issues. No table without RLS should make it to production.

Education: Every developer working with Supabase should understand RLS. Not just know it exists, but understand how to use it effectively.

Culture: Security should be everyone's responsibility, not just the security team's (if you even have one).

One Reddit comment really stuck with me: "We need to stop treating security as a luxury for big companies with big budgets. These tools make it accessible—we just have to use them properly."

Moving Forward: Lessons for 2026 and Beyond

The Moltbook incident is a case study in modern application security. It shows how powerful tools can become risks when not fully understood. It highlights the tension between convenience and safety in platform design. And it reminds us that sometimes, the simplest things—like two SQL statements—can make all the difference.

If you take nothing else from this article, remember this: enable RLS on every table. Write policies before you write application code. Test them thoroughly. And never assume that defaults are secure.

The landscape in 2026 is only getting more complex. With AI agents, edge computing, and increasingly sophisticated attacks, security can't be an afterthought. It has to be foundational. And it starts with understanding the tools you're using—really understanding them, not just following a tutorial.

So go check your Supabase projects right now. Run those two SQL statements if you haven't already. Review your policies. Test your endpoints. Because the next security incident shouldn't be yours.

And if you're feeling overwhelmed? That's normal. Security is a journey, not a destination. Start with the basics—RLS and proper policies—and build from there. Your users (and your future self) will thank you.

Michael Roberts

Michael Roberts

Former IT consultant now writing in-depth guides on enterprise software and tools.