Repository navigation
Releases: BotResources/br-rust-common
Releases · BotResources/br-rust-common
Release list
br-util-postgres 0.1.1
0.1.1
Changed
ensure_app_rolerefuses an empty password. It returnsPostgresError::Configbefore any statement is sent; it used to clear the role password silently. A password containing a NUL byte is refused the same way.- The stored secret is always SCRAM-SHA-256, whatever
password_encryptionsays, because the crate sends a verifier and Postgres stores it as is. Clients without SCRAM support cannot log in as this role. - The verifier uses a fixed iteration count of 4096. The
ALTER ROLEruns as a non-persistent statement, so sqlx does not keep the verifier in its statement cache. - A server-side password policy hook such as
passwordcheckcannot see the plain password, because Postgres only receives the verifier.
Fixed
ensure_app_roleno longer fails when several callers create the same role at once. The check-then-createDOblock had no lock and no retry, so parallel first calls raced onCREATE ROLE(42710 duplicate_objector apg_authid_rolname_indexunique violation) and onALTER ROLE ... PASSWORD(XX000 tuple concurrently updated). The create and the password change now run in one transaction under a per-rolepg_advisory_xact_lock, which serialises callers of one database. Callers on different databases of one cluster, which an advisory lock cannot order, retry up to 6 attempts with a short backoff on exactly these three SQLSTATEs; any other error, and the last failed attempt, is returned asPostgresError::Db. The public signature is unchanged.tokiois a new direct dependency,timefeature only.grant_app_accessno longer fails when several callers grant at once. Its fiveGRANT/ALTER DEFAULT PRIVILEGESstatements ran autocommit with no lock and no retry, so replicas starting together on a fresh database failed withXX000 tuple concurrently updatedor apg_default_acl_role_nsp_obj_indexunique violation, including when two different app roles were granted at once. The five statements now run in one transaction under one database-widepg_advisory_xact_lock(its own key namespace, distinct from theensure_app_roleone), with the same bounded retry asensure_app_rolefor callers the lock cannot order; the retry helper is shared by both functions. The public signature and the error type are unchanged.
Security
ensure_app_roleno longer sends the clear password to Postgres. It used to buildALTER ROLE "r" PASSWORD $tag$clear$tag$, so the clear password sat in the statement text (server logs,pg_stat_statements, the wire). It now computes a SCRAM-SHA-256 verifier in the process (postgres-protocol, random 16-byte salt, 4096 iterations) and sends onlyALTER ROLE "r" PASSWORD 'SCRAM-SHA-256$4096:...';pg_authid.rolpasswordholds the verifier. The verifier is checked against the alphabet[A-Za-z0-9+/=$:-]before it is quoted, and a failed check isPostgresError::Config. The dollar-quote machinery and the buffer scrub are removed. The new dependency ispostgres-protocol0.6.12or later, the first release outside RUSTSEC-2026-0179 and RUSTSEC-2026-0180; it addsfallible-iteratorand the RustCrypto 0.11 line (hmac,sha2,md-5,digestand their small helper crates) next to the 0.10 linesqlxalready uses.
br-util-directory 0.1.1
0.1.1
Fixed
migrateno longer fails on a database whose_sqlx_migrationsledger holds another migration set. It ransqlx::migrate!against the importer's own ledger, so an importer with its own migrations gotVersionMissing(the ledger held versions this crate does not know) orVersionMismatch(the same version number, another checksum), whichever side migrated first, and the importer's own migrator failed on the crate's version1in the same way.migratenow keeps its own ledger table_br_directory_migrations; it never writes the importer's ledger, and reads it only to adopt a row written by0.1.0, under one transaction-scoped advisory lock so concurrent callers converge. A recorded migration whose checksum drifted still fails, withDirectoryError::Migrate(VersionMismatch). The public signature and the error type are unchanged.- A database migrated by
0.1.0is adopted without re-running the SQL. When_sqlx_migrationsholds this crate's migration with the same checksum,migraterecords it in the new ledger and leaves the old row in place. An importer whose own migrator still lists that row can drop it, or keep ignoring missing versions.
Changed
- Dependency pin:
br-util-postgresmoves frombr-util-postgres/v0.1.0tobr-util-postgres/v0.1.1.br-util-postgrestypes are not part of this crate's API.
br-util-scope-declaration 0.1.0
0.1.0
Changed
- First release of
br-util-scope-declarationas its own library, taggedbr-util-scope-declaration/v0.1.0. The code is the one shipped by the workspace releasev1.4.0; what changes is the versioning: the single workspace version and the singlevX.Y.Ztag are gone, and this crate now carries its own version line. No source file differs fromv1.4.0. - Dependency pin:
{ git = "https://github.com/BotResources/br-rust-common", package = "br-util-scope-declaration", tag = "br-util-scope-declaration/v0.1.0", version = "0.1.0" }. Moving fromtag = "v1.4.0", change both the tag and the version: the number goes down because the line restarts at0.1. - Sibling pins: this crate depends on
br-core-integration,br-core-scope,br-scope-declaration-contract,br-util-axum-readinessandbr-util-nats-fabric, pinned by tagbr-core-integration/v0.1.0,br-core-scope/v0.1.0,br-scope-declaration-contract/v0.1.0,br-util-axum-readiness/v0.1.0andbr-util-nats-fabric/v0.1.0. It namesFabricandFabricErrorfrombr-util-nats-fabric,ScopeDeclaration,ServiceKeyandServiceScopesRejectedfrombr-core-scope,ReadinessHandlefrombr-util-axum-readiness, and returnsActor, which isbr-core-kernel's type carried bybr-core-integrationandbr-core-events, so a consumer resolves one copy of the types they share. Move this crate together with those siblings andbr-core-eventsandbr-core-kernelfromv1.4.0to their per-crate pins: this crate atv0.1.0next to any of them at another tag holds two copies of the same type, and passing a value of one to the other fails to compile (E0308).
br-util-nats-fabric 0.1.0
0.1.0
Changed
- First release of
br-util-nats-fabricas its own library, taggedbr-util-nats-fabric/v0.1.0. The code is the one shipped by the workspace releasev1.4.0; what changes is the versioning: the single workspace version and the singlevX.Y.Ztag are gone, and this crate now carries its own version line. No source file differs fromv1.4.0. - Dependency pin:
{ git = "https://github.com/BotResources/br-rust-common", package = "br-util-nats-fabric", tag = "br-util-nats-fabric/v0.1.0", version = "0.1.0" }. Moving fromtag = "v1.4.0", change both the tag and the version: the number goes down because the line restarts at0.1. - Feature:
outbox(the Postgres transactional outbox, off by default) is unchanged; pin it withfeatures = ["outbox"]next to the tag and version. - Sibling pins: this crate depends on
br-core-integrationandbr-core-events, pinned by tagbr-core-integration/v0.1.0andbr-core-events/v0.1.0. It re-exportsEventMetadatafrombr-core-eventsandIntegrationEvent,IntegrationCommand,MessageOutcomeand the coordinate types (Bc,Aggregate,Verb,PastFact,CommandCoords,EventCoords,CoordError) frombr-core-integration, andbr-core-integrationcarriesbr-core-kernel'sActor,UserIdandServiceAccountIdthroughEventMetadata, so a consumer resolves one copy of the types they share. Move this crate together withbr-core-integration,br-core-eventsandbr-core-kernelfromv1.4.0to their per-crate pins: this crate atv0.1.0next to any of them at another tag holds two copies of the same type, and passing a value of one to the other fails to compile (E0308).
br-util-directory 0.1.0
0.1.0
Changed
- First release of
br-util-directoryas its own library, taggedbr-util-directory/v0.1.0. The code is the one shipped by the workspace releasev1.4.0; what changes is the versioning: the single workspace version and the singlevX.Y.Ztag are gone, and this crate now carries its own version line. No source file differs fromv1.4.0. - Dependency pin:
{ git = "https://github.com/BotResources/br-rust-common", package = "br-util-directory", tag = "br-util-directory/v0.1.0", version = "0.1.0", features = ["consumer"] }. Moving fromtag = "v1.4.0", change both the tag and the version: the number goes down because the line restarts at0.1. - Features:
publisherandconsumer(both off by default) are unchanged; pin them withfeatures = ["publisher"](the identity side, which writes the roster),features = ["consumer"](theknown_*projection and readers) or both next to the tag and version. - Sibling pins: this crate depends on
br-core-directory,br-util-nats-fabricand, behind theconsumerfeature,br-util-postgres, pinned by tagbr-core-directory/v0.1.0,br-util-nats-fabric/v0.1.0andbr-util-postgres/v0.1.0. It namesPublishedUser,PublishedGroup,PublishedServiceAccountandDirectoryMetafrombr-core-directory, andFabric,FabricError,KvKeyError,ProjectionErrorandWatchHealthReceiverfrombr-util-nats-fabric, so a consumer resolves one copy of the types they share.connect_pooldelegates tobr_util_postgres::init_pool, so a consumer moving fromv1.4.0meets the stricter DSN rules ofbr-util-postgres/v0.1.0through it: see the0.1.0entry ofbr-util-postgres. No type ofbr-util-postgresappears in its public API. Move this crate together withbr-core-directoryandbr-util-nats-fabric(and, through the fabric,br-core-integration,br-core-eventsandbr-core-kernel) fromv1.4.0to their per-crate pins: this crate atv0.1.0next to any of them at another tag holds two copies of the same type, and passing a value of one to the other fails to compile (E0308).
br-scope-declaration-contract 0.1.0
0.1.0
Changed
- First release of
br-scope-declaration-contractas its own library, taggedbr-scope-declaration-contract/v0.1.0. The code is the one shipped by the workspace releasev1.4.0; what changes is the versioning: the single workspace version and the singlevX.Y.Ztag are gone, and this crate now carries its own version line. No source file differs fromv1.4.0. - Dependency pin:
{ git = "https://github.com/BotResources/br-rust-common", package = "br-scope-declaration-contract", tag = "br-scope-declaration-contract/v0.1.0", version = "0.1.0" }. Moving fromtag = "v1.4.0", change both the tag and the version: the number goes down because the line restarts at0.1. - Sibling pin: this crate depends on
br-core-integration, pinned by tagbr-core-integration/v0.1.0, and returns itsCommandCoords,EventCoordsandCoordError, so a consumer resolves one copy of the types they share. Move this crate andbr-core-integrationfromv1.4.0to their per-crate pins together: abr-core-integrationat another tag next to it holds twoCommandCoordstypes, and passing one to the other side fails to compile (E0308).
br-identity-app 0.1.0
0.1.0
Changed
- First release of
br-identity-appas its own library, taggedbr-identity-app/v0.1.0. The code is the one shipped by the workspace releasev1.4.0; what changes is the versioning: the single workspace version and the singlevX.Y.Ztag are gone, and this crate now carries its own version line. No source file differs fromv1.4.0. - Dependency pin:
{ git = "https://github.com/BotResources/br-rust-common", package = "br-identity-app", tag = "br-identity-app/v0.1.0", version = "0.1.0" }. Moving fromtag = "v1.4.0", change both the tag and the version: the number goes down because the line restarts at0.1. - Sibling pins: this crate depends on
br-core-integration,br-core-scope,br-identity-domain,br-scope-declaration-contractandbr-util-nats-fabric, pinned by tagbr-core-integration/v0.1.0,br-core-scope/v0.1.0,br-identity-domain/v0.1.0,br-scope-declaration-contract/v0.1.0andbr-util-nats-fabric/v0.1.0. It namesFabricandFabricErrorfrombr-util-nats-fabric,IntegrationCommandandCommandCoordsfrombr-core-integration,ServiceKey,DeclareServiceScopesandScopeDeclarationErrorfrombr-core-scope, andScopeRegistry,DeclarationOutcomeandRegistryHydrationErrorfrombr-identity-domain, so a consumer resolves one copy of the types they share. Move this crate together with those siblings andbr-core-eventsandbr-core-kernelfromv1.4.0to their per-crate pins: this crate atv0.1.0next to any of them at another tag (such asbr-core-scopeatv1.4.0) holds two copies of the same type, and passing a value of one to the other fails to compile (E0308).
br-util-postgres 0.1.0
0.1.0
Changed
- First release of
br-util-postgresas its own library, taggedbr-util-postgres/v0.1.0. The code is the one shipped by the workspace releasev1.4.0plus the DSN host fix below, whichv1.4.0does not contain; the versioning also changes: the single workspace version and the singlevX.Y.Ztag are gone, and this crate now carries its own version line. - Dependency pin:
{ git = "https://github.com/BotResources/br-rust-common", package = "br-util-postgres", tag = "br-util-postgres/v0.1.0", version = "0.1.0" }. Moving fromtag = "v1.4.0", change both the tag and the version: the number goes down because the line restarts at0.1. - Sibling pin: this crate depends on
br-util-bootpinned by tagbr-util-boot/v0.1.0, so the two crates agree on oneDATABASE_URLname constant and one resolvedbr-util-boot. They share no type. Move this crate andbr-util-bootfromv1.4.0to their per-crate pins together. br-util-postgres—validate_database_tlsis stricter about what it
accepts.v1.4.0does not contain these rules. These DSNs were accepted
before and now returnPostgresError::Configbefore any trust decision: a
DSN with no scheme (localhost,localhost/db), a foreign scheme
(mysql://,pg://), a DSN with no explicit host (postgres:///db?sslmode=require),
whose host the driver would take fromPGHOSTADDR,PGHOSTor a socket
directory (such a DSN must now name its host), and any DSN that sqlx cannot
parse, whatever its host: a DSN with an invalidsslmodevalue
(?sslmode=bogus) or an invalid port, whichv1.4.0accepted when the host
was loopback, is now refused before the loopback shortcut. A loopback DSN is
accepted only when sqlx can parse it, and a host listed inTRUSTED_NETWORK_HOSTSis no exception: a trusted host with an invalidsslmodeis now aConfigerror. A non-ASCII trusted host no longer matches, because the URL parser percent-encodes the host. IPv6 hosts compare in canonical
lower-case form ([0:0:0:0:0:0:0:1]is::1). An upper-case scheme
(POSTGRES://) is now accepted.
Fixed
br-util-postgres—validate_database_tlsno longer reads the host from
outside the URL authority (fail-open parsing). The host was taken after the
first@of the whole DSN, so a DSN with@localhostonly in its query,
path or fragment (for examplepostgres://evil.example.com/db?x=a@localhost)
was judgedlocalhost: treated as loopback and accepted without TLS, while
the driver connected toevil.example.com. The host is now read from the
authority only (credentials end at the last@of the authority; a@in the
path, query or fragment, or percent-encoded in the user information, never
changes it), with the same URL parser the driver uses.init_pooland
init_migration_poolinherit the fix. The public signatures are unchanged.
br-util-observability 0.1.0
0.1.0
Changed
- First release of
br-util-observabilityas its own library, taggedbr-util-observability/v0.1.0. The code is the one shipped by the workspace releasev1.4.0; what changes is the versioning: the single workspace version and the singlevX.Y.Ztag are gone, and this crate now carries its own version line. - Dependency pin:
{ git = "https://github.com/BotResources/br-rust-common", package = "br-util-observability", tag = "br-util-observability/v0.1.0", version = "0.1.0" }. Moving fromtag = "v1.4.0", change both the tag and the version: the number goes down because the line restarts at0.1.
br-util-graphql 0.1.0
0.1.0
Changed
- First release of
br-util-graphqlas its own library, taggedbr-util-graphql/v0.1.0. The code is the one shipped by the workspace releasev1.4.0; what changes is the versioning: the single workspace version and the singlevX.Y.Ztag are gone, and this crate now carries its own version line. - Dependency pin:
{ git = "https://github.com/BotResources/br-rust-common", package = "br-util-graphql", tag = "br-util-graphql/v0.1.0", version = "0.1.0" }. Moving fromtag = "v1.4.0", change both the tag and the version: the number goes down because the line restarts at0.1. - Sibling pin: this crate depends on
br-core-values, pinned by tagbr-core-values/v0.1.0, so a consumer resolves one copy of the types they share. Move this crate and the siblings it names fromv1.4.0to their per-crate pins together.