plexus-auth-core 0.1.0

Sealed-type primitives for the Plexus auth framework: AuthContext, VerifiedUser, Principal.
Documentation
[package]
name = "plexus-auth-core"
version = "0.1.0"
edition = "2021"
description = "Sealed-type primitives for the Plexus auth framework: AuthContext, VerifiedUser, Principal."
license = "AGPL-3.0-only"
repository = "https://github.com/hypermemetic/plexus-auth-core"

# Why this is its own crate:
#
# Module-private constructors within `plexus-core` are a procedural defense —
# they rely on contributors respecting visibility within a single crate. A future
# PR to plexus-core that adds a `pub fn forge_auth_context()` would compile.
# Review would catch it; the type system would not.
#
# `plexus-auth-core` exists so the auth primitives have a home that no other
# crate can bypass. Combined with Rust's orphan rules and crate-private
# constructors, this escalates the seal from procedural to structural:
#
#   - No fabrication: no public constructor reachable from other crates
#   - No backdoor From / Into: orphan rules forbid third crates from adding any
#   - No accidental Default: explicitly NOT derived
#   - No leaky Deserialize: routed through the verifier or absent
#   - No mutation: fields private to plexus-auth-core
#
# See AUTHZ-0 §"Crate-level isolation amplifies the seal" and the ticket
# AUTHZ-CORE-CRATE-1 for the full rationale.

[lib]
name = "plexus_auth_core"
path = "src/lib.rs"

[features]
# `test-support` exposes a small set of pub-but-doc-hidden constructors so
# downstream crates (notably plexus-core) can write end-to-end tests that
# need to mint real sealed values. These constructors are gated and
# `#[doc(hidden)]`; they MUST NOT be reachable from production builds.
# Enable via `[dev-dependencies] plexus-auth-core = { features =
# ["test-support"] }` — never as a default feature and never in
# `[dependencies]`.
#
# Added by AUTHZ-CRED-CORE-1B so plexus-core can exercise the end-to-end
# `Credential<T>` serialization path now that
# `run_with_credential_capture` is publicly reachable.
test-support = []

[dependencies]
# Serialization. Note: Deserialize is intentionally implemented in a way that
# documents the seal rather than offering a back-door. See module docs.
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

# Schema generation, for IR/codegen integration. `chrono04` so the
# `CredentialMetadata::expires_at` field's `DateTime<Utc>` participates in
# `JsonSchema` derivation.
schemars = { version = "1.1", features = ["derive", "chrono04"] }

# Async-trait so the SessionValidator-shaped traits can live here in the future.
async-trait = "0.1"

# Issuer URLs in OIDC AuthMechanism::Oidc. AUTHZ-S01-output §1 pins
# `IssuerUrl(url::Url)` for the capability-advertisement type set landed in
# AUTHZ-CORE-3.
url = { version = "2", features = ["serde"] }

# Timestamps on credential metadata (expires_at). AUTHZ-CRED-S01-output §2 pins
# `Option<DateTime<Utc>>`; the workspace's canonical timestamp type is
# chrono::DateTime<Utc> (see plexus-core/Cargo.toml). Used by
# `CredentialMetadata::expires_at` in `src/credential.rs`.
chrono = { version = "0.4", default-features = false, features = ["clock", "serde"] }

# AUTHZ-PRIVACY-1: `AuditRecord::correlation_id` is a UUID (per
# AUTHZ-S01-output §8). Workspace canonical version is 1.x; we pull `v4` for
# generation and `serde` for round-trip.
uuid = { version = "1.6", features = ["v4", "serde"] }

# AUTHZ-PRIVACY-1: `TracingAuditSink` emits structured `tracing::info!` events
# under `target = "plexus::audit"` so every backend gets observability for
# free (AUTHZ-S01-output §8). Workspace pins `tracing = "0.1"`.
tracing = "0.1"

[dev-dependencies]
# trybuild drives compile-fail assertions: AuthContext / VerifiedUser /
# Principal cannot be constructed from outside this crate.
trybuild = "1.0"
tokio = { version = "1", features = ["macros", "rt"] }

# AUTHZ-PRIVACY-1: assert `TracingAuditSink` emits to the `plexus::audit`
# target. `tracing-test` captures span/event output for in-test assertions.
# `no-env-filter` is required because our events use `target = "plexus::audit"`
# (a logical target), not the crate-derived target tracing-test filters on
# by default.
tracing-test = { version = "0.2", features = ["no-env-filter"] }