Secure coding best practices for Lovable apps, including frontend security, Edge Functions, row-level security (RLS), authentication, and workspace protection.
This page focuses on how to write secure code for Lovable apps and avoid common security mistakes during development.For details on Lovable’s security model, security scans, and findings, see Security overview, Project security view, and the Workspace security center.
Lovable apps are built with a clear separation of responsibilities:
Frontend runs in the user’s browser, where users can inspect or change it
Backend code runs server-side and handles validation, authentication, and business logic, as Edge Functions, TanStack Start server functions, or API routes depending on your project
Database uses PostgreSQL with row-level security (RLS) to enforce data access
This separation is the foundation of Lovable’s security model. The sections below follow this structure and highlight common security mistakes at each layer and how to avoid them.
Store sensitive values in Secrets instead, which also explains what belongs in .env versus a secret.Secrets stored in frontend code are visible to users and should be considered compromised.
Frontend validation improves user experience but provides no security guarantees.
// ❌ Wrong: client-side validation can be bypassedconst validateUser = (userData) => userData.email.includes("@");
Instead: Validate incoming data in server-side code before using it.Always treat client input as untrusted. Validate formats, enforce business rules, and handle inputs safely on the server before processing or storing data.Example prompts
Move validation logic from React components to server-side code for better security
Identify client-side validation that should be moved to the backend
Edge Functions run on the server, so you can use them for sensitive logic and credentials. TanStack Start projects can also use server functions and API routes. Every server function or API route must check who is calling and whether they may perform the action.Put authorization, input validation, and calls that require private credentials in server-side code. A function running on the server is still callable by a client, so server-side execution alone does not make the operation private.Use server-side code to handle:
Authentication and authorization
Verify who is making a request and whether they are allowed to perform the action.
Data validation and sanitization
Treat all input as untrusted and enforce business rules consistently.
Business logic and workflows
Handle multi-step processes like registrations, payments, approvals, and state transitions.
Integration with external services
Call third-party APIs securely and keep credentials out of the browser.
Sensitive data processing
Process personal or financial data safely, avoid exposing it unintentionally, and log important security events.
Apply these checks to every relevant endpoint, including functions called directly without going through your app’s UI.Example prompts
Create a server-side function for user registration with proper validation and security checks
Move payment processing logic from the frontend to a secure server-side function
Build a server-side file upload handler with type and size validation
You can inspect every policy in your project under More → Database → Manage → Policies (details).Row-level security (RLS) controls who can read or modify individual rows in your database. It applies to requests your app makes on behalf of a signed-in or anonymous user. Server-side code that uses the service role, the privileged database access your backend has, bypasses RLS, so that code must check permissions itself.Lovable sets up basic RLS policies automatically, but you should review and adjust them early in development. RLS is much easier to change before real data exists, and policies are most effective when they stay focused on access control rather than complex business logic.
All authentication decisions must happen server-side, not in the browser. Client-side authentication checks can be inspected, modified, or bypassed by users and should never be relied on for access control.Enforce authentication in server-side code, where sessions and tokens can be verified securely and consistently.
All validation and critical logic runs in server-side code
Row-level security (RLS) policies are configured and tested
Authentication is enforced server-side
Internal apps have workspace visibility
All critical findings in the Security view are addressed
External API calls happen server-side
Security is an ongoing process.Review these practices whenever you add features, change authentication, modify data access, or introduce new external integrations.Regularly reviewing server-side code, row-level security policies, and authentication flows helps prevent regressions over time.
Was this page helpful?
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Lovable Documentation","description":"Lovable Documentation — Build full-stack websites with AI using natural language. Explore Lovable features, integrations, tutorials, and best practices.","colors":{"primary":"#0095FF","light":"#1AA3FF","dark":"#0084E6"},"logo":{"light":"https://mintcdn.com/lovable-f9060f1e/lZT1ihBcprll2Agr/assets/logo/logoblack.svg?fit=max\u0026auto=format\u0026n=lZT1ihBcprll2Agr\u0026q=85\u0026s=8d9eafaf19f94e27f0d13ac160d54f54","dark":"https://mintcdn.com/lovable-f9060f1e/lZT1ihBcprll2Agr/assets/logo/logowhite.svg?fit=max\u0026auto=format\u0026n=lZT1ihBcprll2Agr\u0026q=85\u0026s=fed1a7a9be6502f49d06a55cec77288c","href":"https://lovable.dev/"},"favicon":"https://mintcdn.com/lovable-f9060f1e/b_1_IEcMDh-0NUDG/assets/logo/favicon.svg?fit=max\u0026auto=format\u0026n=b_1_IEcMDh-0NUDG\u0026q=85\u0026s=a439abba3defb47beabd3f6e7d318cb5","api":{"playground":{"display":"interactive"},"examples":{"defaults":"required","languages":["curl"],"prefill":true,"autogenerate":true},"url":"full"},"navbar":{"links":[{"icon":"message","href":"https://lovable.dev/support","label":"Support"},{"icon":"blog","href":"https://lovable.dev/blog","label":"Blog"}],"primary":{"type":"button","label":"Start building for free","href":"https://lovable.dev/signup?utm_source=lovable_docs\u0026utm_medium=navigation"}},"footer":{"socials":{"x":"https://x.com/Lovable","github":"https://github.com/lovablelabs","linkedin":"https://linkedin.com/company/lovable-dev","youtube":"https://youtube.com/@lovable","discord":"https://discord.gg/lovable-dev","reddit":"https://www.reddit.com/r/lovable"}},"seo":{"metatags":{"og:image":"/assets/logo/opengraph-image.png","canonical":"https://docs.lovable.dev"},"indexing":"all"},"contextual":{"options":["copy","assistant","download-pdf","download-spec"],"display":"header"},"styling":{"latex":true},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"lovable-f9060f1e","hasAudioNarration":false,"actualSubdomain":"lovable-f9060f1e","customDomains":["docs.lovable.dev"],"gitSource":{"type":"github","owner":"lovablelabs","repo":"docs","deployBranch":"main","contentDirectory":"","isPrivate":true,"mountPath":"","label":""},"chroma":{"liveDeploymentHistoryId":"6ae26a764f7bcbb8db4d1dd6","collectionId":"d305deef-c12c-45ea-971f-dc7e80bb91a1","schemaVersion":"v3","latestBuiltDeploymentHistoryId":"6ae26a764f7bcbb8db4d1dd6"},"feedback":{"thumbs":true,"issues":true,"agentFeedback":true},"entitlements":{"AI_CHAT":{"status":"ENABLED"},"REMOVE_BRANDING":{"status":"ENABLED"},"CONTEXTUAL_FEEDBACK":{"status":"ENABLED"},"CODE_SNIPPET_FEEDBACK":{"status":"ENABLED"},"WEB_MCP":{"status":"ENABLED"},"NARRATION":{"status":"ENABLED"}},"buildId":"6ae26a764f7bcbb8db4d1dd6","clientVersion":"0.0.4006","searchFilterCounts":[{"language":"default","tag":"Documentation","count":272},{"language":"default","tag":"Connect","count":125},{"language":"default","tag":"Connector catalog","count":113},{"language":"default","tag":"Build","count":68},{"language":"default","tag":"API Reference","count":33},{"language":"default","tag":"Workspace \u0026 account","count":29},{"language":"default","tag":"Lovable API","count":27},{"language":"default","tag":"Endpoints","count":25},{"language":"default","tag":"Data \u0026 databases","count":21},{"language":"default","tag":"Backend","count":19}]},"assistantConfig":{"enableStarterQuestions":true,"enableContextualStarterQuestions":true,"deflection":{"enabled":true,"type":"link","email":"support@lovable.dev","url":"https://lovable.dev/support"}},"basePath":"","hasChatPermissions":true,"hasWebMcpPermissions":true,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-v7-file-tree","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"pause-universal-search-reconcile","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"per-site-search-delta","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-private-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instinct-self-updating-docs","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-nav-generations","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"byok-sep-25","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-agent-model-picker","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-updated-9-15","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[{"filePath":"assets/css/styles.css","content":".supabase{color:#59cf8c}"}],"page":{"pagePath":"tips-tricks/security-best-practices","slug":"/tips-tricks/security-best-practices","pageMetadata":{"title":"Security best practices for Lovable apps","sidebarTitle":"Security best practices","description":"Secure coding best practices for Lovable apps, including frontend security, Edge Functions, row-level security (RLS), authentication, and workspace protection.","keywords":["Lovable security","security best practices","secure coding","Edge Functions security","row-level security","RLS best practices","frontend security"],"href":"/tips-tricks/security-best-practices"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Secure coding best practices for Lovable apps, including frontend security, Edge Functions, row-level security (RLS), authentication, and workspace protection.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,br:`br`,code:`code`,li:`li`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,ul:`ul`,..._provideComponents(),...props.components},{CodeBlock,Heading,Tip}=_components;if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Tip)_missingMdxReference(`Tip`,true);return _jsxs(_Fragment,{children:[_jsxs(_components.p,{children:[`This page focuses on `,_jsx(_components.strong,{children:`how to write secure code for Lovable apps`}),` and avoid common security mistakes during development.`]}),`\n`,_jsxs(_components.p,{children:[`For details on Lovable’s security model, security scans, and findings, see `,_jsx(_components.a,{href:`/features/security`,children:`Security overview`}),`, `,_jsx(_components.a,{href:`/features/security-view`,children:`Project security view`}),`, and the `,_jsx(_components.a,{href:`/features/security-center`,children:`Workspace security center`}),`.`]}),`\n`,_jsx(Heading,{level:`2`,id:`how-lovable-apps-are-structured`,children:`How Lovable apps are structured`}),`\n`,_jsx(_components.p,{children:`Lovable apps are built with a clear separation of responsibilities:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Frontend`}),` runs in the user’s browser, where users can inspect or change it`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Backend code`}),` runs server-side and handles validation, authentication, and business logic, as Edge Functions, TanStack Start server functions, or API routes depending on your project`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Database`}),` uses PostgreSQL with row-level security (RLS) to enforce data access`]}),`\n`]}),`\n`,_jsx(_components.p,{children:`This separation is the foundation of Lovable’s security model. The sections below follow this structure and highlight common security mistakes at each layer and how to avoid them.`}),`\n`,_jsx(Heading,{level:`2`,id:`frontend-security-basics`,children:`Frontend security basics`}),`\n`,_jsx(_components.p,{children:`All frontend code runs in the user’s browser and can be inspected, modified, or bypassed. Frontend code should never make security decisions.`}),`\n`,_jsx(Heading,{level:`3`,id:`do-not-store-secrets-in-frontend-code`,children:`Do not store secrets in frontend code`}),`\n`,_jsxs(_components.p,{children:[`Store sensitive values in `,_jsx(_components.a,{href:`/features/secrets`,children:`Secrets`}),` instead, which also explains what belongs in `,_jsx(_components.code,{children:`.env`}),` versus a secret.`]}),`\n`,_jsx(_components.p,{children:`Secrets stored in frontend code are visible to users and should be considered compromised.`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`3`,language:`typescript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`typescript`,children:_jsxs(_components.code,{language:`typescript`,numberOfLines:`3`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// ❌ Wrong: secrets exposed to anyone`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` API_KEY`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"sk-1234567890abcdef\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` STRIPE_SECRET`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"sk_live_...\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Instead`}),`: Ask Lovable to add secrets securely. Read secrets only in server-side code, and keep their values out of responses and logs.`]}),`\n`,_jsx(_components.p,{children:_jsx(_components.strong,{children:`Example prompts`})}),`\n`,_jsx(CodeBlock,{filename:``,wrap:`true`,numberOfLines:`2`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Add an API key for Stripe payments securely without exposing it in the frontend code`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsx(CodeBlock,{filename:``,wrap:`true`,numberOfLines:`2`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Review frontend code for exposed secrets, API keys, or sensitive information`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsx(Heading,{level:`3`,id:`do-not-rely-on-frontend-validation-for-security`,children:`Do not rely on frontend validation for security`}),`\n`,_jsx(_components.p,{children:`Frontend validation improves user experience but provides no security guarantees.`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`typescript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`typescript`,children:_jsxs(_components.code,{language:`typescript`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// ❌ Wrong: client-side validation can be bypassed`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` validateUser`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`userData`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`=>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` userData`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`email`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`includes`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"@\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Instead`}),`: Validate incoming data in server-side code before using it.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Always treat client input as untrusted.`}),` Validate formats, enforce business rules, and handle inputs safely on the server before processing or storing data.`]}),`\n`,_jsx(_components.p,{children:_jsx(_components.strong,{children:`Example prompts`})}),`\n`,_jsx(CodeBlock,{filename:``,wrap:`true`,numberOfLines:`2`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Move validation logic from React components to server-side code for better security`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsx(CodeBlock,{filename:``,wrap:`true`,numberOfLines:`2`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Identify client-side validation that should be moved to the backend`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsx(Heading,{level:`2`,id:`backend-security-with-server-side-code`,children:`Backend security with server-side code`}),`\n`,_jsx(_components.p,{children:`Edge Functions run on the server, so you can use them for sensitive logic and credentials. TanStack Start projects can also use server functions and API routes. Every server function or API route must check who is calling and whether they may perform the action.`}),`\n`,_jsx(_components.p,{children:`Put authorization, input validation, and calls that require private credentials in server-side code. A function running on the server is still callable by a client, so server-side execution alone does not make the operation private.`}),`\n`,_jsx(_components.p,{children:`Use server-side code to handle:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Authentication and authorization`}),_jsx(_components.br,{}),`\n`,`Verify who is making a request and whether they are allowed to perform the action.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Data validation and sanitization`}),_jsx(_components.br,{}),`\n`,`Treat all input as untrusted and enforce business rules consistently.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Business logic and workflows`}),_jsx(_components.br,{}),`\n`,`Handle multi-step processes like registrations, payments, approvals, and state transitions.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Integration with external services`}),_jsx(_components.br,{}),`\n`,`Call third-party APIs securely and keep credentials out of the browser.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Sensitive data processing`}),_jsx(_components.br,{}),`\n`,`Process personal or financial data safely, avoid exposing it unintentionally, and log important security events.`]}),`\n`]}),`\n`,_jsx(_components.p,{children:`Apply these checks to every relevant endpoint, including functions called directly without going through your app’s UI.`}),`\n`,_jsx(_components.p,{children:_jsx(_components.strong,{children:`Example prompts`})}),`\n`,_jsx(CodeBlock,{filename:``,wrap:`true`,numberOfLines:`2`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Create a server-side function for user registration with proper validation and security checks`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsx(CodeBlock,{filename:``,wrap:`true`,numberOfLines:`2`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Move payment processing logic from the frontend to a secure server-side function`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsx(CodeBlock,{filename:``,wrap:`true`,numberOfLines:`2`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Build a server-side file upload handler with type and size validation`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsx(Heading,{level:`2`,id:`database-security-with-rls`,children:`Database security with RLS`}),`\n`,_jsxs(_components.p,{children:[`You can inspect every policy in your project under `,_jsx(_components.strong,{children:`More → Database → Manage → Policies`}),` (`,_jsx(_components.a,{href:`/features/database-access#row-level-security-rls-policies`,children:`details`}),`).`]}),`\n`,_jsx(_components.p,{children:`Row-level security (RLS) controls who can read or modify individual rows in your database. It applies to requests your app makes on behalf of a signed-in or anonymous user. Server-side code that uses the service role, the privileged database access your backend has, bypasses RLS, so that code must check permissions itself.`}),`\n`,_jsx(_components.p,{children:`Lovable sets up basic RLS policies automatically, but you should review and adjust them early in development. RLS is much easier to change before real data exists, and policies are most effective when they stay focused on access control rather than complex business logic.`}),`\n`,_jsx(Heading,{level:`3`,id:`common-rls-patterns`,children:`Common RLS patterns`}),`\n`,_jsx(_components.p,{children:`Most Lovable apps fit into a small set of access patterns:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Personal data`}),`: users can access only their own data`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Team-based access`}),`: team members share access to team data`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Public content with ownership`}),`: anyone can read, only owners can modify`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Organization-based access`}),`: users access data within their organization`]}),`\n`]}),`\n`,_jsx(_components.p,{children:`Design your tables and policies around these patterns whenever possible.`}),`\n`,_jsx(Heading,{level:`3`,id:`rls-checks-before-publishing`,children:`RLS checks before publishing`}),`\n`,_jsx(_components.p,{children:`Before going live, verify:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:`RLS is enabled on all sensitive tables`}),`\n`,_jsx(_components.li,{children:`Users cannot access other users’ private data`}),`\n`,_jsx(_components.li,{children:`Shared and public data behaves as intended`}),`\n`,_jsx(_components.li,{children:`New tables are not missing policies`}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`Review RLS-related findings in `,_jsx(_components.a,{href:`/features/security-view`,children:`Project security view`}),`.`]}),`\n`,_jsx(_components.p,{children:_jsx(_components.strong,{children:`Example prompts`})}),`\n`,_jsx(CodeBlock,{filename:``,wrap:`true`,numberOfLines:`2`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Review RLS policies to ensure users can only access their own data and shared data is properly protected`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsx(CodeBlock,{filename:``,wrap:`true`,numberOfLines:`2`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Add RLS policies to the settings table so users can only access their own settings`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsx(CodeBlock,{filename:``,wrap:`true`,numberOfLines:`2`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Set up RLS for teams and projects so team members only see projects from their team`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsx(Heading,{level:`2`,id:`authentication-security-basics`,children:`Authentication security basics`}),`\n`,_jsx(_components.p,{children:`All authentication decisions must happen server-side, not in the browser. Client-side authentication checks can be inspected, modified, or bypassed by users and should never be relied on for access control.`}),`\n`,_jsx(_components.p,{children:`Enforce authentication in server-side code, where sessions and tokens can be verified securely and consistently.`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`3`,language:`typescript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`typescript`,children:_jsxs(_components.code,{language:`typescript`,numberOfLines:`3`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// ❌ Wrong: client-side authentication checks`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` isAuthenticated`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` localStorage`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`getItem`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"authToken\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`!==`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` null`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`isAuthenticated`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`showAdminPanel`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`();`})]}),`\n`]})})}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`5`,language:`typescript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`typescript`,children:_jsxs(_components.code,{language:`typescript`,numberOfLines:`5`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// ✅ Correct: server-side validation`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` { `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:`user`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` } `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` await`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` supabase`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`auth`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`getUser`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`();`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`!`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`user`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` new`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` Response`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Unauthorized\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, { `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`status:`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:` 401`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` });`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsx(_components.p,{children:_jsx(_components.strong,{children:`Authentication best practices`})}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:`Validate authentication and session tokens in server-side code`}),`\n`,_jsx(_components.li,{children:`Check roles and permissions server-side`}),`\n`,_jsx(_components.li,{children:`Use built-in session management for secure token handling`}),`\n`,_jsx(_components.li,{children:`Redirect users to login when sessions expire, but always validate on the server first`}),`\n`,_jsx(_components.li,{children:`Use frontend auth state only to control UI, never to enforce access`}),`\n`]}),`\n`,_jsx(Heading,{level:`2`,id:`workspace-security`,children:`Workspace security`}),`\n`,_jsx(_components.p,{children:`For applications that should not be publicly accessible:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`Set `,_jsx(_components.a,{href:`/features/project-visibility`,children:`project access`}),` to `,_jsx(_components.strong,{children:`workspace`})]}),`\n`,_jsxs(_components.li,{children:[`Verify the app is not `,_jsx(_components.a,{href:`/features/publish`,children:`published`}),` publicly`]}),`\n`,_jsx(_components.li,{children:`Require authentication even for internal tools`}),`\n`,_jsx(_components.li,{children:`Regularly audit who has access`}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`For workspace-wide monitoring, use the `,_jsx(_components.a,{href:`/features/security-center`,children:`Security center`}),`.`]}),`\n`,_jsx(Heading,{level:`2`,id:`security-checklist-before-publishing`,children:`Security checklist before publishing`}),`\n`,_jsx(_components.p,{children:`Before publishing your app, confirm:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:`No secrets exist in frontend code`}),`\n`,_jsx(_components.li,{children:`All validation and critical logic runs in server-side code`}),`\n`,_jsx(_components.li,{children:`Row-level security (RLS) policies are configured and tested`}),`\n`,_jsx(_components.li,{children:`Authentication is enforced server-side`}),`\n`,_jsx(_components.li,{children:`Internal apps have workspace visibility`}),`\n`,_jsxs(_components.li,{children:[`All critical findings in the `,_jsx(_components.a,{href:`/features/security-view`,children:`Security view`}),` are addressed`]}),`\n`,_jsx(_components.li,{children:`External API calls happen server-side`}),`\n`]}),`\n`,_jsxs(Tip,{children:[_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Security is an ongoing process`}),`.`]}),_jsx(_components.p,{children:`Review these practices whenever you add features, change authentication, modify data access, or introduce new external integrations.`}),_jsx(_components.p,{children:`Regularly reviewing server-side code, row-level security policies, and authentication flows helps prevent regressions over time.`})]})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Security best practices for Lovable apps","sidebarTitle":"Security best practices","description":"Secure coding best practices for Lovable apps, including frontend security, Edge Functions, row-level security (RLS), authentication, and workspace protection.","keywords":["Lovable security","security best practices","secure coding","Edge Functions security","row-level security","RLS best practices","frontend security"],"href":"/tips-tricks/security-best-practices"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"How Lovable apps are structured","slug":"how-lovable-apps-are-structured","depth":2,"children":[]},{"title":"Frontend security basics","slug":"frontend-security-basics","depth":2,"children":[{"title":"Do not store secrets in frontend code","slug":"do-not-store-secrets-in-frontend-code","depth":3,"children":[]},{"title":"Do not rely on frontend validation for security","slug":"do-not-rely-on-frontend-validation-for-security","depth":3,"children":[]}]},{"title":"Backend security with server-side code","slug":"backend-security-with-server-side-code","depth":2,"children":[]},{"title":"Database security with RLS","slug":"database-security-with-rls","depth":2,"children":[{"title":"Common RLS patterns","slug":"common-rls-patterns","depth":3,"children":[]},{"title":"RLS checks before publishing","slug":"rls-checks-before-publishing","depth":3,"children":[]}]},{"title":"Authentication security basics","slug":"authentication-security-basics","depth":2,"children":[]},{"title":"Workspace security","slug":"workspace-security","depth":2,"children":[]},{"title":"Security checklist before publishing","slug":"security-checklist-before-publishing","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":["/_mintlify/custom/lovable-f9060f1e/84f62c0d01f1469d/sign-in-with-lovable-demo.js"],"subdomain":"lovable-f9060f1e","siteName":"Lovable Documentation","title":"Security best practices for Lovable apps - Lovable Documentation","relatedPagesConfig":{"enabled":true,"limit":5,"mode":"automatic"},"contextualStarterQuestions":[{"_id":"6ad8b73b09456bb6af853397","deploymentId":"672cd6fd3133ca8082eceab1","questionText":"What frontend security risks exist?","status":"active","generatedBy":"contextual","path":"tips-tricks/security-best-practices","createdAt":"2026-10-21T12:59:39.262Z","updatedAt":"2026-10-21T12:59:39.262Z","__v":0},{"_id":"6ad8b73b09456bb6af853398","deploymentId":"672cd6fd3133ca8082eceab1","questionText":"How should I structure my app?","status":"active","generatedBy":"contextual","path":"tips-tricks/security-best-practices","createdAt":"2026-10-21T12:59:39.262Z","updatedAt":"2026-10-21T12:59:39.262Z","__v":0},{"_id":"6ad8b73b09456bb6af853396","deploymentId":"672cd6fd3133ca8082eceab1","questionText":"How do I store secrets safely?","status":"active","generatedBy":"contextual","path":"tips-tricks/security-best-practices","createdAt":"2026-10-21T12:59:39.262Z","updatedAt":"2026-10-21T12:59:39.262Z","__v":0}],"navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-10-21T12:59:33.944Z","originalFileLocation":"tips-tricks/security-best-practices.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Secure coding best practices for Lovable apps, including frontend security, Edge Functions, row-level security (RLS), authentication, and workspace protection.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Lovable Documentation\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/lovable-f9060f1e/AU_uVgnksniw8mje/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/lovable-f9060f1e/AU_uVgnksniw8mje/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/lovable-f9060f1e/AU_uVgnksniw8mje/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/lovable-f9060f1e/AU_uVgnksniw8mje/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/lovable-f9060f1e/AU_uVgnksniw8mje/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/lovable-f9060f1e/AU_uVgnksniw8mje/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/lovable-f9060f1e/AU_uVgnksniw8mje/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/lovable-f9060f1e/AU_uVgnksniw8mje/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/lovable-f9060f1e/AU_uVgnksniw8mje/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Security best practices for Lovable apps - Lovable Documentation\">\u003cmeta data-mint-head property=\"og:description\" content=\"Secure coding best practices for Lovable apps, including frontend security, Edge Functions, row-level security (RLS), authentication, and workspace protection.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Lovable Documentation\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.lovable.dev/tips-tricks/security-best-practices\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://lovable-f9060f1e.mintlify.app/assets/logo/opengraph-image.png\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Security best practices for Lovable apps - Lovable Documentation\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Secure coding best practices for Lovable apps, including frontend security, Edge Functions, row-level security (RLS), authentication, and workspace protection.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://lovable-f9060f1e.mintlify.app/assets/logo/opengraph-image.png\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/lovable-f9060f1e/AU_uVgnksniw8mje/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Lovable Documentation\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#0095FF\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.lovable.dev/tips-tricks/security-best-practices\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/tips-tricks/security-best-practices.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.lovable.dev/#organization\",\"name\":\"Lovable Documentation\",\"url\":\"https://docs.lovable.dev\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/lovable-f9060f1e/lZT1ihBcprll2Agr/assets/logo/logoblack.svg?fit=max\u0026auto=format\u0026n=lZT1ihBcprll2Agr\u0026q=85\u0026s=8d9eafaf19f94e27f0d13ac160d54f54\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.lovable.dev#website\",\"name\":\"Lovable Documentation\",\"url\":\"https://docs.lovable.dev\",\"publisher\":{\"@id\":\"https://docs.lovable.dev/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.lovable.dev/tips-tricks/security-best-practices#webpage\",\"url\":\"https://docs.lovable.dev/tips-tricks/security-best-practices\",\"name\":\"Security best practices for Lovable apps\",\"description\":\"Secure coding best practices for Lovable apps, including frontend security, Edge Functions, row-level security (RLS), authentication, and workspace protection.\",\"dateModified\":\"2026-10-21T12:59:33.944Z\",\"isPartOf\":{\"@id\":\"https://docs.lovable.dev#website\"},\"breadcrumb\":{\"@id\":\"https://docs.lovable.dev/tips-tricks/security-best-practices#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.lovable.dev/tips-tricks/security-best-practices#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Build\",\"item\":\"https://docs.lovable.dev/features/projects/editor\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Secure your app\",\"item\":\"https://docs.lovable.dev/features/security\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Security best practices for Lovable apps\",\"item\":\"https://docs.lovable.dev/tips-tricks/security-best-practices\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://docs.lovable.dev/tips-tricks/security-best-practices#article\",\"headline\":\"Security best practices for Lovable apps\",\"name\":\"Security best practices for Lovable apps\",\"description\":\"Secure coding best practices for Lovable apps, including frontend security, Edge Functions, row-level security (RLS), authentication, and workspace protection.\",\"url\":\"https://docs.lovable.dev/tips-tricks/security-best-practices\",\"mainEntityOfPage\":{\"@id\":\"https://docs.lovable.dev/tips-tricks/security-best-practices#webpage\"},\"image\":\"https://docs.lovable.dev/assets/logo/opengraph-image.png\",\"dateModified\":\"2026-10-21T12:59:33.944Z\",\"keywords\":\"Lovable security, security best practices, secure coding, Edge Functions security, row-level security, RLS best practices, frontend security\",\"publisher\":{\"@id\":\"https://docs.lovable.dev/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.lovable.dev#website\"}}]}\u003c/script>","siteName":"Lovable Documentation","nav":{"global":null,"tabs":[{"tab":"Documentation","groups":[{"group":"Getting started","icon":"rocket","pages":[{"title":"Welcome to Lovable","href":"/introduction/welcome"},{"title":"Create an account","href":"/introduction/create-an-account"},{"title":"Quick start","href":"/introduction/getting-started"},{"title":"Dashboard overview","href":"/introduction/dashboard-overview"},{"title":"Lovable for Enterprise","sidebarTitle":"Enterprise","href":"/introduction/lovable-for-enterprise"},{"group":"Lovable platforms","pages":[{"title":"Lovable desktop app","sidebarTitle":"Lovable desktop app","href":"/integrations/desktop-app"},{"title":"Lovable mobile app","sidebarTitle":"Lovable mobile app","href":"/integrations/lovable-mobile-app"}]},{"group":"Use Lovable from other tools","pages":[{"title":"Lovable API","sidebarTitle":"Lovable API","href":"/integrations/lovable-api"},{"title":"Lovable MCP server","sidebarTitle":"Lovable MCP server","href":"/integrations/lovable-mcp-server"},{"title":"Lovable ChatGPT app","sidebarTitle":"Lovable ChatGPT app","href":"/tips-tricks/chatgpt-app"},{"title":"Chat with Lovable in Slack","sidebarTitle":"Lovable in Slack","href":"/integrations/lovable-for-slack"},{"title":"Chat with Lovable in Telegram","sidebarTitle":"Lovable in Telegram","href":"/tips-tricks/lovable-telegram-bot"},{"title":"Build with URL","href":"/integrations/build-with-url"},{"title":"Sign in with Lovable","sidebarTitle":"Sign in with Lovable","href":"/integrations/sign-in-with-lovable"}]}]},{"group":"Build","icon":"hammer","pages":[{"group":"Projects","root":{"title":"Projects in Lovable","sidebarTitle":"Overview","href":"/features/projects/overview"},"pages":[{"title":"Find your way around the Lovable editor","sidebarTitle":"Editor","href":"/features/projects/editor"},{"title":"Work with Lovable in the project chat","sidebarTitle":"Project chat","href":"/features/projects/chat"},{"title":"Preview and test your app in Lovable","sidebarTitle":"Preview","href":"/features/projects/preview"},{"title":"Explore changes with drafts","sidebarTitle":"Drafts","href":"/features/drafts"},{"title":"View and edit your project's code","sidebarTitle":"Code editor","href":"/features/code-mode"},{"title":"Revert and restore your project with version history","sidebarTitle":"Version history","href":"/features/projects/history"},{"title":"Project settings","sidebarTitle":"Settings","href":"/features/projects/settings"},{"title":"Delete a project","href":"/features/projects/delete-project"},{"title":"Remix a project","sidebarTitle":"Remix","href":"/features/projects/remix"},{"title":"Import a project from Replit, Bolt, v0, or another tool","sidebarTitle":"Import a project","href":"/features/projects/import-project"},{"title":"Import a website into Lovable from its URL","sidebarTitle":"Import a website","href":"/features/projects/import-website"},{"title":"Upgrade a project to TanStack Start","sidebarTitle":"Upgrade to TanStack Start","href":"/features/upgrade-to-tanstack-start"},{"title":"Find and search projects","sidebarTitle":"Find a project","href":"/introduction/project-search-and-find"},{"title":"Organize projects in folders","sidebarTitle":"Folders","href":"/introduction/project-folders"}]},{"title":"Chat with Lovable across your workspace","sidebarTitle":"Chats","href":"/features/chats"},{"group":"The agent","pages":[{"title":"Discuss your app in Chat mode","sidebarTitle":"Chat mode","href":"/features/chat-mode"},{"title":"Plan a change in Plan mode","sidebarTitle":"Plan mode","href":"/features/plan-mode"},{"title":"Implement changes in Build mode","sidebarTitle":"Build mode","href":"/features/agent-mode"},{"title":"Set a goal for Lovable","sidebarTitle":"Goals","href":"/features/goal-runs"},{"title":"Subagents","sidebarTitle":"Subagents","href":"/features/subagents"}]},{"group":"Context \u0026 instructions","pages":[{"title":"Instructions","sidebarTitle":"Instructions","href":"/features/knowledge"},{"title":"Define reusable instructions with skills","sidebarTitle":"Skills","href":"/features/skills"},{"title":"Cross-project referencing","href":"/features/cross-project-referencing"}]},{"title":"Generate files and analyze data","sidebarTitle":"File generation","href":"/features/generate-files"},{"group":"Design","pages":[{"title":"Edit from the preview","sidebarTitle":"Preview toolbar","href":"/features/preview-toolbar"},{"title":"Design guidance","href":"/features/design-guidance"},{"title":"Design templates","href":"/features/business/design-templates"},{"title":"Design systems","href":"/features/design-systems"},{"title":"Use custom fonts","sidebarTitle":"Custom fonts","href":"/tips-tricks/custom-fonts"},{"title":"Use 21st.dev components in Lovable","sidebarTitle":"21st.dev","href":"/tips-tricks/21stdev"},{"title":"Bring Figma designs into Lovable","sidebarTitle":"Figma","href":"/integrations/figma"}]},{"group":"Backend","root":{"title":"Built-in backend","sidebarTitle":"Overview","href":"/features/cloud"},"pages":[{"group":"Database","root":{"title":"Database","href":"/features/database"},"pages":[{"title":"Control who can access your app's data","sidebarTitle":"Access and security","href":"/features/database-access"},{"title":"Fix a slow database and choose the right capacity","sidebarTitle":"Performance and capacity","href":"/features/database-performance"},{"title":"Back up, restore, and export your project's database","sidebarTitle":"Backups and export","href":"/features/database-backups"},{"title":"Pause, resume, or remove your project's database","sidebarTitle":"Pause, resume, and remove","href":"/features/database-pause-remove"}]},{"group":"Users \u0026 authentication","root":{"title":"Users and authentication","sidebarTitle":"Users \u0026 authentication","href":"/features/authentication"},"pages":[{"title":"Email authentication for your app","sidebarTitle":"Email auth","href":"/features/email-auth"},{"title":"Phone authentication for your app","sidebarTitle":"Phone auth","href":"/features/phone-auth"},{"title":"Add Google authentication to your app","sidebarTitle":"Google auth","href":"/features/google-auth"},{"title":"Add Apple authentication to your app","sidebarTitle":"Apple auth","href":"/features/apple-auth"},{"title":"Add Microsoft authentication to your app","sidebarTitle":"Microsoft auth","href":"/features/microsoft-auth"},{"title":"Add Sign in with Lovable to your app","sidebarTitle":"Lovable auth","href":"/features/lovable-auth"},{"title":"Add SAML single sign-on to your app","sidebarTitle":"SAML SSO (apps)","href":"/features/saml-sso"},{"title":"Add OpenID Connect (OIDC) sign-in to your app","sidebarTitle":"OIDC sign-in (apps)","href":"/features/oidc-auth"},{"title":"Reuse Lovable workspace identity in your app","sidebarTitle":"Workspace identity (apps)","href":"/features/lovable-workspace-identity-reuse"}]},{"title":"Storage","href":"/features/storage"},{"title":"Secrets","href":"/features/secrets"},{"title":"Jobs","href":"/features/jobs"},{"title":"Edge functions","href":"/features/edge-functions"},{"title":"Logs","href":"/features/logs"},{"title":"Project usage and costs","sidebarTitle":"Usage","href":"/features/project-usage"}]},{"group":"AI for your app","root":{"title":"AI features for your app","sidebarTitle":"AI for your app","href":"/features/ai"},"pages":[{"title":"Add chatbots and text generation to your app","sidebarTitle":"Chat and text","href":"/features/ai-chat"},{"title":"Let users generate and edit images in your app","sidebarTitle":"Images","href":"/features/ai-images"},{"title":"Let users generate and edit videos in your app","sidebarTitle":"Video","href":"/features/ai-video"},{"title":"Let users create music in your app","sidebarTitle":"Music","href":"/features/ai-music"},{"title":"Help users find relevant content in your app","sidebarTitle":"Search by meaning","href":"/features/ai-search"},{"title":"Automate classification, routing, and scoring in your app","sidebarTitle":"Classify and score","href":"/features/ai-decisions"},{"title":"Let users listen to your app's content","sidebarTitle":"Text to speech","href":"/features/ai-text-to-speech"},{"title":"Add transcription and voice input to your app","sidebarTitle":"Speech to text","href":"/features/ai-speech-to-text"},{"title":"Build voice assistants your users can talk to","sidebarTitle":"Live voice","href":"/features/ai-live-voice"},{"title":"Replace deprecated AI models in your app","sidebarTitle":"Deprecated models","href":"/features/ai-deprecated-models"}]},{"group":"Test your app","pages":[{"title":"Test and verify your app","sidebarTitle":"Testing tools","href":"/features/testing"},{"title":"Test your app in a browser","sidebarTitle":"Browser testing","href":"/features/browser-testing"}]},{"group":"Secure your app","root":{"title":"Security overview","href":"/features/security"},"pages":[{"title":"Project security view","sidebarTitle":"Project security view","href":"/features/security-view"},{"title":"Trust center","description":"Share security checks verified by Lovable for your published app, with a page at /.well-known/trust.html and machine-readable results at /.well-known/trust.json.","href":"/features/trust-center"},{"title":"Security best practices for Lovable apps","sidebarTitle":"Security best practices","href":"/tips-tricks/security-best-practices"}]},{"title":"Using npm packages","sidebarTitle":"npm packages","description":"Add drag-and-drop, charts, animations, and other advanced features by asking Lovable to integrate npm packages into your project.","href":"/tips-tricks/npm-packages"},{"title":"Build secrets","tag":"ENT","href":"/features/build-secrets"},{"title":"Managed registry","tag":"ENT","href":"/features/managed-registry"}]},{"group":"Connect","icon":"plug","pages":[{"group":"Connectors","root":{"title":"Lovable connectors: Connect tools, services, and APIs","sidebarTitle":"Overview","href":"/integrations/introduction"},"pages":[{"title":"App + chat connectors: Add capabilities to your published app and your chat","sidebarTitle":"App + chat connectors","href":"/integrations/app-connectors"},{"title":"App user connectors: let your users connect their own accounts","sidebarTitle":"App user connectors","href":"/integrations/app-user-connectors"},{"title":"Create a custom connector","sidebarTitle":"Custom connectors","href":"/integrations/create-connector"},{"title":"Chat connectors: Connect your tools to Lovable using MCP servers","sidebarTitle":"Chat connectors","href":"/integrations/chat-connectors"},{"title":"Connect a custom MCP server as a chat connector","sidebarTitle":"Custom MCP servers","href":"/integrations/custom-mcp"},{"title":"MCP registries","href":"/integrations/mcp-registries"},{"title":"Manage connectors in your workspace","sidebarTitle":"Admin controls","href":"/integrations/admin-controls"},{"title":"Integration security","href":"/integrations/security"}]},{"group":"Connector catalog","pages":[{"group":"AI \u0026 search","pages":[{"title":"Connect your app to Algolia","sidebarTitle":"Algolia","href":"/integrations/algolia"},{"title":"Connect your app to Apify","sidebarTitle":"Apify","href":"/integrations/apify"},{"title":"Connect ElevenLabs to enable voice AI in your app","sidebarTitle":"ElevenLabs","href":"/integrations/eleven-labs"},{"title":"Connect Firecrawl to scrape web data for your app","sidebarTitle":"Firecrawl","href":"/integrations/firecrawl"},{"title":"Connect your app to Fireworks AI","sidebarTitle":"Fireworks AI","href":"/integrations/fireworks"},{"title":"Connect your app to Gemini Enterprise","sidebarTitle":"Gemini Enterprise","href":"/integrations/gemini-enterprise"},{"title":"Connect your app to LlamaParse Platform","sidebarTitle":"LlamaParse Platform","href":"/integrations/llamaparse"},{"title":"Connect your app to Parallel","sidebarTitle":"Parallel","href":"/integrations/parallel"},{"title":"Connect your app to Perplexity","sidebarTitle":"Perplexity","href":"/integrations/perplexity"},{"title":"Connect your app to Replicate","sidebarTitle":"Replicate","href":"/integrations/replicate"}]},{"group":"Data \u0026 databases","pages":[{"title":"Connect to Supabase","sidebarTitle":"Supabase","href":"/integrations/supabase"},{"title":"Connect your app to Amazon Redshift","sidebarTitle":"Amazon Redshift","href":"/integrations/amazon-redshift"},{"title":"Connect your app to AWS Athena","sidebarTitle":"AWS Athena","href":"/integrations/aws-athena"},{"title":"Connect your app to AWS S3","sidebarTitle":"AWS S3","href":"/integrations/aws-s3"},{"title":"Connect your app to BigQuery","sidebarTitle":"BigQuery","href":"/integrations/bigquery"},{"title":"Connect your app to ClickHouse","sidebarTitle":"ClickHouse","href":"/integrations/clickhouse"},{"title":"Connect your app to Cube","sidebarTitle":"Cube","href":"/integrations/cube"},{"title":"Connect your app to Databricks","sidebarTitle":"Databricks","href":"/integrations/databricks"},{"title":"Connect your app to the dbt Semantic Layer","sidebarTitle":"dbt Semantic Layer","href":"/integrations/dbt-semantic-layer"},{"title":"Connect your app to GoodData","sidebarTitle":"GoodData","href":"/integrations/gooddata"},{"title":"Connect your app to IBM Db2","sidebarTitle":"IBM Db2","href":"/integrations/ibm-db2"},{"title":"Connect your app to Looker","sidebarTitle":"Looker","href":"/integrations/looker"},{"title":"Connect your app to Metabase","sidebarTitle":"Metabase","href":"/integrations/metabase"},{"title":"Connect your app to Microsoft Fabric","sidebarTitle":"Microsoft Fabric","href":"/integrations/microsoft-fabric"},{"title":"Connect your app to MotherDuck","sidebarTitle":"MotherDuck","href":"/integrations/motherduck"},{"title":"Connect your app to Neon","sidebarTitle":"Neon","href":"/integrations/neon"},{"title":"Connect your app to Omni","sidebarTitle":"Omni","href":"/integrations/omni"},{"title":"Connect your app to Oracle Autonomous AI Database","sidebarTitle":"Oracle Autonomous AI Database","href":"/integrations/oracle-autonomous"},{"title":"Connect your app to Power BI","sidebarTitle":"Power BI","href":"/integrations/power-bi"},{"title":"Connect your app to Qlik Cloud","sidebarTitle":"Qlik Cloud","href":"/integrations/qlik-cloud"},{"title":"Connect your app to Snowflake","sidebarTitle":"Snowflake","href":"/integrations/snowflake"}]},{"group":"Communication \u0026 messaging","pages":[{"title":"Connect your app to Brevo","sidebarTitle":"Brevo","href":"/integrations/brevo"},{"title":"Connect your app to Discord","sidebarTitle":"Discord","href":"/integrations/discord"},{"title":"Connect your app to Firebase Cloud Messaging","sidebarTitle":"Firebase Cloud Messaging","href":"/integrations/firebase-cloud-messaging"},{"title":"Connect your app to GatewayAPI","sidebarTitle":"GatewayAPI","href":"/integrations/gatewayapi"},{"title":"Connect your app to Mailgun","sidebarTitle":"Mailgun","href":"/integrations/mailgun"},{"title":"Connect your app to Resend","sidebarTitle":"Resend","href":"/integrations/resend"},{"title":"Connect your app to Slack","sidebarTitle":"Slack","href":"/integrations/slack"},{"title":"Connect your app to Telegram","sidebarTitle":"Telegram","href":"/integrations/telegram"},{"title":"Connect your app to Twilio","sidebarTitle":"Twilio","href":"/integrations/twilio"},{"title":"Connect your app to WhatsApp Business","sidebarTitle":"WhatsApp Business","href":"/integrations/whatsapp"}]},{"group":"CRM \u0026 sales","pages":[{"title":"Connect your app to Apollo.io","sidebarTitle":"Apollo.io","href":"/integrations/apollo"},{"title":"Connect your app to Attention","sidebarTitle":"Attention","href":"/integrations/attention"},{"title":"Connect your app to Clay","sidebarTitle":"Clay","href":"/integrations/clay"},{"title":"Connect your app to Gong","sidebarTitle":"Gong","href":"/integrations/gong"},{"title":"Connect your app to HubSpot","sidebarTitle":"HubSpot","href":"/integrations/hubspot"},{"title":"Connect your app to KLIPY","sidebarTitle":"KLIPY","href":"/integrations/klipy"},{"title":"Connect your app to Pipedrive","sidebarTitle":"Pipedrive","href":"/integrations/pipedrive"},{"title":"Connect your app to Salesforce","sidebarTitle":"Salesforce","href":"/integrations/salesforce"},{"title":"Connect your app to Zendesk","sidebarTitle":"Zendesk","href":"/integrations/zendesk"},{"title":"Connect your app to Zoho CRM","sidebarTitle":"Zoho CRM","href":"/integrations/zoho-crm"}]},{"group":"Developer tools","pages":[{"title":"Connect your app to AWS API","sidebarTitle":"AWS API","href":"/integrations/aws"},{"title":"Connect your app to Azure Cloud API","sidebarTitle":"Azure Cloud API","href":"/integrations/azure"},{"title":"Connect your app to Azure Graph \u0026 Entra API","sidebarTitle":"Azure Graph \u0026 Entra API","href":"/integrations/azure-graph"},{"title":"Connect your app to Cloudflare API","sidebarTitle":"Cloudflare API","href":"/integrations/cloudflare-api"},{"title":"Connect your app to GitHub API","sidebarTitle":"GitHub API","href":"/integrations/github-api"},{"title":"Connect your app to GitLab API","sidebarTitle":"GitLab API","href":"/integrations/gitlab-api"},{"title":"Connect your app to Google Cloud API","sidebarTitle":"Google Cloud API","href":"/integrations/gcp"},{"title":"Connect your app to Inngest","sidebarTitle":"Inngest","href":"/integrations/inngest"},{"title":"Connect your app to Linear","sidebarTitle":"Linear","href":"/integrations/linear"},{"title":"Connect your app to Logo.dev","sidebarTitle":"Logo.dev","href":"/integrations/logo-dev"},{"title":"Connect your app to the Lovable API","sidebarTitle":"Lovable API connector","href":"/integrations/lovable-api-connector"},{"title":"Connect your app to n8n","sidebarTitle":"n8n","href":"/integrations/n8n"}]},{"group":"E-commerce","pages":[{"title":"Connect your app to Lightspeed","sidebarTitle":"Lightspeed","href":"/integrations/lightspeed"},{"title":"Connect your app to PrestaShop","sidebarTitle":"PrestaShop","href":"/integrations/prestashop"},{"title":"Build a Shopify store with AI","sidebarTitle":"Shopify","href":"/integrations/shopify"},{"title":"Connect your app to WooCommerce","sidebarTitle":"WooCommerce","href":"/integrations/woocommerce"}]},{"group":"Finance \u0026 accounting","pages":[{"title":"Connect your app to Lexware","sidebarTitle":"Lexware","href":"/integrations/lexware"},{"title":"Connect your app to Sevdesk","sidebarTitle":"Sevdesk","href":"/integrations/sevdesk"},{"title":"Connect your app to Wave","sidebarTitle":"Wave","href":"/integrations/wave"},{"title":"Connect your app to Xero","sidebarTitle":"Xero","href":"/integrations/xero"},{"title":"Connect your app to Zoho Books","sidebarTitle":"Zoho Books","href":"/integrations/zoho-books"}]},{"group":"Maps \u0026 location","pages":[{"title":"Connect your app to Google Maps Platform","sidebarTitle":"Google Maps Platform","href":"/integrations/google-maps"},{"title":"Connect your app to Mapbox","sidebarTitle":"Mapbox","href":"/integrations/mapbox"}]},{"group":"Marketing \u0026 social","pages":[{"title":"Connect your app to beehiiv","sidebarTitle":"beehiiv","href":"/integrations/beehiiv"},{"title":"Connect your app to Bing Webmaster Tools","sidebarTitle":"Bing Webmaster Tools","href":"/integrations/bing-webmaster-tools"},{"title":"Connect your app to Google Analytics","sidebarTitle":"Google Analytics","href":"/integrations/google-analytics"},{"title":"Connect Google Business Profile to Lovable","sidebarTitle":"Google Business Profile","href":"/integrations/google-business-profile"},{"title":"Connect your app to Google Search Console (GSC)","sidebarTitle":"Google Search Console","href":"/integrations/google-search-console"},{"title":"Connect your app to Klaviyo","sidebarTitle":"Klaviyo","href":"/integrations/klaviyo"},{"title":"Connect your app to LinkedIn","sidebarTitle":"LinkedIn","href":"/integrations/linkedin"},{"title":"Connect your app to Loops","sidebarTitle":"Loops","href":"/integrations/loops"},{"title":"Connect your app to PostHog","sidebarTitle":"PostHog","href":"/integrations/posthog"},{"title":"Connect your app to Semrush","sidebarTitle":"Semrush","href":"/integrations/semrush"},{"title":"Connect your app to TikTok","sidebarTitle":"TikTok","href":"/integrations/tiktok"},{"title":"Connect your app to Twitch","sidebarTitle":"Twitch","href":"/integrations/twitch"},{"title":"Connect your app to X (Twitter)","sidebarTitle":"X (Twitter)","href":"/integrations/x"}]},{"group":"Payments \u0026 billing","pages":[{"title":"Connect your app to Chargebee","sidebarTitle":"Chargebee","href":"/integrations/chargebee"},{"title":"Connect your app to Pledge","sidebarTitle":"Pledge","href":"/integrations/pledge"},{"title":"Connect your app to Ramp","sidebarTitle":"Ramp","href":"/integrations/ramp"},{"title":"Connect your own Stripe account","sidebarTitle":"Stripe","href":"/integrations/stripe"}]},{"group":"Productivity","pages":[{"title":"Connect your app to Airtable","sidebarTitle":"Airtable","href":"/integrations/airtable"},{"title":"Connect your app to Asana","sidebarTitle":"Asana","href":"/integrations/asana"},{"title":"Connect your app to Ashby","sidebarTitle":"Ashby","href":"/integrations/ashby"},{"title":"Connect your app to Calendly","sidebarTitle":"Calendly","href":"/integrations/calendly"},{"title":"Connect your app to Fireflies","sidebarTitle":"Fireflies","href":"/integrations/fireflies"},{"title":"Connect your app to Google Workspace","sidebarTitle":"Google Workspace","href":"/integrations/google-workspace"},{"title":"Connect your app to Granola","sidebarTitle":"Granola","href":"/integrations/granola"},{"title":"Connect your app to incident.io","sidebarTitle":"incident.io","href":"/integrations/incidentio"},{"title":"Connect your app to Microsoft 365","sidebarTitle":"Microsoft","href":"/integrations/microsoft"},{"title":"Build and publish apps to Microsoft Copilot Managed Runtime","sidebarTitle":"Copilot Managed Runtime","href":"/integrations/microsoft-copilot-managed-runtime"},{"title":"Set up your Microsoft tenant for Copilot Managed Runtime","sidebarTitle":"Copilot Managed Runtime tenant setup","href":"/integrations/microsoft-copilot-managed-runtime-tenant-setup"},{"title":"Connect your app to Notion","sidebarTitle":"Notion","href":"/integrations/notion"},{"title":"Connect your app to Scrive for e-signatures and eID","sidebarTitle":"Scrive","href":"/integrations/scrive"},{"title":"Connect your app to Tally","sidebarTitle":"Tally","href":"/integrations/tally"},{"title":"Connect your app to Workday","sidebarTitle":"Workday","href":"/integrations/workday"}]},{"group":"Security \u0026 compliance","pages":[{"title":"Run AI-powered penetration tests with Aikido","sidebarTitle":"Aikido","href":"/integrations/aikido"},{"title":"Scan your projects for vulnerabilities with Wiz","sidebarTitle":"Wiz","href":"/integrations/wiz"}]},{"group":"Websites \u0026 CMS","pages":[{"title":"Connect your app to Contentful","sidebarTitle":"Contentful","href":"/integrations/contentful"},{"title":"Connect your app to Storyblok","sidebarTitle":"Storyblok","href":"/integrations/storyblok"},{"title":"Connect your app to Wix","sidebarTitle":"Wix","href":"/integrations/wix"},{"title":"Connect your app to WordPress (self-hosted)","sidebarTitle":"WordPress (self-hosted)","href":"/integrations/wordpress"},{"title":"Connect your app to WordPress.com","sidebarTitle":"WordPress.com","href":"/integrations/wordpress-com"}]}]},{"title":"Integrate any API with Lovable","sidebarTitle":"Connect any API","href":"/integrations/any-api"},{"group":"Git sync","root":{"title":"Sync your Lovable project code with GitHub, GitLab, or Bitbucket","sidebarTitle":"Git sync overview","href":"/integrations/git-sync-overview"},"pages":[{"title":"Sync your Lovable project with GitHub","sidebarTitle":"GitHub","href":"/integrations/github"},{"title":"Sync your Lovable project with GitLab","sidebarTitle":"GitLab","href":"/integrations/gitlab"},{"title":"Sync your Lovable project with Bitbucket","sidebarTitle":"Bitbucket","href":"/integrations/bitbucket"}]}]},{"group":"Collaborate","icon":"users","pages":[{"title":"Collaboration","href":"/features/collaboration"},{"title":"Share a project with internal or external collaborators","sidebarTitle":"Share a project","href":"/features/share-project"},{"title":"Project comments","sidebarTitle":"Project comments","href":"/features/project-comments"},{"title":"Control project access","sidebarTitle":"Project access","href":"/features/project-visibility"}]},{"group":"Deploy \u0026 host","icon":"globe","pages":[{"title":"How Lovable hosts your app","sidebarTitle":"Hosting","href":"/features/hosting"},{"title":"Publish your Lovable project","sidebarTitle":"Publish","href":"/features/publish"},{"title":"Set up a custom domain","sidebarTitle":"Custom domains","href":"/features/custom-domain"},{"title":"Transfer a domain to Lovable","sidebarTitle":"Transfer a domain","href":"/features/transfer-domain"},{"title":"Publish every app in your workspace under your own domain","sidebarTitle":"Publishing domain","tag":"ENT","href":"/features/publishing-domain"},{"title":"Publish apps with branded URLs","sidebarTitle":"Branded app URLs","href":"/features/branded-workspace-urls"},{"group":"Ownership \u0026 portability","root":{"title":"Deployment, hosting, and ownership options with Lovable","sidebarTitle":"Ownership \u0026 portability","href":"/tips-tricks/deployment-hosting-ownership"},"pages":[{"title":"Deploying and hosting outside Lovable","sidebarTitle":"Host outside Lovable","href":"/tips-tricks/external-deployment-hosting"}]}]},{"group":"Grow \u0026 optimize","icon":"chart-line","pages":[{"title":"Growth tools","sidebarTitle":"Growth tools","href":"/features/growth-tools"},{"title":"Optimize your app for SEO and AI search","sidebarTitle":"SEO and AEO","href":"/features/seo-aeo"},{"title":"Analytics","sidebarTitle":"Analytics","href":"/features/analytics"},{"title":"Advertise your app","sidebarTitle":"Ads","href":"/features/ads"},{"title":"Add payments to your app","sidebarTitle":"Payments","href":"/features/payments"},{"title":"Send branded emails from your own domain","sidebarTitle":"Emails","href":"/features/custom-emails"},{"title":"Publish your app as an MCP server","sidebarTitle":"Agent integrations","href":"/features/agent-integrations"},{"title":"Project monitoring","href":"/features/project-monitoring"}]},{"group":"Workspace \u0026 account","icon":"gear","pages":[{"group":"Workspace","root":{"title":"Lovable workspace","sidebarTitle":"Workspace","href":"/features/workspace"},"pages":[{"title":"Workspace admin settings","sidebarTitle":"Admin settings","href":"/features/workspace-admin-settings"},{"title":"Show an announcement banner to your workspace","sidebarTitle":"Announcements","href":"/features/workspace-announcements"},{"title":"Insights","sidebarTitle":"Insights","href":"/features/insights"},{"title":"Delete a workspace","href":"/introduction/delete-workspace"}]},{"group":"Organizations","root":{"title":"Organizations: run several workspaces as one company","sidebarTitle":"Organizations","tag":"ENT","href":"/features/organizations"},"pages":[{"title":"Set up organization identity: domains, SSO, and SCIM","sidebarTitle":"Organization identity","tag":"ENT","href":"/features/organization-identity"},{"title":"Manage people across the workspaces in your organization","sidebarTitle":"Organization people","tag":"ENT","href":"/features/organization-people"}]},{"group":"Access","pages":[{"title":"Manage workspace members from the People tab","sidebarTitle":"People","href":"/features/people"},{"title":"Groups","href":"/features/groups"},{"group":"Identity","root":{"title":"Manage workspace identity and user provisioning","sidebarTitle":"Workspace identity","href":"/features/workspace-identity"},"pages":[{"title":"Verify a domain for your workspace","sidebarTitle":"Verified domains","href":"/features/verified-domains"},{"title":"Set up workspace single sign-on (SSO)","sidebarTitle":"Workspace SSO","href":"/features/business/sso"},{"title":"Set up enterprise-managed authentication","sidebarTitle":"Enterprise-managed authentication","href":"/features/enterprise-managed-auth"},{"title":"Set up SCIM user provisioning","sidebarTitle":"SCIM provisioning","tag":"ENT","href":"/features/business/scim"}]},{"title":"Create and manage API keys","sidebarTitle":"API keys","href":"/features/api-keys"},{"title":"Connect apps to Lovable with OAuth","sidebarTitle":"OAuth clients","href":"/features/oauth-clients"}]},{"group":"Security","pages":[{"title":"Privacy \u0026 security settings","sidebarTitle":"Privacy \u0026 security","href":"/features/privacy-and-security-settings"},{"title":"Workspace policies","href":"/features/workspace-policies"},{"title":"Action center","href":"/features/action-center"},{"title":"EU inference","sidebarTitle":"EU inference","tag":"ENT","href":"/features/eu-inference"},{"group":"Security center","root":{"title":"Workspace security center","sidebarTitle":"Workspace security center","href":"/features/security-center"},"pages":[{"title":"Security insights","sidebarTitle":"Security insights","href":"/features/security-insights"}]},{"title":"Audit logs","tag":"ENT","href":"/features/audit-logs"},{"group":"Data exports","root":{"title":"Export audit logs to your SIEM or cloud storage","sidebarTitle":"Data exports","tag":"ENT","href":"/features/data-exports"},"pages":[{"title":"Export Lovable logs to Amazon S3","sidebarTitle":"Amazon S3","tag":"ENT","href":"/features/data-exports-amazon-s3"},{"title":"Export Lovable logs to Azure Blob Storage","sidebarTitle":"Azure Blob Storage","tag":"ENT","href":"/features/data-exports-azure-blob-storage"},{"title":"Export Lovable logs to Azure Log Analytics","sidebarTitle":"Azure Log Analytics","tag":"ENT","href":"/features/data-exports-azure-log-analytics"},{"title":"Export Lovable logs to Google Cloud Storage","sidebarTitle":"Google Cloud Storage","tag":"ENT","href":"/features/data-exports-google-cloud-storage"},{"title":"Export Lovable logs to Splunk","sidebarTitle":"Splunk","tag":"ENT","href":"/features/data-exports-splunk"}]},{"title":"Sensitive data scanning","tag":"ENT","href":"/features/sensitive-data-scanning"},{"title":"Manage training data and privacy","sidebarTitle":"Training data and privacy","href":"/features/business/data-opt-out"}]},{"group":"Your account","root":{"title":"Account settings","href":"/introduction/lovable-account-settings"},"pages":[{"title":"Two-factor authentication (2FA)","href":"/introduction/two-factor-authentication-2-fa"},{"title":"Delete account","href":"/introduction/delete-account"}]}]},{"group":"Plans \u0026 billing","icon":"credit-card","pages":[{"title":"Subscription plans","href":"/introduction/subscription-plans"},{"title":"Change or cancel your subscription","href":"/introduction/manage-subscription"},{"title":"Invoices, payments, and billing details","sidebarTitle":"Invoices and billing","href":"/introduction/invoices-and-billing"},{"title":"Credits and usage","href":"/introduction/credits-and-usage"},{"title":"Credit top-ups","href":"/introduction/credit-top-ups"},{"title":"Usage limits and alerts","sidebarTitle":"Usage limits \u0026 alerts","href":"/features/usage-limits-and-alerts"},{"title":"Low credit balance and out-of-credits recovery","sidebarTitle":"Low balance and recovery","href":"/introduction/out-of-credits"}]},{"group":"Guides \u0026 reference","icon":"life-ring","pages":[{"group":"Guides","pages":[{"title":"How to build a real product with Lovable","sidebarTitle":"Idea to product","href":"/tips-tricks/from-idea-to-app"},{"title":"Launch your site on a custom domain","sidebarTitle":"Launch on a custom domain","href":"/tips-tricks/launch-on-a-custom-domain"},{"title":"Prompting best practices","href":"/prompting/prompting-one"},{"title":"Prompt library","href":"/prompting/prompting-library"},{"title":"Debug and improve your app","sidebarTitle":"Debug \u0026 improve","href":"/prompting/prompting-debugging"},{"title":"Edit Google Docs, Sheets, and Slides in Lovable","sidebarTitle":"Edit Google files","href":"/tips-tricks/google-workspace-editing"}]},{"title":"FAQ","href":"/introduction/faq"},{"title":"Glossary","href":"/glossary"},{"title":"Video tutorials and courses","sidebarTitle":"Videos and courses","href":"/introduction/video-tutorials"},{"title":"Support policy","href":"/introduction/support-policy"}]}]},{"tab":"API Reference","pages":[{"title":"API Reference","href":"/api-reference/introduction"}]},{"tab":"Changelog","pages":[{"title":"Changelog","href":"/changelog"}]}]},"title":"Security best practices for Lovable apps - Lovable Documentation","buildId":"dpl_2xiSHD9XEvLsPGPcfoMtkLTB3dy9","deploymentId":"dpl_2xiSHD9XEvLsPGPcfoMtkLTB3dy9","dynamics":[],"chunks":[]}