crates.io ↗

iet-auth-revocations-timescale

integration implementation official

Persists the JWT denylist, independent of other auth integrations.

CoreFeaturesIntegrationsStacksTooling
Used byno framework crate yetexamples/htmx-starter
iet-auth-revocations-timescaleimplementationTimescaleDB JWT revocations
Depends oniet-telemetrycontractiet-corecontractiet-authcontractiet-db-timescalecontractiet-db-macroscontract

How to use it

Stores JWT denylist digests in fw_auth_revocations and implements iet_auth::TokenRevocations. It is the only auth-timescale capability that owns no identity reference, so it can be registered and used independently of every other integration.

rust
// examples/htmx-starter/servers/web/tests/framework_live_generated.rs
use std::time::{Duration, SystemTime};

let store = iet_auth_revocations_timescale::RevocationStore::new(db.clone());
let revoked = store.revoked(&[80; 32]).await?;
assert!(!revoked);

let expiry = SystemTime::now() + Duration::from_secs(3600);
store.revoke([80; 32], expiry).await?;
assert!(store.revoked(&[80; 32]).await?);
rust
// Registration can run without iet_auth_identity_timescale:
iet_auth_revocations_timescale::register(&mut registry)?;
  • revoke extends retention to a later expiry but never shortens an existing entry.
  • Expiries in the past are rejected with a validation error, not silently accepted.

How it works

RevocationStore implements TokenRevocations: revoked asks repository::revoked for a live digest, and revoke validates the future expiry before repository::revoke upserts into fw_auth_revocations, keeping the later expiration.

flowchart LR
  Revoked["TokenRevocations revoked"] --> RepoR["repository revoked"]
  Revoke["TokenRevocations revoke"] --> Validate["reject past expiry"]
  Validate --> RepoW["repository revoke"]
  RepoR --> Table["fw_auth_revocations"]
  RepoW --> Table

What it implements

  • Implements iet_auth::TokenRevocations from iet-auth.

Database schema

fw_auth_revocationsentity Revocation · hard delete
PKdigestbytea
expires_at_msi64
index auth_revocation_expiry: (expires_at_ms)
check: octet_length(digest) = 32 AND expires_at_ms > 0
Tables are derived from entity metadata; arrows are foreign keys. Dashed names are tables owned by another crate.

The details below come from #[derive(Persistent)] entity metadata:

fw_auth_revocations

Entity Revocation (hard delete).

ColumnRust typeAttributes
digestVec<u8>primary key, SQL kind bytea
expires_at_msi64

Check: octet_length(digest) = 32 AND expires_at_ms > 0

Index auth_revocation_expiry: (expires_at_ms)

Entities register into an EntityRegistry; EntityRegistry::initial emits a reviewed migration pair, and Migrations applies reviewed files. See iet-db-timescale and iet-db.

What's inside

Modules

  • src/entity.rs
  • src/lib.rs
  • src/repository.rs
  • src/stores.rs

Public API

(root)

  • pub fn register( registry: &mut iet_db_timescale::generation::EntityRegistry, ) -> iet_core::AppResult<()>

entity

  • struct Revocation

stores

  • struct RevocationStore
  • pub fn new(database: TimescaleDatabase) -> Self

Impl map

  • iet_auth::TokenRevocations for RevocationStore

Depends on

External crates: sqlx

Used by

  • No other framework crate depends on it directly.

In this repository

  • examples/htmx-starter

Source: crates/integrations/iet-auth-revocations-timescale