Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.xano.com/llms.txt

Use this file to discover all available pages before exploring further.

Quick SummaryXano secures the platform — JWE-based auth, single-tenant infrastructure on dedicated plans, encrypted data at rest, SOC 2 / HIPAA / GDPR compliance. What Xano can’t decide for you is which endpoints should be public, which fields you return, who on your team can touch production, or whether the test accounts you seeded last month are still sitting in your database.This guide is the audit to run before pointing real users at your backend. Not every recommendation will apply to every project, but most will — work through each section and skip the ones that genuinely don’t fit.

Platform security vs. application security

Xano’s platform-level protections are real and they aren’t optional — your data lives on infrastructure that’s been hardened, audited, and certified. But there’s a clear line between platform security (what Xano handles) and application security (what you decide), and most launch-day incidents come from the second one. Application security covers everything that depends on choices only you can make:
  • Who on your team can change production
  • Where you build new features and how they get promoted
  • Which endpoints are reachable from the internet
  • What data those endpoints return
  • What’s still left in your database from prototyping
The most common shape of a launch-day incident is an endpoint the developer forgot they created. We call these ghost endpoints — live, reachable, unauthenticated, and not part of any feature anyone thinks they shipped. They usually originate from auto-generated CRUD during table setup, get forgotten, and never get revisited before launch. The audit below is structured to catch them, along with the rest of the sharp edges that tend to ship by accident.

1. Tighten Account & Team Access

Before you audit a single endpoint, make sure the people who can change your production app are the people who should be able to.

Turn on 2FA for every account with workspace access

Two-factor authentication is the single highest-value protection on a Xano account. Anyone with workspace access — you, your teammates, contractors — should have it enabled. See Enabling 2FA. If your plan supports it, the Require 2FA toggle in your instance Security Policy makes this non-optional for the whole team.

Review team members and their roles

Open your team list and remove anyone who no longer needs access — old contractors, former teammates, the agency that helped you prototype six months ago. For everyone who stays, make sure their role matches what they actually do. Xano’s Role-Based Access Control on Enterprise plans includes a dedicated Workspace Live Data Source permission, which is the gate between “can edit business logic” and “can read or modify production records.” If you have a developer who builds features but shouldn’t be able to query live customer data, that’s the toggle. See Managing Team Members for adding, removing, and adjusting access.

Rotate or revoke leftover Metadata API tokens

Any Metadata API tokens you generated during prototyping are still active until you revoke them. Walk your token list and:
  • Delete tokens you no longer use.
  • For tokens you keep, confirm the scopes are the minimum the integration actually needs. A token with all scopes in the hands of a third-party automation has a bigger blast radius than most teams realize.

Check the rest of the Security Policy

The instance Security Policy panel covers a few other settings worth a look before launch:
  • Inactivity timeout — how long a logged-in session can sit idle.
  • Allowed SSO hosts — restrict logins to specific email domains (e.g., only @yourcompany.com).
  • Authentication enforcement — require team members to log in via specific providers.
  • IP allowlisting / denylisting — restrict who can reach the Xano dashboard.

2. Build Somewhere That Isn’t Production

Most production accidents aren’t malicious — they’re a teammate running a quick test against the wrong data source, or a half-finished feature getting promoted before it’s ready. Xano gives you several layers to keep those accidents off of production.

Develop on a non-live data source

Your workspace can hold multiple data sources — separate sets of records that share the same schema. Use a dev or test data source for everything that isn’t a release, and reserve the live data source for production traffic. Switching is per-request, so the same function stack can run safely against either.

Develop on a non-live branch

Xano workspaces support branches, which are full copies of your business logic. Build new features on a non-live branch and only merge to the live branch when the feature is ready. Take a backup before merging — the branching doc covers the workflow in detail.

Use the sandbox to preview changes before they land

The sandbox is an isolated, ephemeral copy of your workspace that you push changes into first. You can inspect a full diff, run the changes, and verify behavior before promoting anything to a real branch. On paid plans, xano workspace push defaults to the sandbox flow specifically for this reason. The combined pattern — non-live branch + non-live data source + sandbox preview — is what lets you ship confidently without standing up separate staging environments to maintain.

Move secrets into Environment Variables

Anything sensitive hardcoded in a function stack — API keys, signing secrets, third-party tokens — should be moved into Environment Variables. They’re managed in one place, kept out of your function-stack values, and easier to rotate when something leaks.

Clear test accounts and seed data from production

Prototyping leaves residue. Before launch, walk your production data source and remove:
  • Test users with predictable credentials (test@test.com, admin@admin.com, anything with a password like password123)
  • Seeded admin accounts you created to verify the auth flow worked
  • Fixture rows from API testing — orders, posts, comments that aren’t tied to anything real
  • Backdoor accounts a teammate added for “just-in-case” access
A predictable test account on a live endpoint is functionally an unauthenticated endpoint. If you want to keep test users around for QA, move them to a separate data source.

Confirm the Direct Database Connector is locked down

If you’ve enabled the Direct Database Connector for an external tool, make sure the IP allowlist is set to only the addresses that need it. A direct connection bypasses the function-stack layer entirely, including auth checks and rate limits — useful when you need it, risky when it’s open.

3. Audit Your Endpoints

This is the part that catches ghost endpoints.

Inventory every endpoint

Before you can secure your endpoints, you need to see all of them — including the ones you forgot about.
1

Open every API group

Click API in the sidebar. Walk through every API group and each API. Anything in here is potentially live the moment your instance is reachable.
2

List endpoints you can't immediately explain

For each endpoint, ask: “Is this part of a feature my frontend or another consumer actually uses?” If the answer is no, or “I’m not sure,” flag it. These are your ghost-endpoint candidates.Common sources:
  • Auto-generated CRUD endpoints (GET /table, POST /table, DELETE /table/{id}, etc.) created during table setup
  • Endpoints created during prototyping that returned every field for debugging
  • Test or scratch endpoints that were never deleted
3

Delete, restrict, or keep

For every flagged endpoint, take one of three actions:
  • Delete it if it’s not used. An endpoint that doesn’t exist can’t be exploited.
  • Disable External Access if you want to keep the logic but prevent public traffic. The endpoint will only respond to internal calls.
  • Require authentication if it should be reachable but only by signed-in users.
These controls live in each endpoint’s Settings panel — see APIs.

Verify authentication on every endpoint that touches user data

Xano endpoints have an Authentication toggle in their settings. When it’s off, the endpoint will respond to any caller, signed in or not. The default for new endpoints is off — you have to turn it on. For every endpoint that reads, writes, or deletes user-scoped data:
  1. Open the endpoint’s Settings panel and set authentication to required.
  2. In the function stack, filter queries by the authenticated user’s ID (auth.id), not by an ID passed in the request. Authentication only proves someone is signed in; it does not stop user A from passing user B’s ID.
A GET /user/{user_id} endpoint that requires auth but doesn’t filter by auth.id will hand any user’s record to any signed-in caller. This is the most common shape of a data-harvesting attack — register a real account, get a token, iterate IDs. UUIDs make iteration much harder, but they aren’t a substitute for filtering correctly. The two endpoints below both require auth. Only one of them is safe.
query "users/{user_id}" verb=GET {
  api_group = "Users"
  auth = "user"

  input {
    int user_id { table = "user" }
  }

  stack {
    // Trusts whatever user_id the caller passed.
    // Any signed-in user can read any other user's record.
    db.get "user" {
      field_name = "id"
      field_value = $input.user_id
    } as $user
  }

  response = $user
}
The same principle applies to writes: when patching or deleting user-owned records, either filter by $auth.id directly, or load the record first and verify its created_by (or equivalent ownership field) matches $auth.id before continuing.

Lock down auto-generated API documentation

Each API group, and your workspace as a whole, has a Swagger setting that controls who can read its auto-generated documentation. The default is Public, which makes the full list of endpoints, methods, and inputs discoverable by anyone with the URL. For production, set Swagger to:
  • Private (requires token) — readable with the auto-generated token, which you can rotate or revoke.
  • Disabled — docs aren’t generated at all.
A locked-down Swagger setting doesn’t make your endpoints secure on its own, but once you’ve finished the audit above there’s usually no reason to publish a directory of every endpoint you have. See Swagger / OpenAPI Documentation.

Restrict CORS to origins you actually use

The default CORS configuration on a new API group is wildcard — any origin, any method, any header. That’s fine during development; it isn’t fine for a live app. In API Group Settings > CORS, switch to Custom and:
  • List only the origins that should be calling these APIs (production frontend, staging frontend, anything legitimate).
  • Restrict allowed methods to the verbs your frontend actually uses.
  • Restrict allowed headers to what you actually send.
CORS is browser-enforced, not a server-side firewall — it won’t stop a determined attacker, but it cuts off the casual case of another website embedding calls to your API in a user’s session.

Flag sensitive fields so they don’t land in logs

Xano keeps a Request History of incoming requests. Anything sent in a request body — passwords, tokens, PII — can end up stored there unless you mark the field as sensitive. For every field that holds credentials, secrets, or regulated personal data:
  1. Open the field’s settings in the database table.
  2. Enable Sensitive Data.
See Sensitive Data Flagging for the details and the limits of the flag (it covers database-link inputs, not arbitrary function-stack outputs).

Rate-limit endpoints that get hit hard

Paid Xano plans don’t apply a default rate limit, which means a single attacker can iterate IDs against your endpoints as fast as their network and your instance allow. For obvious harvest targets — login, signup, anything that takes an ID and returns a record — add explicit rate limiting via the Rate Limit function. Key the limit by IP, by authenticated user, or by both. If your plan includes Middleware, apply rate limiting (and other cross-cutting checks like role enforcement or suspicious-pattern logging) as middleware so a single rule covers a whole API group instead of being copy-pasted into every function stack.

Verify webhook signature checks

If you accept incoming webhooks from third parties (Stripe, GitHub, etc.), confirm each one verifies the request signature before doing anything with the payload. The Webhooks doc covers the hmac_sha256 / hmac_sha384 / hmac_sha512 security filters used to compare a computed signature against the one in the request header. Without that check, anyone who knows the URL can forge a webhook.

4. Get Ready to Watch What’s Happening

Once you launch, the question stops being “did I configure this right?” and starts being “is something happening I didn’t expect?”

Take a manual backup before launch

Xano keeps a rolling backup automatically, but it’s worth taking a manual one right before your first real traffic — that gives you a clean restore point if something goes sideways in the first 24 hours. See Backup and Restore for retention details and how to take backups on demand.

Know where to look when something looks off

Two surfaces, two different jobs:
  • Request History — what’s hitting your APIs. Watch for traffic to endpoints you didn’t know were being called, repeated GETs with iterating IDs (classic harvest pattern), 401/403 clusters on endpoints nothing should be probing, and unfamiliar user agents.
  • Audit Logs — what’s changing inside your workspace. Who edited which function, who deleted which table, who flipped a setting. If a teammate’s account ever gets compromised, this is where you’ll see the damage.
Open both right after launch and again the next day. Most issues that catch teams off guard are visible in one of these two places hours before they become a real problem.

Pre-Launch Security Checklist

Once you’ve worked through the sections above, confirm: Account & team
  • 2FA enabled on every account with workspace access
  • Team list reviewed; old or unused accounts removed
  • RBAC roles match what each person actually needs to do
  • Metadata API tokens audited — unused ones revoked, scopes minimized
  • Instance Security Policy reviewed (inactivity, SSO hosts, IP rules)
Environments
  • Development happens on a non-live data source
  • Development happens on a non-live branch
  • Sandbox previews used before promoting changes
  • Secrets moved into Environment Variables (no hardcoded keys)
  • Test accounts and seed data cleared from production
  • Direct Database Connector locked down or disabled
Endpoints
  • Walked every API group and identified every endpoint
  • Deleted endpoints that aren’t used by any consumer
  • Disabled External Access on internal-only endpoints
  • Enabled Authentication on every endpoint that returns or modifies user-scoped data
  • Verified function stacks filter by auth.id rather than trusting IDs from the request
  • Set Swagger to Private or Disabled on production API groups
  • Replaced wildcard CORS with an explicit list of allowed origins, methods, and headers
  • Flagged every field carrying credentials, secrets, or regulated PII as Sensitive Data
  • Added rate limiting to login, signup, and other obvious harvest targets
  • Applied centralized Middleware for cross-cutting auth and rate-limit rules where available
  • Confirmed every incoming webhook verifies its signature
Operational
  • Manual backup taken right before launch
  • Reviewed Request History for traffic against endpoints you can’t explain
  • Reviewed Audit Logs for unexpected workspace changes