Adapter Authentication System
Relevant source files
The following files were used as context for generating this wiki page:The Adapter Authentication System is a specialized framework within dbt-core designed to encode and manage the complex authentication semantics required for various database adapters. Unlike a generic configuration parser, this system prioritizes semantic correctness and preserves compatibility-sensitive behaviors through a strictly defined Intermediate Representation (IR). It ensures that authentication inputs—such as tokens, OAuth credentials, and host information—are interpreted accurately across different platforms and engines.
The system is built on a zero-copy, borrowed-data design to avoid behavior regressions caused by early normalization or unnecessary owned allocations. By preserving the original shape of input data (e.g., distinguishing between a boolean true and a string "true"), it maintains the high-fidelity required for internal systems and platform stability.
Sources: crates/dbt-auth/AGENTS.md:1-12, crates/dbt-auth/CLAUDE.md:1-12
Core Design Principles and Invariants
The authentication system adheres to several technical invariants to prevent silent failures in authentication flows.
Zero-Copy and Borrowed Data
Authentication parsing and IR are designed to use borrowed data types such as &str and Option<&str> whenever possible. Cow<'a, str> is only utilized when normalization is explicitly required. This design prevents the loss of important distinctions in input data that can occur when widening ownership to String.
Sources: crates/dbt-auth/AGENTS.md:20-35, crates/dbt-auth/CLAUDE.md:20-35
Semantic Accessors
Config accessors are chosen based on the required semantic behavior of the input field:
get_str: Requires the field to be an actual YAML string.get_string: Allows the field to originate from numbers or booleans, which are then normalized to text.
Replacing get_string with get_str is considered a behavior regression unless intentionally narrowing the accepted input shapes.
Sources: crates/dbt-auth/AGENTS.md:46-58, crates/dbt-auth/CLAUDE.md:46-58
Late Normalization
Values are preserved in their original form for as long as possible. String conversion and owned allocations occur only at the final boundary where a downstream API (such as a database driver or REST client) requires it.
Sources: crates/dbt-auth/AGENTS.md:37-44, crates/dbt-auth/CLAUDE.md:37-44
Authentication Flow and IR Resolution
The system utilizes an internal pipeline to resolve raw configuration into a platform-specific AuthIR.
This diagram illustrates the resolution logic for Databricks authentication, where a pre-minted token takes precedence over OAuth fields to support specific platform flows like dbt Studio U2M.
Sources: crates/dbt-auth/src/databricks/mod.rs:88-120
Implementation: Databricks Authentication
The Databricks implementation supports multiple authentication families, represented by the DatabricksAuthIR enum.
| Auth Family | Implementation | Required Fields |
|---|---|---|
| OAuth M2M | Service Principal authentication | client_id, client_secret |
| Browser OAuth | External browser-based login | client_id (optional) |
| Token (PAT) | Personal Access Token | token |
Auth Type Precedence
Even when auth_type is set to oauth, the presence of a token in the configuration will cause the system to short-circuit to Token (PAT) authentication. This is critical for supporting Cloud-side handshakes where the access token is forwarded alongside the app credentials.
Sources: crates/dbt-auth/src/databricks/mod.rs:20-86, crates/dbt-adapter/src/python/databricks/api_client.rs:32-45
Implementation: DuckDB and MotherDuck
DuckDB authentication often involves initializing session-level secrets and tokens, especially for MotherDuck integration.
MotherDuck Token Resolution
The system resolves the motherduck_token through a hierarchical search:
- The
settingsblock in the adapter configuration. - The query parameters of the connection path (
md:my_db?motherduck_token=...). - The
MOTHERDUCK_TOKENenvironment variable.
Initialization SQL Generation
The system generates an ordered sequence of SQL statements to prepare the session:
INSTALLandLOADfor extensions (auto-injectingmotherduckformd:paths).CREATE OR REPLACE SECRETfor cloud storage access (S3, GCS, etc.).SET motherduck_tokenfor MotherDuck authentication.ATTACH IF NOT EXISTSfor database files.
Sources: crates/dbt-auth/src/duckdb/init.rs:1-15, crates/dbt-auth/src/duckdb/init.rs:88-112
This sequence ensures that the environment is fully authenticated before any database attachments or queries occur.
Sources: crates/dbt-auth/src/duckdb/init.rs:240-270
Integration with Adapter Logic
Authentication is integrated into the core AdapterImpl through the auth_for_backend factory.
// crates/dbt-adapter/src/adapter/adapter_impl.rs:1146
let auth: Arc<dyn dbt_auth::Auth> =
dbt_auth::auth_for_backend(Box::new(dbt_auth::NoopAuthWarningPrinter), backend).into();
The adapter uses these authenticated builders to establish connections. For example, the DatabricksApiClient utilizes the resolved token to construct the Authorization: Bearer <token> header for workspace and job API calls.
Sources: crates/dbt-adapter/src/adapter/adapter_impl.rs:1146-1150, crates/dbt-adapter/src/python/databricks/api_client.rs:48-52
Summary of Risks and Verification
Incorrect modifications to the authentication crate can lead to silent regressions:
- Ownership Widening: Erasing distinctions between originally provided strings and coerced values.
- Normalization Regressions: Changing how configuration values are interpreted by downstream drivers.
- Compatibility Breaks: Narrowing accepted profile shapes or legacy keys.
The project requires human verification for any changes affecting borrowed fields, accessor behaviors (get_string vs get_str), or auth enum structures.
Sources: crates/dbt-auth/AGENTS.md:72-100, crates/dbt-auth/CLAUDE.md:72-100