Security

    Is my Neon database secure for a mobile app?

    A mobile developer reviewing a React Native build configuration on a laptop, with a Neon Postgres dashboard showing branch credentials and Row Level Security policies on a second monitor.

    A founder ships a prototype that talks to a Neon Postgres database from a React Native app. The app works, the dashboard shows queries running, and the question shifts from will it work to is this safe for real users. Neon's own infrastructure is well secured, but the architecture choice you make on the client side decides whether a mobile app built on Neon is genuinely safe, or one decompile away from a full database breach.

    Short answer

    Neon is a managed Postgres service with SOC 2 Type II compliance, TLS 1.2 and 1.3 in transit, AES-256 encryption at rest, and HIPAA eligibility on the Scale plan since the Databricks acquisition. The platform itself is safe to build on. A mobile app becomes unsafe when it stores the Postgres connection string in the binary, when it skips Row Level Security on user-scoped tables, or when it shares branch credentials between development and production. Use the Neon Data API with JWT and RLS, or front the database with an authenticated server, and never embed a direct connection string in a build that ships to App Store or Google Play.

    What you should know

    • Neon's connection string is the whole attack surface. A leaked postgresql://user:password@host/db URL is equivalent to handing over the keys to the database, and anything baked into a mobile binary can be extracted.
    • Row Level Security is not optional. Every user-scoped table needs RLS policies tied to the JWT subject, otherwise one user can read another user's data.
    • The Data API is the mobile-safe entry point. It accepts JWT tokens, switches to the authenticated or anonymous Postgres role, and applies the existing RLS policies in the database.
    • Branch credentials should never be shared. Each Neon branch carries its own connection string; using one credential across development, staging, and production removes the protection that branching exists to provide.
    • TLS verify-full is the safe default. Neon documents sslmode=verify-full as the most secure connection mode, including hostname and revocation checks.
    • HIPAA support is plan-gated. The Scale tier on Neon, post the Databricks acquisition in 2025, is HIPAA-eligible with a signed BAA; lower tiers are not.

    How does Neon handle data and connections under the hood?

    The short answer is that Neon separates storage from compute, runs all client traffic through an authenticating proxy, and enforces SSL on every connection.

    Storage sits on a distributed, log-based system; compute nodes attach to it on demand and scale to zero when idle. According to Neon's security overview, data on the NVMe storage layer is encrypted with AES-256, and the in-transit channel uses TLS 1.2 or 1.3. Connection authentication runs through the Neon Proxy before traffic ever reaches Postgres, with 60 bits of entropy on every generated role password.

    The mechanism that matters for a mobile use case is the connection model. A Neon project exposes a Postgres endpoint that is reachable from any IP on the public internet unless you are on the Scale plan with an allowlist or PrivateLink in place. That means the security boundary lives on the application side: whoever holds a valid connection string can connect.

    The limit is that none of these defaults stop a client from leaking the credential. The platform is doing its job. The question is what the client app does with the connection string it holds.

    What happens if a mobile app uses the Neon connection string directly?

    The short answer is that you have handed every user, and every attacker who downloads your IPA or APK, a working credential to the production database.

    A compiled iOS or Android binary is not a secret. Tools like class-dump, apktool, and frida make it trivial to extract strings, plist files, and assets/ payloads from a downloaded build. A DATABASE_URL set as a build-time environment variable ends up inside the bundled JavaScript or the compiled Kotlin code, and a string search across the extracted binary surfaces it within seconds.

    Once the connection string is in attacker hands, native Postgres clients connect from any IP, run any query, and see every row in every table that the role can reach. Row Level Security helps only when the connection runs under a role whose RLS context is set per request; a direct Postgres connection from a leaked string typically runs under a role that bypasses RLS entirely.

    This is the pattern the Quokka analysis of the Neon dating app breach walks through in detail. The takeaway for mobile builders is uncomplicated: a Postgres connection string belongs on a server, never on a device.

    How does the Neon Data API change the picture?

    The short answer is that the Data API is the path Neon publishes for client-side use, and it does so by replacing the connection string with a JWT.

    According to Neon's Data API access control documentation, the Data API accepts requests with an Authorization: Bearer <jwt> header, validates the token against your configured authentication provider, and switches the request to the authenticated Postgres role (or to anonymous when no token is present). The sub claim identifies the user, and RLS policies that reference the JWT user identifier enforce per-row access.

    The mechanism is two-layer. Layer one is table privileges: the authenticated role needs an explicit GRANT on each table before any operation succeeds. Layer two is RLS: even with the grant, policies decide which rows the request can read or write. Both layers fail closed.

    In practice this means a mobile app holds only a short-lived JWT issued by an identity provider, not a database credential. If the JWT leaks, it expires; if the credential signing key leaks, you rotate it. A compromised device cannot reach data the JWT was not scoped for.

    The trade-off is that you have to write the RLS policies. The Data API does not invent them, and a missing policy on a sensitive table is a silent privilege escalation waiting to happen.

    Which compliance certifications matter for a mobile use case?

    The short answer is SOC 2 Type II for general data protection, HIPAA on the Scale plan for any health data, and ISO 27001 plus ISO 27701 if you sell into European enterprises.

    Neon's published security and compliance page lists SOC 2 Type II, ISO 27001, ISO 27701, GDPR alignment, and CCPA alignment as current certifications. HIPAA eligibility arrived on the Scale tier following the Databricks acquisition, which closed in 2025. Lower tier plans are not in scope for PHI.

    The mobile relevance is twofold. First, the privacy nutrition labels in App Store Connect and the Data Safety form on Google Play both ask which categories of personal data the app collects and where it is stored. Pointing the data residency answer at a SOC 2 Type II Postgres is materially different from pointing it at a hobbyist VPS. Second, for a health, fintech, or government app, the BAA on Neon is the contractual mechanism that brings the database inside a compliant perimeter, but it does not extend to the editor where the schema was written or the AI tool that produced the application code.

    LayerDefault protectionMobile-safe configuration
    Connection in transitTLS 1.2 or 1.3sslmode=verify-full with channel binding
    Connection identityPostgres role plus passwordJWT against the Data API; password held server side
    Data at restAES-256 on NVMe storageEncrypted columns for high sensitivity fields
    Per-row accessNone until you enable itRow Level Security policies on every user table
    Branch isolationBranches share project, get their own URLSeparate credentials for dev, preview, staging, prod
    Network reachabilityPublic internetIP allowlist or PrivateLink on the Scale plan
    Audit loggingProject-level via the Neon ConsolePostgres-level audit on sensitive tables

    The practical implication is that every row in the table is a configuration step, not a default. Neon supplies the building blocks; the developer assembles them.

    What does an audit against OWASP MASVS surface for a Neon-backed app?

    The short answer is that the highest-value findings sit in MASVS-AUTH, MASVS-NETWORK, MASVS-STORAGE, and MASVS-CODE.

    The OWASP MASVS categories cover authentication, network communication, data storage, cryptography, platform interactions, code quality, resilience to tampering, and privacy. For a database-backed mobile app, four of those carry most of the weight.

    MASVS-AUTH catches the JWT lifetime, refresh flow, and biometric gating on sensitive operations. MASVS-NETWORK catches whether the app actually uses verify-full rather than accepting any self-signed certificate, and whether certificate pinning is on for high-value flows. MASVS-STORAGE catches caches, request logs, and any persisted copy of the JWT that lands in plaintext on disk. MASVS-CODE catches hardcoded secrets, exposed service keys, and dependency vulnerabilities in the Postgres or HTTP client used to talk to the Data API.

    For builders who want an external read of a compiled build before submission, PTKD.com (https://ptkd.com) is one of the platforms focused on scanning APK, AAB, and IPA files against OWASP MASVS controls, surfacing the storage and network findings that reviewers and auditors most often raise for database-backed apps.

    The limit is that a static scan cannot prove your RLS policies are correct. It can flag a leaked connection string in the binary; it cannot read the SQL on your Neon project. That part remains a manual review.

    What to watch out for

    The first trap is the convenience of a direct Postgres connection during prototyping. Many AI coding agents will happily wire a React Native client straight to Neon because the code is shorter. The shortcut survives long enough to ship, and then the breach happens on the first weekend the app is live.

    The second trap is shared branch credentials. A Neon branch carries its own connection string for a reason: rolling a development credential should not also force a production rotation. Treat the production branch as a separate trust domain and store its credentials only on the server side.

    The third trap is missing RLS on tables added after the initial schema. Neon's Data API switches into the authenticated role and respects whatever RLS exists; a table created later without policies inherits the role's broad SELECT permission and silently becomes readable across users.

    The fourth trap is logging the JWT or the request payload. Crash reporters and analytics SDKs ingest network traces by default, and a JWT in an event payload sent to a third party expands the trust boundary in ways that fail MASVS-STORAGE on review.

    Key takeaways

    • Neon's platform is secure by default, but the security of a Neon-backed mobile app is decided by the architecture choice between a direct Postgres connection (unsafe on a device) and the Data API with JWT and RLS (the path published for client-side use).
    • Embedding a Postgres connection string in an iOS or Android binary is the most common single failure; treat the connection string as a server-only secret and rotate any credential that has ever shipped in a build.
    • Row Level Security needs a policy on every user-scoped table, and the policies need to be reviewed each time a new table is added, otherwise the Data API will happily serve cross-user data.
    • HIPAA eligibility on Neon is plan-gated to the Scale tier following the Databricks acquisition; mobile health apps need the BAA in writing before the first production user signs up.
    • Some teams ask platforms like PTKD.com (https://ptkd.com) to read the compiled IPA or APK against OWASP MASVS before submission, catching hardcoded credentials, weak TLS settings, and JWT handling issues before App Review or Play Console raises them.
    • #neon
    • #postgres
    • #database
    • #mobile security
    • #owasp masvs
    • #jwt
    • #row level security
    • #ai-coded apps

    Frequently asked questions

    Can I put a Neon connection string inside my iOS or Android app?
    No. Compiled iOS and Android binaries are not secrets; standard tools like apktool and class-dump extract embedded strings within seconds, and a leaked Postgres connection string is a working credential for any attacker with a Postgres client. Keep the connection string on a server, hand the mobile app a short-lived JWT, and verify each release against OWASP MASVS-STORAGE and MASVS-CODE before submission.
    What does Neon's HIPAA support actually cover?
    HIPAA eligibility on Neon arrived with the Scale tier following the Databricks acquisition in 2025, and applies once the Business Associate Agreement is signed. It covers the Postgres database and the underlying storage; it does not cover the AI coding tools you use to write the schema, third-party telemetry SDKs, or hosting providers that hold the application server. Each vendor in the data path needs its own BAA.
    Does Row Level Security replace a backend API?
    RLS combined with the Neon Data API can replace many backend endpoints, because the JWT-to-role mapping plus per-row policies enforce access in the database itself. A dedicated server still earns its place for operations that need server-only secrets, rate limiting, audit logging, or third-party calls. The decision usually comes down to whether the workload is mostly CRUD with row scoping, or whether it orchestrates external systems.
    How should I handle Neon database branches in a mobile project?
    Each Neon branch carries its own connection string and password by design, so production should run on a dedicated branch whose credentials never appear in any client build or shared environment file. Use preview branches for ephemeral testing, scope read-only roles per branch where possible, and rotate any credential that has touched a shipped build, a CI log, or a chat thread.
    What does OWASP MASVS say about cloud database access from a mobile app?
    OWASP MASVS does not prescribe one architecture, but the relevant controls cover how secrets are stored on device (MASVS-STORAGE), how authentication tokens are protected (MASVS-AUTH), and how TLS is enforced on outbound calls (MASVS-NETWORK). A direct Postgres connection from the device tends to fail MASVS-STORAGE because the credential is recoverable from the binary, and MASVS-AUTH because the credential never expires.

    Keep reading

    Scan your app in minutes

    Upload an APK, AAB, or IPA. PTKD returns an OWASP-aligned report with copy-paste fixes.

    Try PTKD free