Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,34 @@ All notable changes to **yara-orm** are documented here. The format is based on
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the project follows
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.17.0] - 2026-08-31

### Fixed

- **PostgreSQL `sslmode` now follows libpq.** Every mode except `disable`
verified the server certificate against the OS trust store, so `prefer` — the
default, and the mode most URLs inherit without saying so — could not reach a
managed database at all: Amazon RDS/Aurora, Cloud SQL and Azure present a
certificate signed by their own private CA, which no OS trust store carries,
and the connection failed the handshake with `UnknownIssuer` before the first
query. libpq (and therefore asyncpg and psycopg, which callers migrate from)
authenticates the server only under `verify-ca` and `verify-full`; `prefer`
and `require` encrypt and nothing more. `prefer` and `require` now do the
same. The connection is still TLS — this is not a fallback to plaintext.

### Added

- **`sslmode=verify-ca` and `sslmode=verify-full`** are accepted in PostgreSQL
URLs, and are the way to ask for certificate verification now that `require`
no longer implies it. `verify-ca` checks the chain, `verify-full` also checks
the hostname. tokio-postgres does not parse either spelling, so the engine
consumes them and hands the driver `sslmode=require`.
- **`sslrootcert=<path>`** adds the PEM roots in that file to the trust store
for the verifying modes — the RDS/Cloud SQL CA bundle, typically. As in
libpq, it does not by itself turn verification on. An unreadable file, or one
holding no certificate, is a configuration error rather than a silent
fallback to the OS roots.

## [1.16.0] - 2026-08-31

### Added
Expand Down
4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "orm-engine"
version = "1.16.0"
version = "1.17.0"
edition = "2021"

[lib]
Expand All @@ -22,6 +22,8 @@ deadpool-postgres = "0.14"
tokio-postgres-rustls = "0.14"
rustls = { version = "0.23", default-features = false, features = ["ring", "std", "tls12", "logging"] }
rustls-native-certs = "0.8"
# Reads the PEM roots a `sslrootcert=` URL parameter points at.
rustls-pemfile = "2"
async-trait = "0.1"
thiserror = "2"
serde_json = "1"
Expand Down
39 changes: 39 additions & 0 deletions docs/backends/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,45 @@ await YaraOrm.init(
These parameters apply to SQLite too (`max_size`/`min_size`/`statement_cache_size`);
in-memory databases always pin a single connection regardless of `max_size`.

### TLS (`sslmode`)

TLS is served by **rustls** — no system OpenSSL — and `sslmode` behaves as it
does in libpq, so a URL that worked with asyncpg or psycopg works here:

| `sslmode` | TLS | Certificate checked |
| -------------------- | ---------------------------- | ------------------------------------ |
| `disable` | no | — |
| `prefer` *(default)* | yes, plaintext if unsupported | no |
| `require` | yes | no |
| `verify-ca` | yes | chain must reach a trusted root |
| `verify-full` | yes | chain **and** hostname |

`prefer` and `require` encrypt the connection without authenticating the server:
`require` promises TLS, not identity. Ask for verification explicitly when you
want it:

```python
await YaraOrm.init(
"postgres://user:pass@db.example.com/app"
"?sslmode=verify-full&sslrootcert=/etc/ssl/certs/rds-global-bundle.pem"
)
```

`sslrootcert` points at a PEM file whose certificates are added to the OS trust
store for that connection — the CA bundle of a managed database, typically.
Managed PostgreSQL (Amazon RDS/Aurora, Cloud SQL, Azure) presents a certificate
signed by the provider's own CA, which no OS trust store carries, so the
verifying modes need this parameter; download the provider's bundle and name it
here. As in libpq, `sslrootcert` alone does not turn verification on — pair it
with `verify-ca` or `verify-full`. A file that cannot be read, or that holds no
certificate, raises at `init()` rather than quietly verifying against the OS
roots instead.

!!! note "Reaching a database through another name"
`verify-full` rejects a certificate that does not name the host you dialled,
which is what a proxy endpoint, an SSH tunnel or a bare IP usually means.
`verify-ca` is the mode for those: the chain is still verified.

## MySQL

The MySQL backend is built on the pure-Rust **mysql_async** driver and its own
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ build-backend = "maturin"
[project]
# Distribution name on PyPI is "yara-orm"; the import package is `yara_orm`.
name = "yara-orm"
version = "1.16.0"
version = "1.17.0"
description = "Fast async Python ORM with a Rust engine — Tortoise-style models, querysets, relations and migrations for PostgreSQL, MySQL, MariaDB and SQLite"
readme = "README.md"
requires-python = ">=3.9"
Expand Down
2 changes: 1 addition & 1 deletion python/yara_orm/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ class User(Model):
except ImportError: # pragma: no cover
_engine_version = "unbuilt"

__version__ = "1.16.0"
__version__ = "1.17.0"

__all__ = [
"YaraOrm",
Expand Down
Loading