Introduction
Integration from an app with its own backend
Your product already has real accounts: a platform's built-in auth and database (Base44, Lovable, or similar), or your own stack (Auth0, Cognito, a hand-rolled users table). This page shows how to replace that auth and data storage with secureFlows — mainly by giving an AI coding tool the right prompts — without losing existing users' data or accidentally opening up anything that used to require sign-in.
Who this is for
Use this guide when any of the following are true:
- The app was built on a platform that already provides its own auth and database (for example an AI app builder's built-in user/auth system, with per-user records already enforced server-side).
- The app has its own hand-rolled login and a database of user records (Auth0, Cognito, Firebase Auth, a plain Postgres users table — anything with real accounts, not just data on a device).
- You want secureFlows to become the source of truth for who the user is and what belongs to them, replacing what's there today.
No existing accounts at all — data only ever lived on the user's own device? Use Integration from a local-only app instead; its migration step is simpler because there is no second backend to retire. Brand-new app with nothing to preserve? Use the Integration Walkthrough.
Before the prompts: create a workspace and register an application in Workspace Management (you will need the workspace name and application ID). The walkthrough covers that setup if you have not done it yet.
What changes
| Today (own backend) | After secureFlows | |
|---|---|---|
| Who the user is | Whoever the old platform or your own auth system says is signed in | A signed-in person via secureFlows hosted login (you never handle passwords) |
| Where lasting data lives | The old platform's database, isolated by its own row-level security or backend code | In secureFlows as the app’s main user database, isolated by the session token |
| Backend checks | Server functions gate costly or privileged actions on the old platform's authenticated user | Same functions gate on a verified secureFlows session — the check moves, it does not disappear |
| Your product UI | Everything is your existing screens and features | Same screens and features — secureFlows adds sign-in and private storage underneath |
One idea to keep
Classify before you move anything
Not everything in the old database is lasting user data, and not every old auth check protects user data directly. Split what you find into: data that must survive across devices (moves to secureFlows), working state that only matters while the user is active (stays local, never persisted just because storage now exists), data that isn't owned by one user at all (doesn't belong in secureFlows), and backend authorization checks (must be re-pointed at secureFlows, never simply deleted because the operation itself doesn't touch secureFlows data). Sketch that split yourself first (next section), then compare it to what the AI proposes.
Sketch your data map first
No one knows this app better than you do — you don’t need any technical background to do this well. This step isn’t mandatory — Prompt A works even if you skip it — but it’s one of the most effective ways to get the AI’s first proposal right instead of correcting it afterward. Before you read what the AI proposes, write your own quick answer. Comparing two independent answers is what catches a mistake like quietly dropping an authorization check — reading one confident-looking plan usually does not.
Walk through your app one screen or feature at a time. For each thing it stores or shows, ask:
- Would your users be upset if it vanished when they signed in on a new device? Yes
→
keep forever. - Is it just something mid-edit for a user — typing, a filter, an unsaved screen?
Yes →
just while using. - Would every user see the exact same thing, not something personal to them? Yes →
not user-specific.
Then, separately, list every backend action that currently requires being signed in — anything that calls a paid API, sends something, or does something an anonymous visitor shouldn’t be able to trigger. This list matters most here: it's the thing most likely to get silently dropped during a migration.
Write it in this shape:
Data: - <screen or feature>: <what it stores> → <keep forever / just while using / not user-specific> Signed-in-only actions: - <feature>: <what it does> — currently requires sign-in
Example, for a recipe app built on an AI app builder:
Data: - Saved recipes: name, ingredients, instructions, nutrition → keep forever - Recipe chat: the back-and-forth while a user is refining a recipe they haven't saved yet → just while using - "Common allergens" reference list shown on every recipe → not user-specific Signed-in-only actions: - Recipe chat: calls an LLM to generate/refine a recipe — currently requires sign-in
Don’t worry about getting every line “right” — the point is to have your own answer
ready to compare, not to pre-solve the migration yourself. When you’re done, paste it into Prompt A
below, where it says <PASTE YOUR DATA SKETCH HERE>.
Integration prompts
Use the prompts in order. Prompt A teaches the tool what secureFlows is (via
SKILL.md), then asks it to inspect the existing backend and propose what should move, and only
then implements sign-in and storage. Prompt B comes later, once cloud save/load works for a new user.
Replace the placeholders with your workspace name and application ID from the console, and describe the old
auth/database honestly — the more specific you are, the more accurate the tool's proposal will be. Keep
the Why line — it tells the tool this is an intentional architecture change.
Warning
Migration can change how and where your app stores user data. Existing data may be lost if something goes wrong. Back up or export everything you need to keep before you change auth, storage, or run any migration prompts.
Prompt A — learn secureFlows, agree the data map, then implement
This app already has its own authentication and database: <name it, e.g. "Base44's built-in User
entity plus a Recipe table with owner-only row-level security" or "our own Postgres users table with
JWT auth">.
Use secureFlows for auth and data storage (read https://www.secure-flows.com/ai/secureflows-integration/SKILL.md).
Use: workspace = <YOUR_WORKSPACE>, appId = <YOUR_APP_ID>
Why: migrating from our own auth and database to secureFlows.
Here is my own data sketch, before you propose yours (see "Sketch your data map" above for how I made
this). Compare your proposal to it line by line — especially the signed-in-only actions — and call out
anything you disagree with instead of silently picking one version:
<PASTE YOUR DATA SKETCH HERE>
Do this in order. Stop after step 1 and wait for my confirmation before writing code:
1. Read the SKILL, including its migration guidance. Inspect this app's current data model and backend
code and propose:
(a) which existing records are lasting per-user data that should move to secureFlows,
(b) which app state only matters while a user is actively using the app and can stay local,
(c) any backend or serverless functions that currently check who's signed in before doing something
costly or privileged (e.g. calling a paid API) — list each one explicitly and say how it will
keep being protected once the old auth is gone,
(d) anything in the current database that isn't owned by one user (shared/global data) and should
not move to secureFlows at all.
Compare this against my sketch above, especially the signed-in-only actions list, and flag any
disagreement explicitly.
2. After I approve the plan: add secureFlows hosted login, replacing the app's existing login entirely
— not running alongside it.
3. Move only the approved lasting fields to secureFlows. Re-point the backend checks from (c) at a
secureFlows session check instead of removing them.
Keep describing the product features as they are today: <brief description of what the app does, and
what auth/data it currently has>.
If the tool starts coding before you approve the plan, stop it and point it back to step 1. If its plan doesn’t address every line in your sketch — especially a signed-in-only action you listed — or disagrees without explanation, ask about it directly before approving. Quietly dropping a backend check, or proposing to store a full activity transcript “to keep other reads small,” are both common mistakes worth catching before merge, not after.
Migrating existing accounts
People who already had accounts on the old system still have data sitting in the old database. Use a second prompt after Prompt A works (sign-in and cloud save/load feel correct for a new user).
Prompt B — import each user's old account once, on first sign-in
After a user signs in with secureFlows for the first time, they may already have an account and data in the app's old system. 1. Match the signed-in secureFlows identity to their old account (e.g. by email from sf.fetchSessionIdentity) and look up their existing data in the app's old database — read-only, do not write back to it. 2. If their secureFlows record is empty, import that old data into secureFlows once, then stop treating the old database as the source of truth for this user. 3. If they already have data in secureFlows (e.g. they signed in on another device first), do NOT overwrite it with the old record. Keep the secureFlows copy; optionally offer an explicit "Import my old data" choice only if they ask for it. 4. Never re-run the import on every sign-in — mark it done per user. 5. Do not delete the old database or its auth tables until every active user has migrated — keep it around, read-only, as the fallback until then. Use the same secureFlows workspace/appId and SKILL.md as before. The old system's data looks like: <short description, e.g. "a Recipe table with id/title/ingredients/ instructions/nutrition, owned via a created_by_id column">.
Adjusting the prompts for your app
- Workspace and appId — must match the console exactly (same spelling and casing).
- Name the old auth/database honestly — "Base44's built-in User + RLS," "Firebase Auth + Firestore," "our own JWT + Postgres" all lead to different-looking code. Vague descriptions produce vague proposals.
- Name every backend function that gates on the signed-in user — an LLM proxy, a paid-API call, an admin action. These are the ones most likely to be silently un-gated during a migration; calling them out up front (in your data sketch's signed-in-only actions list) is cheaper than catching it in review.
- Web vs mobile — say so in one sentence if it is not obvious from the project.
-
Staging — when testing against staging, append the same line as in the walkthrough:
replace every
www.secure-flows.comwith your staging host.
Where to go next
No existing backend, just on-device data: Integration from a local-only app. Setup and plain-language sign-in story: Integration Walkthrough. More questions: Q&A. The reference your AI tool reads: SKILL.md.
Advanced (optional)
For engineers who want the mechanical checklist behind those prompts. Most teams can skip this and stay with Prompts A and B.
Recommended sequence
- Provision workspace + application (redirect URI = app origin +
/callback). - Run Prompt A: tool reads SKILL, proposes which existing data/checks move vs stay, you confirm.
- Add hosted login; store the session token only in short-lived client storage (web:
sessionStorage, neverlocalStorage); remove the old auth entirely, don't run it alongside secureFlows. - Route approved lasting writes through secureFlows once the user is signed in.
- Re-point every backend check identified in Prompt A step 1(c) at a secureFlows session check.
- One-time import of each user's old account on first sign-in (Prompt B).
- Verify: user A saves → sign out → user B must not see A’s data, even by guessing A's old record id.
- Once every active user has migrated, retire the old database and its auth tables.
Migration details
secureFlows is a flat per-user key→value JSON store — no record IDs, timestamps, sorting, or
row-level security of its own. Keep the old domain model's shape as the stored value (e.g.
{ id, title, createdAt, ... }), generating those fields client-side if listing or sorting
needs them. They are metadata only, never a security boundary — isolation comes from the session
token alone, so a client-supplied id must never be trusted to prove ownership of a key. Splitting one
large value into several keys does not shrink a list read either: the Session API always returns a user's
entire payload, not a per-key slice, so key granularity only affects individual reads/writes.
Prefer importing only when the secureFlows record is empty. If secureFlows data already exists, keep it unless the user explicitly chooses to import the old leftovers. Mark migration done so it never runs again on every sign-in. Stay within plan payload size limits; large files belong in private object storage with an opaque id/key in the payload, served via signed URLs or an auth-checked download — not permanently public links.
Pitfalls
- Do not send a homemade
userIdin request bodies — identity comes from the session token. - Do not drop a backend function's authorization check just because the function itself is "stateless" or doesn't touch secureFlows data — verify the caller's secureFlows session token server-side instead (identity endpoint + Bearer token; treat 401/410/403 as unauthenticated). An unauthenticated proxy to a paid API is a cost and abuse risk, not a detail to wave away.
- HTTP
410means sign in again, not “data deleted.” - On mid-flow signed-out (e.g. Save), clear token and signed-in UI state so Sign out does not appear stuck.
- Avoid dual-writing forever to the old database + secureFlows for the same lasting fields.
- Don't delete the old database before every active user has migrated off it.
Wire-level HTTP: Integration Quickstart.