Skip to content
← Blog

Backend checklist before you share an AI-built app

Nine checks to run before you send someone the link: sign-in, row permissions, secrets in client code, agent keys, backups, migrations, logs, scheduled jobs, and environments. For each, what floo handles and what is still yours to do.

floo team

TL;DR

Before you share an AI-built app, check nine things: sign-in, row permissions, secrets in client code, keys for agents, backups, migrations, logs, scheduled jobs, and environments. On floo, sign-in, credential handling, scoped agent keys, migrations on deploy, logs, and database history are part of the platform. Deciding who sees which rows, keeping secrets out of browser variables, and making jobs safe to rerun are still yours.

  • The two checks that matter most are sign-in and row permissions. That is where agent-built apps leak first: an agent adds tables and routes faster than anyone reviews who can reach them.
  • floo removes one class of permission bug. The browser gets no database key, so there are no row-level security policies to get wrong. Your server still has to filter rows by the signed-in person.
  • No platform can stop you shipping a secret in a public variable. Anything in NEXT_PUBLIC_, VITE_, or REACT_APP_ is readable by every visitor.
  • Each check below takes a few minutes, and most of them you can hand to your agent as a prompt.

The floo behavior below comes from floo's docs as of November 3, 2026. Links are at the end.

The checklist at a glance

CheckWhat floo doesWhat you still do
1. Sign-inInvite-only sign-in at the gatewayInvite the right people; pick the access mode per environment
2. Row permissionsNo database key in the browserFilter every query by the signed-in person where data is personal
3. SecretsInjects managed credentials at deploy; stores secrets write-onlyKeep secrets out of public build variables and browser code
4. Agent keysScoped, rate-limited, revocable keys per agentOne key per agent, stored in a secret store, revoked when done
5. BackupsPostgres change history; 30 days of storage versionsKnow how to ask for a restore; keep durable data out of Redis
6. MigrationsRuns migrate_command before traffic movesWrite changes the previous version can still run against
7. LogsRuntime and build logs; webhooks on failuresLog useful errors, never secrets; point the webhook somewhere
8. Scheduled jobsRuns [cron.<name>] in your imageMake jobs safe to run twice; watch for failures
9. EnvironmentsSeparate dev and prod, each with its own dataTest in dev or a preview before releasing to prod

1. Can only the right people open it?

What floo does. access_mode = "accounts" under [app] puts a hosted sign-in page in front of every request. Admission is invitation-only: no self-signup, and no one gets in by email domain. Removing a member revokes their sessions at once, and app users get no access to floo itself.

What you still do.

  • Open the app in a private window and confirm you see the sign-in page, not the app.
  • Run floo apps members --app <name> and remove anyone who should not be there.
  • If dev is public for fast iteration, make sure prod is not. [environments.<env>] overrides access_mode per environment, and each environment resolves on its own.

More on sign-in without auth code.

2. Can one person read another person's data?

This is where most agent-built apps leak. On backends where the browser queries the database, the guard is a rule on each table, and a table the agent added without a correct rule is open.

What floo does. It never gives the browser a way to the database. Only your server code holds DATABASE_URL, and the gateway tells it who is calling in the X-Floo-User-Email and X-Floo-User-Role headers. There are no row-level security policies to write or forget. Why that matters.

What you still do. floo decides who gets in; your code decides what they see. floo's docs say plainly that the application owns record-level permissions.

  • Every route that returns personal data filters by the signed-in person, for example where owner_email = $1.
  • Admin-only actions check X-Floo-User-Role on the server, not by hiding a button.
  • Queries use parameters, never string concatenation.
  • Ask your agent: "List every route that reads or writes the database, show me the filter each one applies, and write a test that signs in as two different users and proves neither can read the other's rows."

3. Are secrets out of the browser?

What floo does. Managed Postgres, Redis, and storage credentials are generated at deploy time and injected into the server's environment; they never enter git or floo.app.toml. floo env set stores a new value as a write-only secret unless its name has a public build prefix, and floo env list masks every value. In multi-service apps, --service scopes a secret to the backend services that need it.

What you still do. No platform can stop a secret you ship to the browser yourself. Next.js, Vite, and Create React App bake every variable starting with NEXT_PUBLIC_, VITE_, or REACT_APP_ into the JavaScript bundle, where anyone can read it.

  • Search the frontend for those prefixes and for anything that looks like a key or connection string.
  • Move every call that needs a secret into a server route.
  • Rotate any key that was ever in client code, a commit, or pasted into a chat.

4. How do your agents and scripts get in?

An app that only humans can open eventually needs a program to call it: your agent updating rows, a script pulling a report. The tempting fix is to make the app public again, or to hand the program an all-powerful key.

What floo does. Declare which routes accept an API key with [[routes]] and access = "api_key", then mint a key for a named consumer with a scope and a rate limit. The key works only on routes declared with that scope, is stripped before your code sees the request, and can be revoked without signing anyone out. Requests are listed by key ID for about seven days.

What you still do.

  • One consumer and key per agent or script, so you can revoke one without breaking the others.
  • Store the raw key in the program's secret store. It is shown once; never paste it into a prompt or commit it.
  • Scopes gate routes, not records. The route handler still checks what the caller may change.

How to give your agent its own key.

5. Can you get the data back?

What floo does. Managed Postgres keeps change history for each database, and floo runs a restore when you email team@getfloo.com with the app, the environment, and the approximate time before the bad change. Managed storage keeps every overwritten or deleted object version for 30 days, and you restore them yourself with floo storage restore.

What you still do.

  • Know that a database restore is a request, not a button. There is no restore command in the CLI or dashboard yet.
  • Treat Redis as a cache. floo makes no backup or durability guarantee for it, so queued work must be rebuildable from Postgres.
  • Data you keep in services you connected yourself is backed up by those providers, not floo.

6. Will a schema change break the live app?

What floo does. migrate_command runs once per deploy, before traffic moves to the new version. A failed migration stops the deploy and the previous version keeps serving. Each preview environment with Postgres gets its own database branch, so an agent can test a migration away from dev and prod.

What you still do.

  • Write migrations the previous code can still run against, because it serves traffic until cutover: add columns first, backfill, remove old ones in a later release.
  • Remember that a rollback moves traffic to an earlier image but does not undo a migration.
  • How to test migrations with agents.

7. Will you know when it breaks?

What floo does. floo logs query returns runtime logs, filterable by error, service, or text, kept for 7 days. floo deploys logs shows why a build or rollout failed. When a deploy fails or a runtime error crosses its threshold, floo can send a signed event to a webhook you configure, such as your agent or an on-call bot.

What you still do.

  • Log errors with enough context to act on, and never log secrets or full request bodies with personal data.
  • Configure the agent webhook, or at least know the one command to run when someone says it is broken.

8. Are scheduled jobs safe to run twice?

What floo does. A [cron.<name>] block runs a command on a UTC schedule inside your service's image, with the same database and environment variables. Dev and prod each run their own copy.

What you still do. floo's cron jobs do not retry. A failed run waits for the next schedule.

  • Make each job idempotent, so a manual rerun with floo cron run or an overlap does no harm.
  • Check failures with floo logs query --cron <job>.

9. Where do you try changes before the team sees them?

What floo does. Every app has dev and prod, each with its own URL, database, and credentials. A push deploys to dev; a GitHub release deploys a commit to prod only after it is live in dev. Preview environments give a branch its own isolated copy.

What you still do.

  • Decide whether you need prod at all. A small tool for a few people can live in dev alone; once more people rely on it, promote deliberately so a bad push never reaches them.
  • Set environment variables in both environments when their values differ.

How do you run the checklist?

Hand it to your agent. Ask it to go through each of the nine checks against your repo and your floo app, report what it found, and fix what it can. Then read the answers to checks 2 and 3 yourself; they are the two where a mistake exposes data.

If you have not added a backend yet, start with how to add a backend to an app your agent built, or a template that already passes most of this list. The backend overview lists every part floo supplies, and the backend roundup compares the alternatives.

Sources

Frequently asked questions

What should I check before sharing an app my agent built?

Who can open it, whether one person can read another's data, whether any secret is in the browser bundle, how agents and scripts authenticate, whether you can restore the data, how schema changes deploy, where errors show up, whether scheduled jobs are safe to rerun, and where you test changes before the team sees them.

How do I check whether a secret is in my client code?

Search the frontend for keys and for variables starting with NEXT_PUBLIC_, VITE_, or REACT_APP_. Those are baked into the JavaScript bundle at build time and anyone who opens the app can read them. Database URLs, API tokens, and service keys belong on the server only.

Does floo handle permissions for me?

floo handles who can open the app: its gateway admits only invited people and tells your code who they are. Which rows each person can see is your code's job. Because the browser never holds a database key, that check is a filter in a server route rather than a row-level security policy on every table.

Can I restore my database if an agent deletes data?

On floo, managed Postgres keeps change history and floo runs restores when you email team@getfloo.com with the app, environment, and approximate time. Storage objects can be restored yourself for 30 days. Redis has no backup, so keep anything you cannot lose in Postgres.

Build internal software.

Infrastructure for building secure, full-stack internal apps with AI. Team sign-in, a database, scheduled jobs, and hosting, all included.

Get an API key
Usage-based pricing. See plans →