Chroma-native Auth
Chroma offers built in authentication and authorization mechanisms to secure your Chroma instance.
Auth Disabled by Default
By default, Chroma does not require authentication. You must enable it manually. If you are deploying Chroma in a public-facing environment, it is highly recommended to enable authentication.
Auth needs the company of SSL/TLS
Authentication without encryption is insecure. If you are deploying Chroma in a public-facing environment, it is highly recommended that you add (SSL/TLS)[ssl-proxy.md].
Authentication
Chroma supports two types of authentication:
- Basic Auth - RFC 7617 compliant pre-emptive authentication with username and password credentials in Authorization header.
- Token Auth - Standard token-based auth with
AuthorizationorX-Chroma-Tokenheaders.
For each authentication method there are configurations in both client and server.
Basic Authentication
Server
Generate a password file with bcrypt hashed password:
1. docker run --rm --entrypoint echo httpd:2 "change_this_password" | htpasswd -iBc server.htpasswd user1
Multiple users
Chroma supports multiple users in the htpasswd file. You can add multiple users by running the command multiple times WITHOUT -c flag.
Environment variables:
1. export CHROMA_SERVER_AUTHN_CREDENTIALS_FILE="server.htpasswd"
2. export CHROMA_SERVER_AUTHN_PROVIDER="chromadb.auth.basic_authn.BasicAuthenticationServerProvider"
Running the server:
CLIDockerDocker Compose
1. export CHROMA_SERVER_AUTHN_CREDENTIALS_FILE="server.htpasswd"
2. export CHROMA_SERVER_AUTHN_PROVIDER="chromadb.auth.basic_authn.BasicAuthenticationServerProvider"
3. chroma run --path /chroma-data
1. docker run --rm -v ./server.htpasswd:/chroma/server.htpasswd \
2. -e CHROMA_SERVER_AUTHN_CREDENTIALS_FILE="server.htpasswd" \
3. -e CHROMA_SERVER_AUTHN_PROVIDER="chromadb.auth.basic_authn.BasicAuthenticationServerProvider" \
4. -p 8000:8000 \
5. chromadb/chroma:latest
Create a docker-compose.yaml with the following content:
1. networks:
2. net:
3. driver: bridge
4. services:
5. chromadb:
6. image: chromadb/chroma:latest
7. volumes:
8. - ./chromadb:/chroma/chroma
9. - ./server.htpasswd:/chroma/server.htpasswd
10. environment:
11. - IS_PERSISTENT=TRUE
12. - PERSIST_DIRECTORY=/chroma/chroma # this is the default path, change it as needed
13. - ANONYMIZED_TELEMETRY=${ANONYMIZED_TELEMETRY:-TRUE}
14. - CHROMA_SERVER_AUTHN_CREDENTIALS_FILE=server.htpasswd
15. - CHROMA_SERVER_AUTHN_PROVIDER=chromadb.auth.basic_authn.BasicAuthenticationServerProvider
16. ports:
17. - 8000:8000
18. networks:
19. - net
Run the following command to start the Chroma server:
1. docker compose -f docker-compose.yaml up -d
Is my config right?
If you have correctly configured the server you should see the following line in the server logs:
1. Starting component BasicAuthenticationServerProvider
Client
PythonJSGoJava
1. import chromadb
2. from chromadb.config import Settings
4. client = chromadb.HttpClient(
5. settings=Settings(
6. chroma_client_auth_provider="chromadb.auth.basic_authn.BasicAuthClientProvider",
7. chroma_client_auth_credentials="admin:admin")
8. )
10. # if everything is correctly configured the below should list all collections
11. client.list_collections()
1. // const {ChromaClient} = require("chromadb"); // CommonJS
2. import { ChromaClient } from "chromadb"; // ES Modules
3. const client = new ChromaClient({
4. url: "http://localhost:8000",
5. auth: {
6. provider: "basic",
7. credentials: "admin:admin",
8. }
9. });
1. package main
3. import (
4. "context"
5. "log"
6. chroma "github.com/amikos-tech/chroma-go"
7. "github.com/amikos-tech/chroma-go/types"
8. )
10. func main() {
11. client, err := chroma.NewClient(
12. chroma.WithBasePath("http://localhost:8000"),
13. chroma.WithAuth(types.NewBasicAuthCredentialsProvider("admin", "admin")),
14. )
15. if err != nil {
16. log.Fatalf("Error creating client: %s \n", err)
17. }
18. _, err = client.ListCollections(context.TODO())
19. if err != nil {
20. log.Fatalf("Error calling ListCollections: %s \n", err)
21. }
22. }
The below example shows auth with just headers. A more robust authentication mechanism is being implemented.
1. package tech.amikos;
3. import tech.amikos.chromadb.*;
4. import tech.amikos.chromadb.Collection;
6. import java.util.*;
8. public class Main {
9. public static void main(String[] args) {
10. try {
11. Client client = new Client(System.getenv("http://localhost:8000"));
12. client.setDefaultHeaders(new HashMap<>() {{
13. put("Authorization", "Basic " + Base64.getEncoder().encodeToString("admin:admin".getBytes()));
14. }});
15. // your code here
16. } catch (Exception e) {
17. System.out.println(e);
18. }
19. }
20. }
Testing with cURL
1. curl -v http://localhost:8000/api/v1/collections -u user1:change_this_password
Token Authentication
Server
Environment variables:
1. export CHROMA_SERVER_AUTHN_CREDENTIALS="chr0ma-t0k3n"
2. export CHROMA_SERVER_AUTHN_PROVIDER="chromadb.auth.token_authn.TokenAuthenticationServerProvider"
3. export CHROMA_AUTH_TOKEN_TRANSPORT_HEADER="Authorization" # or X-Chroma-Token
Auth Headers
Chroma supports two token transport headers:
Authorization(default) - the clients are expected to passAuthorization: Bearer <token>headerX-Chroma-Token- the clients are expected to passX-Chroma-Token: <token>header
The header can be configured via CHROMA_AUTH_TOKEN_TRANSPORT_HEADER environment variable.
Running the server:
CLIDockerDocker Compose
1. export CHROMA_SERVER_AUTHN_CREDENTIALS="chr0ma-t0k3n"
2. export CHROMA_SERVER_AUTHN_PROVIDER="chromadb.auth.token_authn.TokenAuthenticationServerProvider"
3. export CHROMA_AUTH_TOKEN_TRANSPORT_HEADER="Authorization"
4. chroma run --path /chroma-data
1. docker run --rm -e CHROMA_SERVER_AUTHN_CREDENTIALS="chr0ma-t0k3n" \
2. -e CHROMA_SERVER_AUTHN_PROVIDER="chromadb.auth.token_authn.TokenAuthenticationServerProvider" \
3. -e CHROMA_AUTH_TOKEN_TRANSPORT_HEADER="Authorization" \
4. -p 8000:8000 \
5. chromadb/chroma:latest
Create a docker-compose.yaml with the following content:
1. networks:
2. net:
3. driver: bridge
4. services:
5. chromadb:
6. image: chromadb/chroma:latest
7. volumes:
8. - ./chromadb:/chroma/chroma
9. - ./server.htpasswd:/chroma/server.htpasswd
10. environment:
11. - IS_PERSISTENT=TRUE
12. - PERSIST_DIRECTORY=/chroma/chroma # this is the default path, change it as needed
13. - ANONYMIZED_TELEMETRY=${ANONYMIZED_TELEMETRY:-TRUE}
14. - CHROMA_SERVER_AUTHN_CREDENTIALS="chr0ma-t0k3n"
15. - CHROMA_AUTH_TOKEN_TRANSPORT_HEADER="Authorization"
16. - CHROMA_SERVER_AUTHN_PROVIDER=chromadb.auth.token_authn.TokenAuthenticationServerProvider
17. ports:
18. - 8000:8000
19. networks:
20. - net
Run the following command to start the Chroma server:
1. docker compose -f docker-compose.yaml up -d
Is my config right?
If you have correctly configured the server you should see the following line in the server logs:
1. Starting component TokenAuthenticationServerProvider
Client
PythonJSGoJava
1. import chromadb
2. from chromadb.config import Settings
4. client = chromadb.HttpClient(
5. settings=Settings(
6. chroma_client_auth_provider="chromadb.auth.token_authn.TokenAuthClientProvider",
7. chroma_client_auth_credentials="chr0ma-t0k3n",
8. chroma_client_auth_token_transport_header="Authorization"
9. )
10. )
12. # if everything is correctly configured the below should list all collections
13. client.list_collections()
1. // const {ChromaClient} = require("chromadb"); // CommonJS
2. import { ChromaClient } from "chromadb"; // ES Modules
3. const client = new ChromaClient({
4. url: "http://localhost:8000",
5. auth: {
6. provider: "token",
7. credentials: "chr0ma-t0k3n",
8. }
9. });
1. package main
3. import (
4. "context"
5. "log"
6. chroma "github.com/amikos-tech/chroma-go"
7. "github.com/amikos-tech/chroma-go/types"
8. )
10. func main() {
11. client, err := chroma.NewClient(
12. chroma.WithBasePath("http://localhost:8000"),
13. chroma.WithAuth(types.NewTokenAuthCredentialsProvider("chr0ma-t0k3n", types.AuthorizationTokenHeader)),
14. )
15. if err != nil {
16. log.Fatalf("Error creating client: %s \n", err)
17. }
18. _, err = client.ListCollections(context.TODO())
19. if err != nil {
20. log.Fatalf("Error calling ListCollections: %s \n", err)
21. }
22. }
The example below shows authorization with just headers. A more robust auth mechanism is under implementation.
1. package tech.amikos;
3. import tech.amikos.chromadb.*;
4. import tech.amikos.chromadb.Collection;
6. import java.util.*;
8. public class Main {
9. public static void main(String[] args) {
10. try {
11. Client client = new Client(System.getenv("http://localhost:8000"));
12. client.setDefaultHeaders(new HashMap<>() {{
13. put("Authorization", "Bearer chr0ma-t0k3n");
14. }});
15. // your code here
16. } catch (Exception e) {
17. System.out.println(e);
18. }
19. }
20. }
Testing with cURL
1. curl -v http://localhost:8000/api/v1/collections -H "Authorization: Bearer chr0ma-t0k3n"
Authorization
Coming soon!
September 6, 2024
