Authentication
Weaviate offers an optional authentication scheme using API keys and OpenID Connect (OIDC), which can enable various authorizations levels.
When authentication is disabled, all anonymous requests will be granted access.
In this documentation, we cover all scenarios for your convenience:
- Configuring Weaviate and the client for API key use
- Configuring Weaviate and the client for OIDC
- Configuring Weaviate for anonymous access
Note that API key and OIDC authentication can be both enabled at the same time.
For most use cases, the API key option offers a balance between security and ease of use. Give it a try first, unless you have specific requirements that necessitate a different approach.
See this page for how to set up values.yaml
for authentication & authorization.
WCD authentication
Weaviate Cloud (WCD) instances are pre-configured for API key authentication.
API key
To configure Weaviate for API key-based authentication, add the following environment variables to your configuration file.
An example docker-compose.yml
file looks like this:
services:
weaviate:
...
environment:
...
# Enables API key authentication.
AUTHENTICATION_APIKEY_ENABLED: 'true'
# List one or more keys, separated by commas. Each key corresponds to a specific user identity below.
AUTHENTICATION_APIKEY_ALLOWED_KEYS: 'jane-secret-key,ian-secret-key'
# List one or more user identities, separated by commas. Each identity corresponds to a specific key above.
AUTHENTICATION_APIKEY_USERS: 'jane@doe.com,ian-smith'
The example associates API keys and users.
API key | User |
---|---|
jane-secret-key | jane@doe.com |
ian-secret-key | ian-smith |
n
APIKEY_ALLOWED_KEYS vs n
APIKEY_USERSThere are two options for configuring the number of keys and users:
- Option 1: There is exactly one user specified and any number of keys (all keys will end up using the same user).
- Option 2: The lengths match, then key
n
will map to usern
.
These users' permissions will be determined by the authorization settings. Below is one such example configuration.
services:
weaviate:
...
environment:
...
AUTHORIZATION_ADMINLIST_ENABLED: 'true'
AUTHORIZATION_ADMINLIST_USERS: 'jane@doe.com,john@doe.com'
AUTHORIZATION_ADMINLIST_READONLY_USERS: 'ian-smith,roberta@doe.com'
The example associates permissions with users.
User | User type | Permission |
---|---|---|
jane-secret-key | Admin | Read, write |
john@doe.com | Admin | Read, write |
ian-smith | Read Only | Read |
roberta@doe.com | Read Only | Read |
In the example, jane-secret-key
is an admin
key, and ian-secret-key
is a read-only
key.
You might notice that the authorization list includes john@doe.com
and roberta@doe.com
. Weaviate supports a combination of API key and OIDC-based authentication. Thus, the additional users might be OIDC users.
API key: Client-side usage
When you use an API key to authenticate to Weaviate, add the API key in the request header.
The format is: Authorization: Bearer WEAVIATE_API_KEY
. Replace WEAVIATE_API_KEY
with the API key for your Weaviate instance.
The cURL command looks like this:
curl https://${WEAVIATE_INSTANCE_URL}/v1/meta -H "Authorization: Bearer ${WEAVIATE_API_KEY}" | jq
For details on using a client library, follow one of these links:
OIDC
OIDC authentication involves three parties.
- A user who wants to access a resource.
- An identity provider (a.k.a token issuer) (e.g. Okta, Microsoft, or WCD) that authenticates the user and issues tokens.
- A resource (in this case, Weaviate) who validates the tokens to rely on the identity provider's authentication.
For example, a setup may involve a Weaviate instance as a resource, Weaviate Cloud (WCD) as an identity provider, and the Weaviate client acting on behalf of the user. This document attempts to provide some perspective from each one to help you use Weaviate with authentication.
More about OIDC
With OpenID Connect (based on OAuth2), an external identity provider and token issuer ('token issuer' hereafter) is responsible for managing users.
OIDC authentication requires obtaining a valid token from the token issuer so that it can be sent in the header of any request to Weaviate. This applies to both REST and GraphQL requests.
When Weaviate receives a token (JSON Web Token or JWT), it verifies that it was indeed signed by the configured token issuer. If the signature is correct, all contents of the token are trusted, which authenticates the user based on the information in the token.
OIDC: Server-side
Any "OpenID Connect" compatible token issuer that implements OpenID Connect Discovery is compatible with Weaviate.
Configure Weaviate as the resource
Configuring the OIDC token issuer is outside the scope of this document, but here are a few options as a starting point:
For simple use-cases such as for a single user, you can use Weaviate Cloud (WCD) as the OIDC token issuer. To do so:
- Make sure you have a WCD account (you can sign up here).
- In the Docker Compose file (e.g.
docker-compose.yml
), specify:https://auth.wcs.api.weaviate.io/auth/realms/SeMI
as the issuer (inAUTHENTICATION_OIDC_ISSUER
),wcs
as the client id (inAUTHENTICATION_OIDC_CLIENT_ID
), and- enable the adminlist (
AUTHORIZATION_ADMINLIST_ENABLED: 'true'
) and add your WCD account email as the user (inAUTHORIZATION_ADMINLIST_USERS
) . email
as the username claim (inAUTHENTICATION_OIDC_USERNAME_CLAIM
).
If you need a more customizable setup you can use commercial OIDC providers like Okta.
As another alternative, you can run your own OIDC token issuer server, which may be the most complex but also configurable solution. Popular open-source solutions include Java-based Keycloak and Golang-based dex.
By default, Weaviate validates that the token includes a specified client id in the audience claim. If your token issuer does not support this feature, you can turn it off as outlined in the configuration section below.
Set configuration options
To use OpenID Connect (OIDC), the respective environment variables must be correctly configured in the configuration yaml for Weaviate.
As of November 2022, we were aware of some differences in Microsoft Azure's OIDC implementation compared to others. If you are using Azure and experiencing difficulties, this external blog post may be useful.
The OIDC-related Docker Compose environment variables are shown below. For configuration details, see the inline-yaml comments:
services:
weaviate:
...
environment:
...
# enabled (optional - defaults to false) turns OIDC auth on. All other fields in
# this section will only be validated if enabled is set to true.
AUTHENTICATION_OIDC_ENABLED: 'true'
# issuer (required) tells weaviate how to discover the token issuer. This
# endpoint must implement the OpenID Connect Discovery spec, so that weaviate
# can retrieve the issuer's public key.
#
# The example URL below uses the path structure commonly found with keycloak
# where an example realm 'my-weaviate-usecase' was created. The exact
# path structure depends on the token issuer. See the token issuer's documentation
# about which endpoint implements OIDC Discovery.
AUTHENTICATION_OIDC_ISSUER: 'http://my-token-issuer/auth/realms/my-weaviate-usecase'
# client_id (required unless skip_client_id_check is set to true) tells
# Weaviate to check for a particular OAuth 2.0 client_id in the audience claim.
# This is to prevent that a token which was signed by the correct issuer
# but never intended to be used with Weaviate can be used for authentication.
#
# For more information on what clients are in OAuth 2.0, see
# https://tools.ietf.org/html/rfc6749#section-1.1
AUTHENTICATION_OIDC_CLIENT_ID: 'my-weaviate-client'
# username_claim (required) tells Weaviate which claim in the token to use for extracting
# the username. The username will be passed to the authorization plugin.
AUTHENTICATION_OIDC_USERNAME_CLAIM: 'email'
# skip_client_id_check (optional, defaults to false) skips the client_id
# validation in the audience claim as outlined in the section above.
# Not recommended to set this option as it reduces security, only set this
# if your token issuer is unable to provide a correct audience claim
AUTHENTICATION_OIDC_SKIP_CLIENT_ID_CHECK: 'false'
# scope (optional) these will be used by clients as default scopes for authentication
AUTHENTICATION_OIDC_SCOPES: ''
Get the Weaviate OpenID endpoint
If you have OIDC authentication enabled, you can obtain Weaviate's OIDC configuration from the following endpoint:
curl ${WEAVIATE_INSTANCE_URL}/v1/.well-known/openid-configuration
Edit ${WEAVIATE_INSTANCE_URL} to provide your instance URL.
OIDC: Client-side
The OIDC standard allows for many different methods (flows) of obtaining tokens. The appropriate method can vary depending on your situation, including configurations at the token issuer, and your requirements.
OIDC authentication flows are outside the scope of this documentation, but here are some options to consider:
- Use the
client credentials flow
for machine-to-machine authorization. (Note that this authorizes an app, not a user.)- Validated using Okta and Azure as identity providers; GCP does not support client credentials grant flow (as of December 2022).
- Weaviate's Python client directly supports this method.
- Client credential flows usually do not come with a refresh token and the credentials are saved in the respective clients to acquire a new access token on expiration of the old one.
- Use the
resource owner password flow
for trusted applications like Weaviate Cloud. - Use
hybrid flow
if Azure is your token issuer or if you would like to prevent exposing passwords.
Support for Weaviate clients
If Weaviate core is configured to use the client credentials grant
flow or the resource owner password flow
, a Weaviate client can instantiate a connection to Weaviate core that incorporates the authentication flow.
- Python Client v4
- Python Client v3
- JS/TS Client v3
- JS/TS Client v2
- Go
- Java
import os
import weaviate
from weaviate.classes.init import Auth
# Best practice: store your credentials in environment variables
weaviate_url = os.environ["WEAVIATE_URL"]
weaviate_username = os.environ["WCD_USERNAME"]
weaviate_password = os.environ["WCD_PASSWORD"]
client = weaviate.connect_to_weaviate_cloud(
cluster_url=weaviate_url, # Replace with your Weaviate Cloud URL
auth_credentials=Auth.client_password(
username=weaviate_username, # Your Weaviate Cloud username
password=weaviate_password # Your Weaviate Cloud password
)
)
# Set these environment variables
# WEAVIATE_USER your Weaviate OIDC username
# WEAVIATE_PWD your Weaviate OIDC password
import os
import weaviate
resource_owner_config = weaviate.AuthClientPassword(
username = os.getenv("WEAVIATE_USER"),
password = os.getenv("WEAVIATE_PWD"),
)
# Use OIDC credentials to authenticate
client = weaviate.Client("http://localhost:8080", auth_client_secret=resource_owner_config)
// Set these environment variables
// WEAVIATE_USER your Weaviate OIDC username
// WEAVIATE_PWD your Weaviate OIDC password
// WEAVIATE_URL your Weaviate instance
import weaviate, { WeaviateClient } from 'weaviate-client';
const client = await weaviate.connectToCustom(
{
httpHost: process.env.WEAVIATE_URL, // URL only, no http prefix
httpPort: 8080,
grpcHost: process.env.WEAVIATE_GPC_URL,
grpcPort: 50051,
grpcSecure: false,
httpSecure: false,
authCredentials: new weaviate.AuthUserPasswordCredentials({
username: process.env.WEAVIATE_USER,
password: process.env.WEAVIATE_PWD,
}),
headers: {
'X-Cohere-Api-Key': process.env.COHERE_API_KEY || ''
}
})
console.log(client)
// Set these environment variables
// WEAVIATE_USER your Weaviate OIDC username
// WEAVIATE_PWD your Weaviate OIDC password
// WEAVIATE_URL your Weaviate instance
import weaviate, { AuthUserPasswordCredentials } from 'weaviate-ts-client';
const client = weaviate.client({
scheme: "https",
host: "WEAVIATE_URL",
authClientSecret: new AuthUserPasswordCredentials({
username: process.env.WEAVIATE_USER,
password: process.env.WEAVIATE_PWD,
})
});
console.log(client)
// Set these environment variables
// WEAVIATE_USER your Weaviate OIDC username
// WEAVIATE_PWD your Weaviate OIDC password
cfg := weaviate.Config{
Host: "weaviate.example.com",
Scheme: "http",
AuthConfig: auth.ResourceOwnerPasswordFlow{
Username: os.Getenv("WEAVIATE_USER"),
Password: os.Getenv("WEAVIATE_PWD"),
Scopes: []string{"offline_access"}, // optional, depends on the configuration of your identity provider (not required with WCD)
},
Headers: nil,
}
client, err := weaviate.NewClient(cfg)
if err != nil{
fmt.Println(err)
}
// Set these environment variables
// WEAVIATE_USER your Weaviate OIDC username
// WEAVIATE_PWD your Weaviate OIDC password
import io.weaviate.client.Config;
import io.weaviate.client.WeaviateAuthClient;
Config config = new Config("http", "localhost:8080");
WeaviateAuthClient.clientPassword(
config,
System.getenv("WEAVIATE_USER"),
System.getenv("WEAVIATE_PWD"),
Arrays.asList("scope1", "scope2") // optional, depends on the configuration of your identity provider (not required with WCD)
);
For details on using a client library, follow one of these links:
Get and pass tokens manually
Manually obtaining and passing tokens
For cases or workflows where you may wish to manually obtain a token, we outline below the steps to do so, for the resource owner password flow and hybrid flow.
Resource owner password flow
- Send a GET request to
WEAVIATE_INSTANCE_URL/v1/.well-known/openid-configuration
to fetch Weaviate's OIDC configuration (wv_oidc_config
). Replace WEAVIATE_INSTANCE_URL with your instance URL. - Parse the
clientId
andhref
fromwv_oidc_config
. - Send a GET request to
href
to fetch the token issuer's OIDC configuration (token_oidc_config
). - If
token_oidc_config
includes the optionalgrant_types_supported
key, check thatpassword
is in the list of values.- If
password
is not in the list of values, the token issuer is likely not configured forresource owner password flow
. You may need to reconfigure the token issuer or use another method. - If the
grant_types_supported
key is not available, you may need to contact the token issuer to see ifresource owner password flow
is supported.
- If
- Send a POST request to the
token_endpoint
oftoken_oidc_config
with the body:{"grant_type": "password", "client_id": client_id, "username": USERNAME, "password": PASSWORD
. ReplaceUSERNAME
andPASSWORD
with the actual values.
- Parse the response (
token_resp
), and look foraccess_token
intoken_resp
. This is your Bearer token.
Hybrid flow
- Send a GET request to
WEAVIATE_INSTANCE_URL/v1/.well-known/openid-configuration
to fetch Weaviate's OIDC configuration (wv_oidc_config
). Replace WEAVIATE_INSTANCE_URL with your instance URL. - Parse the
clientId
andhref
fromwv_oidc_config
- Send a GET request to
href
to fetch the token issuer's OIDC configuration (token_oidc_config
) - Construct a URL (
auth_url
) with the following parameters, based onauthorization_endpoint
fromtoken_oidc_config
. This will look like the following:{authorization_endpoint}
?client_id={clientId}
&response_type=code%20id_token&response_mode=fragment&redirect_url={redirect_url}
&scope=openid&nonce=abcd- the
redirect_url
must have been pre-registered with your token issuer.
- Go to the
auth_url
in your browser, and log in if prompted. If successful, the token issuer will redirect the browser to theredirect_url
, with additional parameters that include anid_token
parameter. - Parse the
id_token
parameter value. This is your Bearer token.
Code example
This example demonstrate how to obtain an OIDC token.
import requests
import re
url = "http://localhost:8080" # <-- Replace with your actual Weaviate URL
# Get Weaviate's OIDC configuration
weaviate_open_id_config = requests.get(url + "/v1/.well-known/openid-configuration")
if weaviate_open_id_config.status_code == "404":
print("Your Weaviate instance is not configured with openid")
response_json = weaviate_open_id_config.json()
client_id = response_json["clientId"]
href = response_json["href"]
# Get the token issuer's OIDC configuration
response_auth = requests.get(href)
if "grant_types_supported" in response_auth.json():
# For resource owner password flow
assert "password" in response_auth.json()["grant_types_supported"]
username = "username" # <-- Replace with the actual username
password = "password" # <-- Replace with the actual password
# Construct the POST request to send to 'token_endpoint'
auth_body = {
"grant_type": "password",
"client_id": client_id,
"username": username,
"password": password,
}
response_post = requests.post(response_auth.json()["token_endpoint"], auth_body)
print("Your access_token is:")
print(response_post.json()["access_token"])
else:
# For hybrid flow
authorization_url = response_auth.json()["authorization_endpoint"]
parameters = {
"client_id": client_id,
"response_type": "code%20id_token",
"response_mode": "fragment",
"redirect_url": url,
"scope": "openid",
"nonce": "abcd",
}
# Construct 'auth_url'
parameter_string = "&".join([key + "=" + item for key, item in parameters.items()])
response_auth = requests.get(authorization_url + "?" + parameter_string)
print("To login, open the following url with your browser:")
print(authorization_url + "?" + parameter_string)
print(
"After the login you will be redirected, the token is the 'id_token' parameter of the redirection url."
)
# You could use this regular expression to parse the token
resp_txt = "Redirection URL"
token = re.search("(?<=id_token=).+(?=&)", resp_txt)[0]
print("Set as bearer token in the clients to access Weaviate.")
Token lifetime
The token has a configurable expiry time that is set by the token issuer. We suggest establishing a workflow to periodically obtain a new token before expiry.
Add a Bearer to a Request
When you use an API key to authenticate to Weaviate, add the API key in the request header.
The format is: Authorization: Bearer WEAVIATE_API_KEY
. Replace WEAVIATE_API_KEY
with the API key for your Weaviate instance.
For example, the cURL command looks like this:
curl https://localhost:8080/v1/objects -H "Authorization: Bearer ${WEAVIATE_API_KEY}" | jq
For details on using a client library, follow one of these links:
Anonymous access
By default, Weaviate is configured to accept requests without any authentication headers or parameters. Users that send requests without explicit authentication are authenticated as user: anonymous
.
You can use the authorization plugin to specify which
permissions to apply to anonymous users. If anonymous access is disabled altogether,
any request without an allowed authentication scheme returns 401 Unauthorized
.
Configuration
Anonymous access can be enabled or disabled in the configuration yaml using the environment variable shown below:
services:
weaviate:
...
environment:
...
AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: 'true'
How to use
Send REST requests to Weaviate without any additional authentication headers or parameters.
Questions and feedback
If you have any questions or feedback, let us know in the user forum.