Back to Chroma

Chroma Authentication

examples/basic_functionality/auth.ipynb

1.5.97.2 KB
Original Source

Chroma Authentication

This tutorial aims to explain how authentication can be setup in Chroma.

Important: The concept of authentication is only applicable to Client/Server deployments. If you are using Chroma in a standalone mode, authentication is not applicable.

Concepts

Architecture Overview

Authentication Flow (Sequence)

The authentication sequence is applied for every request. It is important to understand that credential computation or retrieval (e.g. from external auth providers) is only done once for the first authenticated request. Subsequent requests will use the same credentials.

The authentication flow is as follows:

Preemptive Authentication

In its current release the authentication in Chroma works in a preemptive mode. This means that the client is responsible for sending the authentication information on every request. The server will not challenge the client for authentication.

Warning: There are security risks involved with preemptive authentication in that the client might unintentionally send credentials to malicious or unintended server. When deploying authentication users are encouraged to use HTTPS (always verify server certs), to use secure providers (e.g. JWT) and apply good security practices.

Authentication Provider

Authentication in Chroma is handled by Authentication Providers. Providers are pluggable modules that allow Chroma to abstract the authentication mechanism from the rest of the system.

Chroma ships with the following build-in providers:

  • Basic authentication
  • Token-based authentication

Client-side Authentication

Client-side authentication refers to the process of preparing and communicating credentials information on the client-side and sending that information the Chroma server.

Server-side Authentication and Authorization

  • Server-side authentication means validating a request's credentials and identifying the user who sent it.
  • Server-side authorization means checking whether the identity associated with a request is allowed to make the request. This depends on authentication, since it depends on knowing the identity of the requestor.

Configuration

Server Configuration

In order for the server to provide authentication and authorization., it needs several pieces of information.

  • CHROMA_SERVER_AUTHN_PROVIDER - Configures which authentication provider class to use. In this case we are using chromadb.auth.basic_authn.BasicAuthenticationServerProvider. This authentication provider expects requests to have a header of the form {"Authorization": "Basic <base64-encoded username:password>"}.
  • CHROMA_SERVER_AUTHN_CREDENTIALS_FILE - The path to the credentials file for the authentication provider. As you'll see below, we will put these credentials in ./server.htpasswd.
  • CHROMA_SERVER_AUTHN_CREDENTIALS - Instead of a file, you can pass authentication configuration directly. We do not recommend this but it is suitable for testing and certain deployment environments.

Client Configuration

Similarly on the client side we need to provide the following configuration parameters:

  • CHROMA_CLIENT_AUTH_PROVIDER - Configures which authentication provider class to use. In this case we are using chromadb.auth.basic_authn.BasicAuthClientProvider, which is built to work well with the server-side BasicAuthenticationServerProvider.
  • CHROMA_CLIENT_AUTH_CREDENTIALS - Auth credentials to be included as headers in each request to Chroma. In this case we are using admin:admin.

Setting Up

Before You Begin

Make sure you have either chromadb or chromadb-client installed. You can do that by running the following command:

bash
pip install chromadb

or

bash
pip install chromadb-client

Make sure Chroma Server is running. Use one of the following methods to start the server:

From the command line:

Note: The below options will configure the server to use Basic Authentication with the username admin and password admin.

bash
export CHROMA_USER=admin
export CHROMA_PASSWORD=admin
docker run --rm --entrypoint htpasswd httpd:2 -Bbn ${CHROMA_USER} ${CHROMA_PASSWORD} > server.htpasswd
CHROMA_SERVER_AUTHN_CREDENTIALS_FILE="./server.htpasswd" \
CHROMA_SERVER_AUTHN_PROVIDER="chromadb.auth.basic_authn.BasicAuthenticationServerProvider" \
uvicorn chromadb.app:app --workers 1 --host 0.0.0.0 --port 8000  --proxy-headers --log-config log_config.yml

With Docker Compose:

Note: You need to clone the git repository first and run the command from the repository root.

bash
export CHROMA_USER=admin
export CHROMA_PASSWORD=admin
docker run --rm --entrypoint htpasswd httpd:2 -Bbn ${CHROMA_USER} ${CHROMA_PASSWORD} > server.htpasswd
cat << EOF > .env
CHROMA_SERVER_AUTH_CREDENTIALS_FILE="/chroma/server.htpasswd"
CHROMA_SERVER_AUTH_PROVIDER="chromadb.auth.basic_authn.BasicAuthenticationServerProvider"
EOF
docker-compose up -d --build 

Basic Authentication

python
import chromadb
from chromadb import Settings

client = chromadb.HttpClient(
    settings=Settings(chroma_client_auth_provider="chromadb.auth.basic_authn.BasicAuthClientProvider",
                      chroma_client_auth_credentials="admin:admin"))
client.heartbeat()  # this should work with or without authentication - it is a public endpoint

client.get_version()  # this should work with or without authentication - it is a public endpoint

client.list_collections()  # this is a protected endpoint and requires authentication


Verifying Authentication (Negative Test)

python
# Try to access a protected endpoint without authentication
import sys

client = chromadb.HttpClient()
try:
    client.list_collections()
except Exception as e:
    if "Unauthorized" in str(e):
        print("As expected, you are not authorized to access protected endpoints.", file=sys.stderr)
    else:
        raise e

Token Authentication

Chroma also ships with support for authentication via opaque tokens. To use this, use CHROMA_SERVER_AUTHN_PROVIDER="chromadb.auth.token_authn.TokenAuthenticationServerProvider". The token authentication provider expects a configuration file containing one or more users, each of which must have one or more tokens. See the bottom of chroma/examples/basic_functionality/authz/authz.yaml for an example.

You may also pass a single token to the TokenAuthenticationServerProvider. If you do so, it will only allow requests containing exactly that token. Example:

CHROMA_SERVER_AUTHN_PROVIDER="chromadb.auth.token_authn.TokenAuthenticationServerProvider"
CHROMA_SERVER_AUTHN_CREDENTIALS="test-token"

Default Token (Authorization with Bearer)

python
import chromadb
from chromadb import Settings

# Adds a header {"Authorization": "Bearer test-token"} to all requests
client = chromadb.HttpClient(
    settings=Settings(chroma_client_auth_provider="token", chroma_client_auth_credentials="test-token"))
client.heartbeat()  # this should work with or without authentication - it is a public endpoint

client.get_version()  # this should work with or without authentication - it is a public endpoint

client.list_collections()  # this is a protected endpoint and requires authentication