pgcrypto
What it is
pgcrypto is PostgreSQL's supplied cryptography extension. It exposes digest, keyed hash, password-hashing, PGP encryption, random-byte, and UUID functions inside the database.
What it provides
- SHA-family digests and HMACs
- Adaptive password hashes through
cryptandgen_salt - PGP encryption and decryption functions
- Cryptographically strong random bytes and UUIDs
Use it for searchable fingerprints, tamper checks, database-managed password verification, encrypted database fields, or random token material. For sensitive plaintext, use TLS and decide explicitly whether the application or database is the correct trust boundary.
Use it with Rent
extension pgcrypto {
name = "pgcrypto"
}The RSL declaration makes installation and migration intent part of the reviewed application schema. Register the typed pack at runtime to call its APIs:
let crypto = extensions.register_pack::<PgCrypto>()?;
let fingerprint = crypto.digest(
crypto.value("payload"),
DigestAlgorithm::Sha256,
);
let client = crypto.client(&pool);
let password_hash = client
.hash_password(
"secret",
PasswordAlgorithm::Blowfish,
)
.await?;
let valid = client
.verify_password("secret", &password_hash)
.await?;
let id = client.random_uuid().await?;Run the application
Add the extension declaration above to your application's schema. Confirm that your PostgreSQL provider offers the extension and that your migration role can install it, then apply the migration and run your application:
rent migrate dev --name enable_pgcrypto
cargo runA digest can fingerprint a high-entropy token. A fast SHA digest is not a password-storage scheme. Use TLS when sending passwords to the database and exclude bound values from logs.
Complete example
Download this project, or copy the files below into an empty directory.
Replace RENT_REPOSITORY_URL in Cargo.toml with the URL supplied with your preview access. Use the matching Rent CLI release.
Use an empty PostgreSQL database with the extension binaries available on its server. Set DATABASE_URL
to that database and follow any server setup requirements described above.
rent extension check --provider self-hosted
rent generate
rent migrate dev --name initial
cargo runIf your host preinstalls other extensions, declare those in RSL as well. For a database with existing application tables, baseline it first.
Cargo.toml
[package]
name = "rent-extension-pgcrypto"
version = "0.1.0"
edition = "2024"
[workspace]
[[bin]]
name = "rent-extension-pgcrypto"
path = "main.rs"
[dependencies]
rent = { git = "RENT_REPOSITORY_URL", tag = "v0.8.6", default-features = false, features = ["postgres", "extensions", "migrate"] }
rent-ext-pgcrypto = { git = "RENT_REPOSITORY_URL", tag = "v0.8.6" }
anyhow = "1.0.104"
tokio = { version = "1.53.1", features = ["full"] }rent.toml
schema = "schema.rsl"
generated = "generated"
migrations = "migrations"
[database]
dialect = "postgres"
backends = ["postgres"]schema.rsl
datasource db {
provider = "postgresql"
}
extension pgcrypto {
name = "pgcrypto"
}
model Post {
id BigInt @id
title String
body String @default("")
}main.rs
use anyhow::Result;
use rent::{driver::DatabasePool, extension::ExtensionRegistry};
#[allow(dead_code, unused_imports)]
#[rustfmt::skip]
#[path = "generated/mod.rs"]
mod generated;
#[tokio::main]
async fn main() -> Result<()> {
let pool = DatabasePool::connect_url(&std::env::var("DATABASE_URL")?).await?;
let mut extensions = ExtensionRegistry::default();
use rent_ext_pgcrypto::{PasswordAlgorithm, PgCrypto, PgCryptoClientExt};
let pack = extensions.register_pack::<PgCrypto>()?;
let crypto = pack.client(&pool);
let hash = crypto.hash_password("example password", PasswordAlgorithm::Blowfish).await?;
anyhow::ensure!(crypto.verify_password("example password", &hash).await?);
println!("New identifier: {}", crypto.random_uuid().await?);
Ok(())
}