IS TEMPO SAFE? SECURITY ANALYSIS | VIBEEVAL

Is Tempo safe? The short answer

Tempo the platform is safe. Apps built with Tempo are safe when the developer adds the layers the generator left out. Tempo (tempo.new, by Tempo Labs) generates a mainstream stack — React (Vite) frontend, Supabase auth and database — and the hosting, HTTPS, and deploys are handled. The generated apps consistently ship with the same set of gaps: Supabase tables without correct RLS, auth enforced only in React route guards, dev-time storyboard routes reachable in production, and prototype API keys compiled into the bundle. Each gap is a short fix; collectively they are the difference between a demo and a production app.

The Tempo generation pattern

Tempo’s combination of AI agents and a visual editor optimizes for “this works and looks right on first try.” That has a predictable cost:

  • RLS lags the schema. The AI creates tables as the app grows; enabling and correctly scoping Row Level Security on each one is a separate step that frequently doesn’t happen.
  • Auth lives in the client. Generated route guards check the session in React. The Supabase API behind them — reachable with the bundled anon key — is only as protected as the RLS policies.
  • Dev surfaces persist. Storyboards and component playgrounds are central to the visual workflow; nothing forces their removal from the production build.
  • Keys hardcode. A key pasted into a component during prototyping is compiled into the bundle by Vite and served to every visitor.
  • Non-engineers ship. Visual edits from designers and PMs land as real code changes with no security review in the loop.
  • Regeneration regresses. An AI edit can rewrite a component or policy and silently reintroduce a gap you already fixed.

These are not bugs in Tempo; they are characteristics of AI generation plus visual editing under “make this work” pressure. Knowing the pattern is the entire fix — every audit item below targets one of those failure modes.

The 6 areas to harden in every Tempo app

1. Row Level Security on every table

The anon key in the bundle means anyone can query the Supabase REST API directly. RLS is the wall — and it has to be enabled and correctly scoped on every table.

Fix. Enable RLS everywhere, then write owner-scoped policies:

ALTER TABLE projects ENABLE ROW LEVEL SECURITY;

CREATE POLICY "read own" ON projects
  FOR SELECT USING (auth.uid() = user_id);

CREATE POLICY "insert own" ON projects
  FOR INSERT WITH CHECK (auth.uid() = user_id);

CREATE POLICY "update own" ON projects
  FOR UPDATE USING (auth.uid() = user_id);

Cover all four operations — AI-generated schemas often get SELECT right and leave UPDATE and DELETE open. Verify from outside with the Supabase RLS Checker.

2. Server-side enforcement behind every client guard

A React route guard is a UX nicety. The security question is: if I skip the React app entirely and hit Supabase with the anon key, what can I read and write?

Fix. For every “protected” feature, enforce the restriction at the data layer — an RLS policy, or an Edge Function that verifies the JWT:

// Supabase Edge Function: verify the caller before doing anything
import { createClient } from "jsr:@supabase/supabase-js@2";

Deno.serve(async (req) => {
  const supabase = createClient(
    Deno.env.get("SUPABASE_URL")!,
    Deno.env.get("SUPABASE_ANON_KEY")!,
    { global: { headers: { Authorization: req.headers.get("Authorization")! } } },
  );
  const { data: { user } } = await supabase.auth.getUser();
  if (!user) return new Response("Unauthorized", { status: 401 });
  // ...proceed as this verified user
});

3. Ownership checks (BOLA / IDOR)

Auth confirms the request has a valid session. It does not confirm the session owns the row being requested. Policies that scope to authenticated instead of auth.uid() = user_id are the Supabase flavor of BOLA — see BOLA in AI-generated CRUD.

Fix. Manual test, every launch: sign up as user A, create a record, sign in as user B, fetch the same record through the Supabase client. Anything other than an empty result is a policy bug.

4. Bundle hygiene

Everything in a Vite build is public. The Supabase URL and anon key belong in the bundle; nothing else secret does.

Fix. Grep the built output before every deploy:

npm run build
grep -rE 'sk_(live|test)_|sk-[A-Za-z0-9]{20,}|re_[A-Za-z0-9]{20,}|service_role' dist/

Move flagged calls into Edge Functions (secrets in Deno.env), rotate the exposed keys — including anything that ever appeared in git history — and re-run the Token Leak Checker against the deployed URL.

5. Production build surface

Storyboards, component playgrounds, and preview routes are development tooling. In production they render components outside any auth flow.

Fix. Exclude dev-only routes from production builds:

{import.meta.env.DEV && <Route path="/storyboard/*" element={<Storyboards />} />}

Then verify on the deployed URL that /storyboard, /tempobook, /playground, and similar paths 404. Confirm source maps are off (build.sourcemap: false in vite.config.ts) — see source maps and exposed .git.

6. Review discipline for visual edits

The visual editor’s entire purpose is letting non-engineers change the app. The mitigation isn’t technical, it’s process.

Fix. One rule, enforced: any change touching data fetching, auth state, schema, or a new integration gets an engineering look before deploy. After every AI edit or regeneration, re-run the two-account test and the bundle grep — regeneration can quietly reintroduce a gap you already fixed.

Storage and uploads — the recurring extra

If the app handles file uploads, check the Supabase Storage side: buckets created by generated code are sometimes public, storage policies are often missing, and upload handlers rarely cap size or MIME type. Scope objects to their owner with storage policies, and validate uploads in code. See file upload zip-slip / XXE for the server-side processing variant.

Pre-launch Tempo checklist

A practical sequence to run before pushing a Tempo app to a real audience:

  1. RLS enabled on every table, with owner-scoped policies for all four operations.
  2. Two-account cross-user test passes on every user-scoped table.
  3. No secrets in the bundle beyond the Supabase URL and anon key.
  4. Storyboard / playground / dev routes 404 on the production URL.
  5. Privilege columns (role, is_admin) not writable by their owner.
  6. OAuth redirect URLs restricted to the production domain.
  7. Storage buckets private unless deliberately public, with owner-scoped policies.
  8. Rate limiting on Edge Functions that call paid APIs.
  9. Run VibeEval against the deployed URL for the dynamic pass.

Tempo vs Lovable vs v0 — security positioning

  • Tempo. Visual editor + AI agents on React/Vite + Supabase. Failure modes concentrate in RLS, client-only auth, dev-route leakage, and unreviewed visual edits.
  • Lovable. Opinionated Supabase + frontend generator. Same RLS and anon-key failure modes, without the visual-editor review gap.
  • v0. UI-first generator. Failure modes follow whatever backend you wire up.

Pick the tool whose failure modes you have the bandwidth to audit. For Tempo, that means someone who is comfortable reading RLS policies and willing to re-test after every visual edit — the platform will not do it for you.

The verdict

Tempo produces working, good-looking React apps quickly, and its Supabase foundation is solid managed infrastructure. Security is not the generator’s focus. Treat every Tempo-built app as needing a security pass before production: RLS on every table, server-side enforcement behind every guard, a clean bundle, no dev routes, and a re-test after every AI edit. The list is mechanical and scannable. Run it before launch, every launch.

Scan your Tempo app

Let VibeEval scan your deployed Tempo application for the RLS, client-only-auth, BOLA, and credential-leakage patterns that AI generators most often leave in.

COMMON QUESTIONS

01
Is Tempo safe to use?
Tempo the platform is safe — it's a hosted environment with HTTPS, managed deploys, and a standard React (Vite) + Supabase stack. The risk sits in the apps it generates: the Supabase anon key ships in the client bundle, so every table without a correct Row Level Security policy is publicly queryable, generated route guards are client-side only, and dev-time storyboard routes can survive into production.
Q&A
02
What is the most common Tempo app vulnerability?
Missing or overly broad Supabase RLS. Because the anon key is in the bundle by design, RLS is the only server-side access control. Tables created during a fast build session frequently launch with RLS disabled, or with policies that allow any authenticated user to read every row of user-scoped data. Test with two accounts before every launch.
Q&A
03
Does Tempo's client-side auth protect my data?
No. React route guards hide pages; they do not protect the Supabase API behind them. Anyone can take the anon key from your bundle and query tables directly with curl. Every real restriction must exist as an RLS policy or inside an Edge Function that verifies the JWT — the route guard is UX only.
Q&A
04
Is the Supabase anon key in my Tempo bundle a leak?
The anon key itself is designed to be public — it's safe if and only if RLS is enabled and correct on every table. What is a leak: the service_role key, or any third-party secret (OpenAI, Stripe secret, Resend) pasted into a component during prototyping. Vite compiles those into the bundle for every visitor. Grep the built output and rotate anything you find.
Q&A
05
Are Tempo's storyboard and dev routes a security risk?
In production, yes. Tempo's visual workflow generates storyboards and component playgrounds during development. If they remain reachable on the deployed URL, they render your components — sometimes wired to live data — outside any auth flow, and they map your internal UI. Verify they're excluded from the production build, and re-check after every AI edit.
Q&A
06
Is it risky that non-engineers can edit code in Tempo?
It's the platform's core feature and its core risk. Designers and PMs shipping visual edits means code changes land that no one security-reviews. The mitigation is process: require engineering review on any change that touches data fetching, auth state, or schema, and re-run your cross-user access test after each editing session.
Q&A
07
What does Tempo do well from a security standpoint?
The stack it generates is modern and mainstream: React with Vite, Supabase for auth and database. Supabase auth is solid managed infrastructure — password hashing, session handling, and OAuth are not your problem. HTTPS and hosting are handled. The gap is consistently application-level: RLS policies, bundle hygiene, and surviving dev surfaces.
Q&A

SCAN YOUR APP

14-day trial. No card. Results in under 60 seconds.

START FREE SCAN