<p>
    Appwrite provides many security features to keep both your Appwrite project and your user's information secure.
</p>

<h2><a href="/docs/authentication-security#persistence" id="persistence">Persistence</a></h2>

<p>
    Appwrite handles the persistence of the session in a consistent way across SDKs. After authenticating with an SDK, the SDK will persist the session so that the user will not need to log in again the next time they open the app. The mechanism for persistence depends on the SDK.
</p>

<div class="notice">
  <h2>Best Practice</h2>
  <p>Only keep user sessions active as long as needed and maintain exactly <b>one</b> instance of the Client SDK in your app to avoid conflicting session data.</p>
</div>

<table cellspacing="0" cellpadding="0" border="0" class="full margin-bottom-large text-size-small vertical">
    <thead>
        <tr>
            <th style="width: 80px"></th>
            <th style="width: 120px">SDK</th>
            <th>Persistence Method</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <img src="/images-ee/platforms/web.svg" alt="Logo" height="30" class="force-light sdk-logo margin-start margin-end" />
                <img src="/images-ee/platforms/dark/web.svg" alt="Logo" height="30" class="force-dark sdk-logo margin-start margin-end" />
            </td>
            <td>
                Web
            </td>
            <td>
                Uses a secure session cookie and falls back to local storage when a session cookie is not available.
            </td>
        </tr>        
        <tr>
            <td>
                <img src="/images-ee/platforms/flutter.svg" alt="Logo" height="30" class="force-light sdk-logo margin-start margin-end" />
                <img src="/images-ee/platforms/dark/flutter.svg" alt="Logo" height="30" class="force-dark sdk-logo margin-start margin-end" />
            </td>
            <td>
                Flutter
            </td>
            <td>
                Uses a session cookie stored in Application Documents through the <b>path_provider</b> package.
            </td>
        </tr>
        <tr>
            <td>
                <img src="/images-ee/platforms/apple.svg" alt="Logo" height="30" class="force-light sdk-logo margin-start margin-end" />
                <img src="/images-ee/platforms/dark/apple.svg" alt="Logo" height="30" class="force-dark sdk-logo margin-start margin-end" />
            </td>
            <td>
                Apple
            </td>
            <td>
                Uses a session cookie stored in <b>UserDefaults</b>.
            </td>
        </tr>
        <tr>
            <td>
                <img src="/images-ee/platforms/android.svg" alt="Logo" height="30" class="force-light sdk-logo margin-start margin-end" />
                <img src="/images-ee/platforms/dark/android.svg" alt="Logo" height="30" class="force-dark sdk-logo margin-start margin-end" />
            </td>
            <td>
                Android
            </td>
            <td>
                Uses a session cookie stored in <b>SharedPreferences</b>.
            </td>
        </tr>
    </tbody>
</table>

<h2><a href="/docs/authentication-security#limits" id="limits">Session Limits</a></h2>
<p>In Appwrite versions 1.2 and above, you can limit the number of active sessions created per user to prevent the accumulation of unused but active sessions. New sessions created by the same user past the session limit delete the oldest session.</p>

<p>You can change the session limit in the <b>Security</b> tab of the Auth Service in your Appwrite Console. The default session limit is 10 with a maximum configurable limit of 100.</p> 

<h2><a href="/docs/authentication-security#permissions" id="permissions">Permissions</a></h2>

<p>
    Security is very important to protect users' data and privacy. 
    Appwrite uses a <a href="/docs/permissions">permissions model</a> coupled with user sessions to ensure users need correct permissions to access resources.
    With all Appwrite services, including databases and storage, access is granted at the collection, bucket, document, or file level. 
    These permissions are enforced for client SDKs and server SDKs when using JWT, but are ignored when using a server SDK with an API key.
</p>

<h2><a href="#password-history" id="password-history">Password History</a></h2>
<p>Password history prevents users from reusing recent passwords. This protects user accounts from security risks by enforcing a new password every time it's changed.</p>

<p>Password history can be enabled in the Auth service's <b>Security</b> tab on the Appwrite Console. You can choose how many previous passwords to remember up to a maximum of 20 and block users from reusing them.</p>

<h2><a href="#password-dictionary" id="password-dictionary">Password Dictionary</a></h2>
<p>Password dictionary protects users from using bad passwords. It compares the user's password to the <a href="https://github.com/danielmiessler/SecLists/blob/master/Passwords/Common-Credentials/10k-most-common.txt">10,000</a> most common passwords and throws an error if there's a match. Together with <a href="/docs/rate-limits">rate limits</a>, password dictionary will significantly reduce the chance of a malicious actor from guessing user passwords.</p>

<p>Password dictionary can be enabled in the Auth service's <b>Security</b> tab on the Appwrite Console.</p>

<h2><a href="#personal-information" id="personal-information">Personal Data</a></h2>
<p>
    Encourage passwords that are hard to guess by disallowing users to pick passwords that contain personal data. 
    Personal data includes the user's name, email, and phone number.
</p>
<p>Disallowing personal data can be enabled in the Auth service's <b>Security</b> tab on the Appwrite Console.</p>