Hi @shan-databricks,
You can do this in Databricks, but it's recommended to separate secrets from runtime parameters.
For SQL Server and PostgreSQL, the modern approach is usually a JDBC Unity Catalog connection. A JDBC UC connection stores the JDBC driver, URL path, and credentials in a governed connection object, works across supported compute types, and keeps credentials hidden from the querying user. In that pattern, your job parameters only need to carry non-sensitive values such as the connection name, schema, table, or query.
If the requirement is read-only access, Databricks generally recommends Lakehouse Federation instead of raw JDBC for supported sources such as PostgreSQL and SQL Server.
For MongoDB, I would usually recommend using the MongoDB Spark connector together with Databricks secrets rather than passing credentials as job parameters. Databricks documents MongoDB as a third-party Spark connector use case, and custom third-party Spark JARs are supported on dedicated clusters only, not on Databricks SQL, serverless, or standard access mode clusters.
More generally, use job parameters only for non-secret runtime values such as source_system, connection_name, database, collection, table, or query. Databricks explicitly notes that job parameters can be overridden at run time and that a default parameter value is not a security control.
If you are using a notebook task, a common pattern is:
- Retrieve secrets with dbutils.secrets.get()
- Retrieve job parameters with dbutils.widgets.get()
Databricks also supports referencing secrets in Spark configuration properties or environment variables using {{secrets/scope/key}}, but this comes with additional security considerations and is usually not the first choice unless you specifically need cluster-level or init-script-based injection.
A few example patterns below may help make this more concrete.
For SQL Server/PostgreSQL using a JDBC Unity Catalog connection:
connection_name = dbutils.widgets.get("connection_name")
table_name = dbutils.widgets.get("table_name")
df = (
spark.read.format("jdbc")
.option("databricks.connection", connection_name)
.option("dbtable", table_name)
.load()
)
This is the pattern Databricks recommends when migrating existing Spark JDBC code...move the URL and credentials into the connection object, and pass only runtime values like the connection name and table/query from the job.
For Notebook parameters + Databricks secrets:
source_system = dbutils.widgets.get("source_system")
database_name = dbutils.widgets.get("database_name")
username = dbutils.secrets.get(scope="ext-sources", key="username")
password = dbutils.secrets.get(scope="ext-sources", key="password")
This works well when you want the job to stay parameter-driven, but still keep credentials in a secret scope instead of the job definition.
For MongoDB using the Spark connector:
mongo_uri = dbutils.secrets.get(scope="ext-sources", key="mongodb-uri")
database_name = dbutils.widgets.get("database_name")
collection_name = dbutils.widgets.get("collection_name")
df = (
spark.read.format("mongodb")
.option("connection.uri", mongo_uri)
.option("database", database_name)
.option("collection", collection_name)
.load()
)
For MongoDB, the connector-based approach is the better fit than trying to force everything through JDBC-style job parameters, especially since Databricks documents MongoDB as a third-party Spark connector use case.
For SQL Server using the bundled connector directly
df = (
spark.read.format("sqlserver")
.option("host", dbutils.widgets.get("host"))
.option("user", dbutils.secrets.get(scope="ext-sources", key="sqlserver-user"))
.option("password", dbutils.secrets.get(scope="ext-sources", key="sqlserver-password"))
.option("database", dbutils.widgets.get("database_name"))
.option("query", dbutils.widgets.get("source_query"))
.load()
)
Databricks also documents this bundled-connector pattern for SQL Server. If you do this, the same principle applies.. as in...keep secrets in secret scopes, and use job parameters only for non-sensitive runtime inputs.
If this answer resolves your question, could you mark it as โAccept as Solutionโ? That helps other users quickly find the correct fix.
Regards,
Ashwin | Delivery Solution Architect @ Databricks
Helping you build and scale the Data Intelligence Platform.
***Opinions are my own***