Skip to main content
Applies to: Embedded ❌, Enterprise ✅ A deployment authenticates each request over a db:// connection before authorization decides what it may do. Choose one of these methods:
  • API keys: a long-lived shared secret passed as api_key on connect. Works in every SDK.
  • OAuth 2.0: short-lived bearer tokens obtained from your identity provider, refreshed automatically by the client.
OAuth is the recommended option when you want to rotate credentials centrally, plug into an existing identity provider, or run on Azure with managed identities so no secret material lives on the client.

API key

Pass the API key from your Enterprise tenant on connect. This works with both the synchronous and asynchronous Python clients, as well as TypeScript and Rust. Load the key from an environment variable or secret manager.
For Rust, enable the remote feature on the lancedb dependency to use API key or OAuth authentication. See Database for the connection options.

OAuth

The async Python, TypeScript, and Rust clients can obtain bearer tokens from an OIDC issuer and attach them to every request. Token acquisition, caching, and refresh are handled inside the client. Your application code only provides the configuration. A deployment accepts these tokens only when its administrator has configured it with your identity provider. Ask them for the issuer URL, client ID, scopes, and any resource or audience required by the provider. For Authorization Code, register the loopback redirect URI with the provider. For Device Code, enable the provider’s device authorization grant for your application.
In Python, OAuth is supported through lancedb.connect_async. The synchronous connect entry point continues to use API key authentication for db:// URIs. In TypeScript, lancedb.connect accepts oauthConfig directly. In Rust, use .oauth_config(config) on the connection builder.

Supported flows

OAuthFlowType (Python and TypeScript) or OAuthFlow (Rust) selects how the client acquires tokens:

Configure OAuth

Build an OAuth config and pass it on connect. Use oauth_config in Python and Rust, and oauthConfig in TypeScript.
For Azure workloads with access to IMDS, use a managed identity instead of a client secret:
managed_identity_client_id / managedIdentityClientId selects a user-assigned identity. Omit it for a system-assigned identity. The required client_id / clientId field does not select the Azure managed identity. In Rust, set the client_id inside OAuthFlow::AzureManagedIdentity to Some(...) for a user-assigned identity, or None for a system-assigned identity. The top-level OAuthConfig::client_id is the application client ID. For interactive sign-in, configure Authorization Code or Device Code. The authorization URL or device verification instructions are written to standard error. Authorization Code also tries to open a browser and listens for the callback at http://127.0.0.1:8400/callback by default. Register that redirect URI with your identity provider. Public clients can omit client_secret; request a refresh token from your provider (often by including offline_access) if you want to reuse the session.
With DEVICE_CODE / DeviceCode / OAuthFlow::DeviceCode(DeviceCodeOptions::new()), the same configuration and connection calls apply; only the flow value changes. Device Code sends no PKCE parameters by default. For a provider that requires S256 PKCE on device grants, Rust callers can select OAuthFlow::DeviceCode(DeviceCodeOptions::new().use_pkce(true)) (import DeviceCodeOptions from lancedb::remote). This option is currently Rust-only. Enable it only when the provider supports the extension; a failed PKCE request is not retried without PKCE.

Reuse an interactive session

By default, tokens stay in process memory. Set token_cache / tokenCache for Authorization Code or Device Code to keep refresh tokens across process restarts. Only refresh tokens are persisted; access tokens and client secrets are not written to the cache. Set cache_dir / cacheDir to choose the directory, or leave it unset to use the platform cache directory. Your identity provider must issue a refresh token for a later process to sign in without prompting again. Use OAuthSession with the same config to log in before connecting, inspect whether a refresh token is cached, or remove the local cached credential:
login() runs the interactive flow even when a session is cached. logout() removes the local cache entry; it does not revoke the provider’s token or end a browser sign-in. OAuthSession requires a persistent cache and supports only Authorization Code and Device Code. A cache is unused for Client Credentials and rejected for Azure Managed Identity.

Configuration reference

The shared configuration below is available in all three SDKs; device-code PKCE is a Rust-only option through DeviceCodeOptions. Python and Rust use snake_case field names; TypeScript uses camelCase. In Rust, set optional OAuthConfig fields to Some(value) or None. Configure redirect_uri, callback_port, and use_pkce through the builder methods on AuthorizationCodeOptions, and select a managed identity through OAuthFlow::AzureManagedIdentity { client_id: ... }. TokenCacheOptions also accepts cache_dir / cacheDir to select a cache directory and lock_timeout_secs / lockTimeoutSecs to set the wait for a cross-process refresh lock (default 30 seconds). In Rust, use the TokenCacheOptions::cache_dir(...) and TokenCacheOptions::lock_timeout_secs(...) builder methods. Token endpoint authentication uses Some(ClientAuthMethod::None), Some(ClientAuthMethod::ClientSecretBasic), or Some(ClientAuthMethod::ClientSecretPost); None selects the default.
Treat the client secret like any other production credential. Load it from a secret manager or environment variable rather than committing it to source control. All three SDKs deliberately omit the secret from their debug/repr output so accidental log lines do not expose the value.
LanceDB Embedded has nothing to authenticate to: your process opens the files directly, and the object store’s own credentials are the only gate.