Is Appwrite Safe? Open-Source BaaS Security Review (2026)

Roughly 20% of AI-built apps that use Appwrite as a backend have at least one collection or storage bucket with any set as a write permission. That single misconfiguration lets anyone without an account create, update, or delete records in that collection. No authentication. No rate limiting from the permission layer. Just an open write endpoint sitting in production.

The platform itself is not the problem. The permission model is flexible by design. The issue is that "any" is a tempting shortcut during development, and AI code generators often leave it in place when scaffolding backend logic.

TL;DR

Appwrite Cloud is secure infrastructure. The risks are in your configuration: document and bucket permissions set to any allow unauthenticated writes, server API keys belong only in server-side code (never in client bundles), and self-hosted deployments must replace the _APP_OPENSSL_KEY_V1 default before going live. Get those three right and Appwrite is a solid production backend.

Safe to Use

Our Verdict

What's Good

  • Client SDK uses sessions, not API keys, so there's no key to accidentally leak from the browser
  • SOC 2 aligned security controls on Appwrite Cloud
  • Fine-grained permission roles: user, team, label, and any combinations
  • internalPermissions on individual documents override collection defaults
  • EU data residency available; GDPR data processing agreements provided
  • Active security disclosure program and regular CVE patches

What to Watch

  • any permission is dangerously easy to set and forgets to require authentication
  • Realtime subscriptions expose the same data as REST queries, so an open collection leaks via both channels
  • Self-hosting requires manual rotation of encryption secrets and manual updates
  • Server API keys have no expiry by default; compromised keys stay valid indefinitely until manually revoked
  • Storage buckets default to no permissions, which blocks all access, but switching to any for convenience is common

The Permission Model Footgun

Appwrite controls access to documents, collections, buckets, and functions through a permission system with these roles:

RoleWho it allows
anyEvery visitor, authenticated or not
usersAny logged-in user
guestsOnly unauthenticated visitors
user:[userId]One specific user
team:[teamId]All members of a team

The problem is any on write operations. During development, setting any to create/update/delete is convenient: you can test writes without worrying about auth tokens. In production, it means any HTTP client can write to your database.

CheckYourVibe flags any write permissions on collections and buckets as a critical finding. The actual scanner output looks like this:

Critical: Unauthenticated Write Access on 'posts' Collection

Appwrite collection permissions include create: any and update: any. Any visitor can create or modify records without an account. Found in your Appwrite database configuration.

The fix is straightforward: replace any with users for operations that require a login, and user:[userId] for operations that should only affect the current user's own data.

// Wrong: any visitor can create a post
const permissions = [
  Permission.create(Role.any()),
  Permission.read(Role.any()),
];

// Right: only the authenticated user can create, anyone can read (public content)
const permissions = [
  Permission.create(Role.user(userId)),
  Permission.read(Role.any()),
];

API Key Exposure: Client vs. Server

Appwrite has two authentication modes and they are not interchangeable.

Client SDK (for browser and mobile apps): Authenticates via session cookies after the user logs in. You initialize it with your Project ID and Endpoint only. No API key involved.

// Client-side: no API key, this is correct
import { Client, Account } from 'appwrite';

const client = new Client()
  .setEndpoint('https://cloud.appwrite.io/v1')
  .setProject('your-project-id');  // Project ID is not a secret

Server SDK (for backend services, functions, webhooks): Authenticates with an API key that has specific scopes like documents.write or users.read.

// Server-side only: API key must never reach the browser
import { Client, Users } from 'node-appwrite';

const client = new Client()
  .setEndpoint('https://cloud.appwrite.io/v1')
  .setProject(process.env.APPWRITE_PROJECT_ID)
  .setKey(process.env.APPWRITE_API_KEY);  // Keep this server-side only

When CheckYourVibe scans your deployed app, we look for NEXT_PUBLIC_APPWRITE_API_KEY, VITE_APPWRITE_API_KEY, or any variable with an Appwrite-shaped value (standard_ prefix, 40-character hex) appearing in your client JavaScript. Finding one means that key's full scope is available to every visitor.

Appwrite API keys have no expiry date by default. If you suspect a key was leaked, go to Appwrite Console > Project > API Keys, delete the compromised key immediately, and generate a new one. There is no automatic rotation.

Self-Hosting: The Encryption Key Problem

The most serious self-hosting misconfiguration is the _APP_OPENSSL_KEY_V1 environment variable. This key encrypts stored OAuth tokens, session secrets, and user credentials. Appwrite ships with a placeholder in its docker-compose.yml:

# docker-compose.yml (self-hosted Appwrite)
environment:
  - _APP_OPENSSL_KEY_V1=your-secret-key  # THIS MUST BE REPLACED

Hundreds of tutorials and GitHub repos show this exact default. If you deployed Appwrite without changing this value, every stored session token and OAuth credential in your database was encrypted with the string "your-secret-key". Anyone with database read access can decrypt them.

To generate a strong key before first run:

# Generate a 32-byte random key (base64 encoded)
openssl rand -base64 32

# Set it in your .env before docker compose up
echo "_APP_OPENSSL_KEY_V1=$(openssl rand -base64 32)" >> .env

If you already have user data encrypted with the default key, rotating it requires a migration: export users, change the key, re-import. The Appwrite documentation covers this process, but it is disruptive. Get it right before the first deployment.

Changing _APP_OPENSSL_KEY_V1 on a running deployment with existing users will invalidate all current sessions and OAuth tokens. Every user will be logged out and external OAuth connections will break. Do this before you have real users, or plan a maintenance window.

What Appwrite Cloud Handles for You

If you're using Appwrite Cloud rather than self-hosting, the platform manages:

  • TLS/SSL: All traffic encrypted in transit, certificates managed automatically
  • Encryption keys: The _APP_OPENSSL_KEY_V1 equivalent is set and rotated by Appwrite
  • Infrastructure updates: Security patches applied without your intervention
  • DDoS mitigation: Handled at the network edge
  • Backups: Managed database backups with point-in-time recovery on higher plans

Appwrite Cloud is SOC 2 aligned and offers GDPR data processing agreements. EU data residency (Frankfurt region) is available on Pro and Scale plans for teams with regulatory requirements.

The tradeoff is that you do not have direct database access or control over the infrastructure configuration. For most founders building AI-assisted apps, that tradeoff is worth it.

Realtime Subscriptions and the Double-Exposure Risk

Appwrite's Realtime feature lets clients subscribe to collection changes. It uses the same permission model as the REST API, which means an open collection is exploitable via Realtime as well as direct queries.

// Subscribing to a collection with any:read permission
// This stream is available to unauthenticated clients
const unsubscribe = client.subscribe(
  'databases.production.collections.orders.documents',
  (response) => {
    console.log(response.payload); // Every new order, visible to anyone
  }
);

If your orders collection has read: any set, every new document created fires a Realtime event that any connected client receives. Close the read permission to users or user:[userId] to restrict it.

Storage Buckets: Same Model, Different Default

Appwrite storage buckets default to no permissions, which means all access is blocked until you set them. This is safer than an open default, but the fix is often too broad.

A bucket with read: any makes every uploaded file publicly accessible via a direct URL, with no authentication required:

https://cloud.appwrite.io/v1/storage/buckets/[bucketId]/files/[fileId]/view

For user-generated content that should be private (profile photos, uploaded documents, medical records), use read: user:[userId] instead. For genuinely public assets like product images, read: any is fine.

Function Security

Appwrite Functions run server-side and receive injected environment variables via process.env.APPWRITE_FUNCTION_PROJECT_ID and process.env.APPWRITE_FUNCTION_API_KEY. These are provided by the platform and are not in your function code.

What you do control is what your function exposes. An HTTP-triggered function that returns sensitive data without checking req.headers['x-appwrite-trigger'] or validating a webhook signature is an open endpoint. Add explicit caller verification to any function handling webhooks or sensitive operations.

Is Appwrite safe for production apps?

Appwrite Cloud is safe for production when you configure permissions correctly. The platform handles SSL, managed infrastructure, and SOC 2 aligned security controls. The risks are in your configuration: document and bucket permissions set to any expose data to unauthenticated users, and server API keys placed in client-side code give attackers full backend access.

What is the biggest security risk in Appwrite?

The any shortcut in Appwrite's permission model. Setting create, update, or delete access to any on a document collection or storage bucket means any visitor can write or overwrite that data without logging in. CheckYourVibe flags this as a critical finding when it appears on collections holding user or payment data.

Should I use Appwrite Cloud or self-host Appwrite?

Appwrite Cloud removes most infrastructure security concerns: managed TLS, automatic updates, and no default secrets to rotate. Self-hosting gives you full data control but requires you to set a strong _APP_OPENSSL_KEY_V1 before first run, restrict console access, manage updates yourself, and secure the Docker network. For most founders, Cloud is safer because the default is managed.

Can Appwrite API keys be exposed in the browser?

Yes, if you use a server API key in client-side code. Appwrite's client SDK does not use API keys: it authenticates via session cookies after a login flow. Server API keys (the standard_XXXXX format) are for backend services only. If you see APPWRITE_API_KEY or NEXT_PUBLIC_APPWRITE_API_KEY in your frontend code, that key is either already in your bundle or about to be.

Is Appwrite GDPR compliant?

Appwrite Cloud offers GDPR-compliant data processing with EU data residency available on Pro and Scale plans. The platform supports data deletion, export, and consent workflows. Self-hosted deployments put GDPR compliance on you: you own the infrastructure, the backups, and the data processing agreements.

Check your deployed Appwrite app for exposed API keys in your JavaScript bundle, open collection permissions, and security header gaps. Free scan, no signup required.

Is It Safe?

Is Appwrite Safe? Open-Source BaaS Security Review (2026)