Authentication and authorization
Authentication and authorization are closely related concepts, and sometimes abbreviated as AuthN
and AuthZ
. Authentication (AuthN
) is the process of verifying the identity of a user, while authorization (AuthZ
) is the process of determining what permissions the user has.
Authentication
Weaviate controls access through user authentication via API keys or OpenID Connect (OIDC), with an option for anonymous access. Users can then be assigned different authorization levels, as shown in the diagram below.
For example, a user logging in with the API key jane-secret
may be granted administrator permissions, while another user logging in with the API key ian-secret
may be granted read-only permissions.
In summary, Weaviate allows the following authentication methods:
- API key
- OpenID Connect (OIDC)
- Anonymous access (no authentication, strongly discouraged except for development or evaluation)
Note that API key and OIDC authentication can be both enabled at the same time.
The way to configure authentication differs by your deployment method, depending on whether you are running Weaviate in Docker or Kubernetes. Below, we provide examples for both.
For Weaviate Cloud (WCD) instances, authentication is pre-configured with OIDC and API key access. You can authenticate against Weaviate with your WCD credentials using OIDC, or with API keys.
API key
For more details on how to work with API keys in Weaviate, check out the authentication guide.
We recommend using a client library to authenticate against Weaviate. See How-to: Connect pages for more information.
OIDC
For more details on how to work with OIDC authentication in Weaviate, check out the authentication guide.
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 Database is configured to use the client credentials grant
flow or the resource owner password flow
, a Weaviate client can instantiate a connection to Weaviate Database 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)
);
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
Authorization
Weaviate provides differentiated access through authorization levels, based on the user's authentication status. A user can be granted admin permission, read-only permission, or no permission at all. From v1.29.0
, Weaviate also supports Role-Based Access Control (RBAC) for more fine-grained control over user permissions.
The following diagram illustrates the flow of a user request through the authentication and authorization process:
The following authorization schemes are available in Weaviate:
In the Admin list authorization scheme, anonymous users can be granted permissions.
The way to configure authorization differs by your deployment method, depending on whether you are running Weaviate in Docker or Kubernetes. Below, we provide examples for both.
Further resources
- Configuration: Authentication
- Configuration: Authorization
- Configuration: Environment variables - Authentication and Authorization
Questions and feedback
If you have any questions or feedback, let us know in the user forum.