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_, orREACT_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
| Check | What floo does | What you still do |
|---|---|---|
| 1. Sign-in | Invite-only sign-in at the gateway | Invite the right people; pick the access mode per environment |
| 2. Row permissions | No database key in the browser | Filter every query by the signed-in person where data is personal |
| 3. Secrets | Injects managed credentials at deploy; stores secrets write-only | Keep secrets out of public build variables and browser code |
| 4. Agent keys | Scoped, rate-limited, revocable keys per agent | One key per agent, stored in a secret store, revoked when done |
| 5. Backups | Postgres change history; 30 days of storage versions | Know how to ask for a restore; keep durable data out of Redis |
| 6. Migrations | Runs migrate_command before traffic moves | Write changes the previous version can still run against |
| 7. Logs | Runtime and build logs; webhooks on failures | Log useful errors, never secrets; point the webhook somewhere |
| 8. Scheduled jobs | Runs [cron.<name>] in your image | Make jobs safe to run twice; watch for failures |
| 9. Environments | Separate dev and prod, each with its own data | Test 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>]overridesaccess_modeper 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-Roleon 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 runor 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
- floo: app sign-in, app API keys, environment variables, managed services, Postgres, backups and recovery, Redis, rollbacks, logs, agent webhooks, cron jobs, environments, preview environments, limits
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.