> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cognee.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Security & Privacy

> Configure security controls for sensitive data, API key protection, and access control in self-hosted Cognee deployments

Cognee exposes several environment variables that let you harden a self-hosted deployment for production use.
Some controls are enforced by default, while others remain permissive for local development, so you should review each setting before exposing Cognee to untrusted users or networks.

## Security Controls

<AccordionGroup>
  <Accordion title="Authentication">
    ### Require authentication for all API requests

    ```dotenv theme={null}
    REQUIRE_AUTHENTICATION=False   # only applies when ENABLE_BACKEND_ACCESS_CONTROL=False
    ```

    When `false`, the API can accept unauthenticated requests and fall back to the built-in default user.
    Set to `true` in any environment where the API is reachable by untrusted clients.

    <Warning>
      If `ENABLE_BACKEND_ACCESS_CONTROL=true` (the default), authentication is **enforced automatically** regardless of the value of `REQUIRE_AUTHENTICATION`. In practice, the default behavior is authenticated access unless you explicitly set **both** `ENABLE_BACKEND_ACCESS_CONTROL=false` and `REQUIRE_AUTHENTICATION=false`.
    </Warning>

    ### JWT token settings

    ```dotenv theme={null}
    FASTAPI_USERS_JWT_SECRET="super_secret"   # default — CHANGE IN PRODUCTION
    JWT_LIFETIME_SECONDS=3600                 # default: 1 hour
    ```

    `FASTAPI_USERS_JWT_SECRET` must be the same across all instances (e.g., all Kubernetes pods) so that a token issued by one pod is accepted by another. Use a long, randomly generated string in production and never commit the real value to version control.

    `JWT_LIFETIME_SECONDS` controls how long a bearer token or cookie remains valid before the user must log in again.
  </Accordion>

  <Accordion title="Data Protection">
    ### API Key Storage

    ```dotenv theme={null}
    HASH_API_KEY="False"   # default
    ```

    When `false`, API keys are stored as plaintext in the relational database.
    When `true`, each key is hashed with **SHA-256** before storage. The raw key is shown to the user only once at creation time and cannot be recovered afterward.

    <Warning>
      **Migration note:** Enabling `HASH_API_KEY` on a running system that already has plaintext API keys stored will break those existing keys immediately — the lookup hashes the incoming value and finds no match. You must either delete and re-issue all existing keys, or run a one-off migration to SHA-256-hash the existing `api_key` column values.
    </Warning>

    ### Local File System Access

    ```dotenv theme={null}
    ACCEPT_LOCAL_FILE_PATH=True   # default
    ```

    When `true`, Cognee accepts local filesystem paths as data sources (e.g., `/etc/passwd`). This is convenient for local development but dangerous when Cognee is exposed as a multi-user backend — an authenticated user could read arbitrary files that the Cognee process has access to.

    Set to `false` when running Cognee as a backend service:

    ```dotenv theme={null}
    ACCEPT_LOCAL_FILE_PATH=False
    ```

    ### Cypher Query Access

    ```dotenv theme={null}
    ALLOW_CYPHER_QUERY=True   # default
    ```

    When `true`, users can execute raw Cypher queries against the graph database (`SearchType.CYPHER`) and use natural language-to-Cypher translation (`SearchType.NATURAL_LANGUAGE`). Disable this to limit users to higher-level semantic search only:

    ```dotenv theme={null}
    ALLOW_CYPHER_QUERY=False
    ```

    ### Encrypting Neo4j Aura Credentials

    When using the `neo4j_aura_dev` dataset database handler for multi-user mode, Cognee stores per-dataset Neo4j Aura database connection info in the relational database. The stored **database password** is encrypted with **Fernet symmetric encryption**; the encryption key is derived from `NEO4J_ENCRYPTION_KEY`:

    ```dotenv theme={null}
    NEO4J_ENCRYPTION_KEY="test_key"   # default — CHANGE IN PRODUCTION
    ```

    The default value `"test_key"` is intentionally insecure. Replace it with a long random string in any environment that stores real Neo4j Aura credentials.

    <Info>
      The Aura API credentials used to create or delete instances (`NEO4J_CLIENT_ID`, `NEO4J_CLIENT_SECRET`, and `NEO4J_TENANT_ID`) are read from environment variables when needed and are **not** stored in the relational database by this handler.
    </Info>
  </Accordion>

  <Accordion title="Multi-User Isolation">
    ### Dataset & Multi-User Isolation

    ```dotenv theme={null}
    ENABLE_BACKEND_ACCESS_CONTROL=True   # default
    ```

    When enabled, Cognee creates isolated storage per user + dataset combination and enforces permission checks on every read and write operation. This is the primary control for preventing cross-tenant data leakage in multi-user deployments.

    Database support requirements:

    | Layer      | Supported backends                          |
    | ---------- | ------------------------------------------- |
    | Relational | SQLite, PostgreSQL                          |
    | Vector     | LanceDB, PGVector                           |
    | Graph      | Kuzu, Neo4j Aura (`neo4j_aura_dev` handler) |

    If you configure an unsupported backend (e.g., Qdrant, Weaviate), disable access control to avoid runtime errors:

    ```dotenv theme={null}
    ENABLE_BACKEND_ACCESS_CONTROL=False
    REQUIRE_AUTHENTICATION=False
    ```

    See [Dataset Database Handlers](/core-concepts/multi-user-mode/dataset-database-handlers/dataset-database-handlers-what-are-they) for the full list of supported handlers.
  </Accordion>

  <Accordion title="Disabling Authentication for Local Development">
    When running Cognee locally for development or testing, you can disable authentication so that API calls succeed without a bearer token. Because the two variables are combined with an `or` check at startup, **both** must be set to `false`:

    ```dotenv theme={null}
    REQUIRE_AUTHENTICATION=false
    ENABLE_BACKEND_ACCESS_CONTROL=false
    ```

    These values are read once when the server process starts, so you must restart the server after changing them.

    When authentication is disabled, unauthenticated requests are automatically served under a built-in default user (`default_user@example.com`). The relational database must be initialized before the first request so that this default user can be looked up or created.

    **Troubleshooting 401 errors after setting the variables**

    | Symptom                              | Cause                                | Fix                                                                                                           |
    | ------------------------------------ | ------------------------------------ | ------------------------------------------------------------------------------------------------------------- |
    | Still getting `401` on all endpoints | Only one variable was set to `false` | Set **both** `REQUIRE_AUTHENTICATION=false` and `ENABLE_BACKEND_ACCESS_CONTROL=false`                         |
    | `401` persists after editing `.env`  | Server not restarted                 | Restart the server — the variables are evaluated at import time                                               |
    | `500 Failed to create default user`  | Relational DB not initialized        | Call `cognee.prune.prune_system()` once, or let the server run its startup migrations before sending requests |

    <Warning>
      Only disable authentication in local or trusted environments. Leaving both variables `false` in a network-accessible deployment removes all access control.
    </Warning>
  </Accordion>
</AccordionGroup>

## Recommended Production Settings

<AccordionGroup>
  <Accordion title="Recommended Production Settings">
    ```dotenv theme={null}
    # Authentication
    REQUIRE_AUTHENTICATION=True
    FASTAPI_USERS_JWT_SECRET="<random-64-char-string>"
    JWT_LIFETIME_SECONDS=3600

    # API key security
    HASH_API_KEY=True

    # Multi-user isolation
    ENABLE_BACKEND_ACCESS_CONTROL=True

    # Prevent arbitrary file reads (set False for backend deployments)
    ACCEPT_LOCAL_FILE_PATH=False

    # Limit direct graph queries (optional — set False to restrict to semantic search)
    ALLOW_CYPHER_QUERY=False

    # Neo4j Aura credential encryption (only required when using neo4j_aura_dev handler)
    NEO4J_ENCRYPTION_KEY="<random-64-char-string>"
    ```

    <Info>
      For detailed instructions on the multi-user permission system (users, tenants, roles, and ACL), see [Cognee Permissions System](/core-concepts/multi-user-mode/permissions-system/overview).
    </Info>
  </Accordion>
</AccordionGroup>

<Columns cols={2}>
  <Card title="Permissions Setup" icon="lock" href="/setup-configuration/permissions">
    Enable dataset isolation and access control
  </Card>

  <Card title="Multi-User Mode" icon="users" href="/core-concepts/multi-user-mode/multi-user-mode-overview">
    Understand multi-tenant architecture
  </Card>
</Columns>
