URI Options Specification
-
Status: Accepted
-
Minimum Server Version: N/A
Abstract
Historically, URI options have been defined in individual specs, and drivers have defined any additional options independently of one another. Because of the frustration due to there not being a single place where all of the URI options are defined, this spec aims to do just that—namely, provide a canonical list of URI options that each driver defines.
THIS SPEC DOES NOT REQUIRE DRIVERS TO MAKE ANY BREAKING CHANGES.
META
The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.
Specification
Conflicting TLS options
Per the Connection String spec, the behavior of duplicates of most URI options is undefined. However, due to the security implications of certain options, drivers MUST raise an error to the user during parsing if any of the following circumstances occur:
- Both
tlsInsecure
andtlsAllowInvalidCertificates
appear in the URI options. - Both
tlsInsecure
andtlsAllowInvalidHostnames
appear in the URI options. - Both
tlsInsecure
andtlsDisableOCSPEndpointCheck
appear in the URI options. - Both
tlsInsecure
andtlsDisableCertificateRevocationCheck
appear in the URI options. - Both
tlsAllowInvalidCertificates
andtlsDisableOCSPEndpointCheck
appear in the URI options. - Both
tlsAllowInvalidCertificates
andtlsDisableCertificateRevocationCheck
appear in the URI options. - Both
tlsDisableOCSPEndpointCheck
andtlsDisableCertificateRevocationCheck
appear in the URI options. - All instances of
tls
andssl
in the URI options do not have the same value. If all instances oftls
andssl
have the same value, an error MUST NOT be raised.
directConnection URI option with multiple seeds or SRV URI
The driver MUST report an error if the directConnection=true
URI option is specified with multiple seeds.
The driver MUST report an error if the directConnection=true
URI option is specified with an SRV URI, because the URI
may resolve to multiple hosts. The driver MUST allow specifying directConnection=false
URI option with an SRV URI.
srvServiceName and srvMaxHosts URI options
For URI option validation pertaining to srvServiceName
and srvMaxHosts
, please see the
Initial DNS Seedlist Discovery spec
for details.
Load Balancer Mode
For URI option validation in Load Balancer mode (i.e. loadBalanced=true
), please see the
Load Balancer spec for details.
SOCKS5 options
For URI option validation pertaining to proxyHost
, proxyPort
, proxyUsername
and proxyPassword
please see the
SOCKS5 support spec for details.
List of specified options
Each driver option below MUST be implemented in each driver unless marked as optional. If an option is marked as optional, a driver MUST meet any conditions specified for leaving it out if it is not included. If a driver already provides the option under a different name, the driver MAY implement the old and new names as aliases. All keys and values MUST be encoded in UTF-8. All integer options are 32-bit unless specified otherwise. Note that all requirements and recommendations described in the Connection String spec pertaining to URI options apply here.
Name | Accepted Values | Default Value | Optional to implement? | Description |
---|---|---|---|---|
appname | any string that meets the criteria listed in the handshake spec | no appname specified | no | Passed into the server in the client metadata as part of the connection handshake |
authMechanism | any string; valid values are defined in the auth spec | None; default values for authentication exist for constructing authentication credentials per the auth spec, but there is no default for the URI option itself. | no | The authentication mechanism method to use for connection to the server |
authMechanismProperties | comma separated key:value pairs, e.g. "opt1:val1,opt2:val2" | no properties specified | no | Additional options provided for authentication (e.g. to enable hostname canonicalization for GSSAPI) |
authSource | any string | None; default values for authentication exist for constructing authentication credentials per the auth spec, but there is no default for the URI option itself. | no | The database that connections should authenticate against |
compressors | comma separated list of strings, e.g. "snappy,zlib" | defined in compression spec | no | The list of allowed compression types for wire protocol messages sent or received from the server |
connectTimeoutMS | non-negative integer; 0 means "no timeout" | 10,000 ms (unless a driver already has a different default) | no | Amount of time to wait for a single TCP socket connection to the server to be established before erroring; note that this applies to SDAM hello and legacy hello operations |
directConnection | "true" or "false" | defined in SDAM spec | no | Whether to connect to the deployment in Single topology. |
heartbeatFrequencyMS | integer greater than or equal to 500 | defined in SDAM spec | no | the interval between regular server monitoring checks |
journal | "true" or "false" | no "j" field specified | no | Default write concern "j" field for the client |
loadBalanced | "true" or "false" | defined in Load Balancer spec | no | Whether the driver is connecting to a load balancer. |
localThresholdMS | non-negative integer; 0 means 0 ms (i.e. the fastest eligible server must be selected) | defined in the server selection spec | no | The amount of time beyond the fastest round trip time that a given server’s round trip time can take and still be eligible for server selection |
maxIdleTimeMS | non-negative integer; 0 means no minimum | defined in the Connection Pooling spec | required for drivers with connection pools | The amount of time a connection can be idle before it's closed |
maxPoolSize | non-negative integer; 0 means no maximum | defined in the Connection Pooling spec | required for drivers with connection pools | The maximum number of clients or connections able to be created by a pool at a given time. This count includes connections which are currently checked out. |
maxConnecting | positive integer | defined in the Connection Pooling spec | required for drivers with connection pools | The maximum number of Connections a Pool may be establishing concurrently. |
maxStalenessSeconds | -1 (no max staleness check) or integer >= 90 | defined in max staleness spec | no | The maximum replication lag, in wall clock time, that a secondary can suffer and still be eligible for server selection |
minPoolSize | non-negative integer | defined in the Connection Pooling spec | required for drivers with connection pools | The number of connections the driver should create and maintain in the pool even when no operations are occurring. This count includes connections which are currently checked out. |
proxyHost | any string | defined in the SOCKS5 support spec | no | The IPv4/IPv6 address or domain name of a SOCKS5 proxy server used for connecting to MongoDB services. |
proxyPort | non-negative integer | defined in the SOCKS5 support spec | no | The port of the SOCKS5 proxy server specified in proxyHost . |
proxyUsername | any string | defined in the SOCKS5 support spec | no | The username for username/password authentication to the SOCKS5 proxy server specified in proxyHost . |
proxyPassword | any string | defined in the SOCKS5 support spec | no | The password for username/password authentication to the SOCKS5 proxy server specified in proxyHost . |
readConcernLevel | any string (to allow for forwards compatibility with the server) | no read concern specified | no | Default read concern for the client |
readPreference | any string; currently supported values are defined in the server selection spec, but must be lowercase camelCase, e.g. "primaryPreferred" | defined in server selection spec | no | Default read preference for the client (excluding tags) |
readPreferenceTags | comma-separated key:value pairs (e.g. "dc:ny,rack:1" and "dc:ny) can be specified multiple times; each instance of this key is a separate tag set | no tags specified | no | Default read preference tags for the client; only valid if the read preference mode is not primary The order of the tag sets in the read preference is the same as the order they are specified in the URI |
replicaSet | any string | no replica set name provided | no | The name of the replica set to connect to |
retryReads | "true" or "false" | defined in retryable reads spec | no | Enables retryable reads on server 3.6+ |
retryWrites | "true" or "false" | defined in retryable writes spec | no | Enables retryable writes on server 3.6+ |
serverMonitoringMode | "stream", "poll", or "auto" | defined in SDAM spec | required for multi-threaded or asynchronous drivers | Configures which server monitoring protocol to use. |
serverSelectionTimeoutMS | positive integer; a driver may also accept 0 to be used for a special case, provided that it documents the meaning | defined in server selection spec | no | A timeout in milliseconds to block for server selection before raising an error |
serverSelectionTryOnce | "true" or "false" | defined in server selection spec | required for single-threaded drivers | Scan the topology only once after a server selection failure instead of repeatedly until the server selection times out |
socketTimeoutMS | non-negative integer; 0 means no timeout | no timeout | no | NOTE: This option is deprecated in favor of timeoutMS Amount of time spent attempting to send or receive on a socket before timing out; note that this only applies to application operations, not SDAM. |
srvMaxHosts | non-negative integer; 0 means no maximum | defined in the Initial DNS Seedlist Discovery spec | no | The maximum number of SRV results to randomly select when initially populating the seedlist or, during SRV polling, adding new hosts to the topology. |
srvServiceName | a valid SRV service name according to RFC 6335 | "mongodb" | no | the service name to use for SRV lookup in initial DNS seedlist discovery and SRV polling |
ssl | "true" or "false" | same as "tls" | no | alias of "tls"; required to ensure that Atlas connection strings continue to work |
tls | "true" or "false" | TLS required if "mongodb+srv" scheme; otherwise, drivers may may enable TLS by default if other "tls"-prefixed options are present Drivers MUST clearly document the conditions under which TLS is enabled implicitly | no | Whether or not to require TLS for connections to the server |
tlsAllowInvalidCertificates | "true" or "false" | error on invalid certificates | required if the driver’s language/runtime allows bypassing hostname verification | Specifies whether or not the driver should error when the server’s TLS certificate is invalid |
tlsAllowInvalidHostnames | "true" or "false" | error on invalid certificates | required if the driver’s language/runtime allows bypassing hostname verification | Specifies whether or not the driver should error when there is a mismatch between the server’s hostname and the hostname specified by the TLS certificate |
tlsCAFile | any string | no certificate authorities specified | required if the driver's language/runtime allows non-global configuration | Path to file with either a single or bundle of certificate authorities to be considered trusted when making a TLS connection |
tlsCertificateKeyFile | any string | no client certificate specified | required if the driver's language/runtime allows non-global configuration | Path to the client certificate file or the client private key file; in the case that they both are needed, the files should be concatenated |
tlsCertificateKeyFilePassword | any string | no password specified | required if the driver's language/runtime allows non-global configuration | Password to decrypt the client private key to be used for TLS connections |
tlsDisableCertificateRevocationCheck | "true" or "false" | false i.e. driver will reach check a certificate's revocation status | Yes | Controls whether or not the driver will check a certificate's revocation status via CRLs or OCSP. See the OCSP Support Spec for additional information. |
tlsDisableOCSPEndpointCheck | "true" or "false" | false i.e. driver will reach out to OCSP endpoints if needed. | Yes | Controls whether or not the driver will reach out to OCSP endpoints if needed. See the OCSP Support Spec for additional information. |
tlsInsecure | "true" or "false" | No TLS constraints are relaxed | no | Relax TLS constraints as much as possible (e.g. allowing invalid certificates or hostname mismatches); drivers must document the exact constraints which are relaxed by this option being true |
w | non-negative integer or string | no "w" value specified | no | Default write concern "w" field for the client |
waitQueueTimeoutMS | positive number | defined in the Connection Pooling spec | required for drivers with connection pools, with exceptions described in the Connection Pooling spec | NOTE: This option is deprecated in favor of timeoutMS Amount of time spent attempting to check out a connection from a server's connection pool before timing out |
wTimeoutMS | non-negative 64-bit integer; 0 means no timeout | no timeout | no | NOTE: This option is deprecated in favor of timeoutMS Default write concern "wtimeout" field for the client |
zlibCompressionLevel | integer between -1 and 9 (inclusive) | -1 (default compression level of the driver) | no | Specifies the level of compression when using zlib to compress wire protocol messages; -1 signifies the default level, 0 signifies no compression, 1 signifies the fastest speed, and 9 signifies the best compression |
Test Plan
Tests are implemented and described in the tests directory.
Design Rationale
Why allow drivers to provide the canonical names as aliases to existing options?
First and foremost, this spec aims not to introduce any breaking changes to drivers. Forcing a driver to change the name of an option that it provides will break any applications that use the old option. Moreover, it is already possible to provide duplicate options in the URI by specifying the same option more than once; drivers can use the same semantics to resolve the conflicts as they did before, whether it's raising an error, using the first option provided, using the last option provided, or simply telling users that the behavior is not defined.
Why use "tls" as the prefix instead of "ssl" for related options?
Technically speaking, drivers already only support TLS, which supersedes SSL. While SSL is commonly used in parlance to refer to TLS connections, the fact remains that SSL is a weaker cryptographic protocol than TLS, and we want to accurately reflect the strict requirements that drivers have in ensuring the security of a TLS connection.
Why use the names "tlsAllowInvalidHostnames" and "tlsAllowInvalidCertificates"?
The "tls" prefix is used for the same reasons described above. The use of the terms "AllowInvalidHostnames" and "AllowInvalidCertificates" is an intentional choice in order to convey the inherent unsafety of these options, which should only be used for testing purposes. Additionally, both the server and the shell use "AllowInvalid" for their equivalent options.
Why provide multiple implementation options for the insecure TLS options (i.e. "tlsInsecure" vs. "tlsAllowInvalidHostnames"/"tlsAllowInvalidCertificates"?
Some TLS libraries (e.g. Go's standard library implementation) do not provide the ability to distinguish between allow invalid certificates and hostnames, meaning they either both are allowed, or neither are. However, when more granular options are available, it's better to expose these to the user to allow them to relax security constraints as little as they need.
Why leave the decision up to drivers to enable TLS implicitly when TLS options are present?
It can be useful to turn on TLS implicitly when options such as "tlsCAFile" are present and "tls" is not present. However, with options such as "tlsAllowInvalidHostnames", some drivers may not have the ability to distinguish between "false" being provided and the option not being specified. To keep the implicit enabling of TLS consistent between such options, we defer the decision to enable TLS based on the presence of "tls"-prefixed options (besides "tls" itself) to drivers.
Reference Implementations
Ruby and Python
Security Implication
Each of the "insecure" TLS options (i.e. "tlsInsecure", "tlsAllowInvalidHostnames", "tlsAllowInvalidCertificates", "tlsDisableOCSPEndpointCheck", and "tlsDisableCertificateRevocationCheck") default to the more secure option when TLS is enabled. In order to be backwards compatible with existing driver behavior, neither TLS nor authentication is enabled by default.
Future Work
This specification is intended to represent the current state of drivers URI options rather than be a static description of the options at the time it was written. Whenever another specification is written or modified in a way that changes the name or the semantics of a URI option or adds a new URI option, this specification MUST be updated to reflect those changes.
Changelog
-
2024-05-08: Migrated from reStructuredText to Markdown.
-
2023-08-21: Add serverMonitoringMode option.
-
2022-10-05: Remove spec front matter and reformat changelog.
-
2022-01-19: Add the timeoutMS option and deprecate some existing timeout options
-
2021-12-14: Add SOCKS5 options
-
2021-11-08: Add maxConnecting option.
-
2021-10-14: Add srvMaxHosts option. Merge headings discussing URI validation
for directConnection option. -
2021-09-15: Add srvServiceName option
-
2021-09-13: Fix link to load balancer spec
-
2021-04-15: Adding in behaviour for load balancer mode.
-
2021-04-08: Updated to refer to hello and legacy hello
-
2020-03-03: Add tlsDisableCertificateRevocationCheck option
-
2020-02-26: Add tlsDisableOCSPEndpointCheck option
-
2019-09-08: Add retryReads option
-
2019-04-26: authSource and authMechanism have no default value
-
2019-02-04: Specified errors for conflicting TLS-related URI options
-
2019-01-25: Updated to reflect new Connection Monitoring and Pooling Spec