Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/edda

crates/nornir-auth-policy/Cargo.toml

[package]
name = "nornir-auth-policy"
version = "0.1.6"
edition = "2021"
authors = ["Ignalina ApS"]
description = "Shared auth POLICY / composition layer for the nordisk servers — the RBAC role model (`Role`, `AuthConfig`, per-repo ACLs, the opt-in read gate), the declarative `AuthMethodConfig` (OIDC / OAuth2 / mTLS / static-token), and `validate_request`, which builds the enabled, feature-gated `nornir_service::AuthProvider` set from the config and dispatches a presented bearer + client-cert CN through it. The composition tier ABOVE the per-method provider leaves (nornir-auth-{bearer,oidc,oauth2,mtls}): a server pins the providers its tier needs and gets the same login + authorization model as holger (the reference consumer). Consumed by holger, and (suite-wide) korp / dwarves / nornir."
license = "MIT OR Apache-2.0"
repository = "https://git.gunnar.rs/nordisk/edda"
keywords = ["auth", "rbac", "authorization", "oidc", "mtls"]
categories = ["authentication", "network-programming"]

[lib]
name = "nornir_auth_policy"

[features]
default = []
# `online` — forward the outbound-HTTP paths to the OIDC / OAuth2 providers when
# those providers are also pinned (`?` = "if enabled"). The airgap tier omits it,
# so the offline JWT-against-JWKS path is the only auth path compiled and an
# opaque / unresolvable-JWKS token fails closed instead of reaching the network.
online = ["nornir-auth-oidc?/online", "nornir-auth-oauth2?/online"]
# ── Pluggable auth providers (mirrors holger's tier feature set 1:1) ────────────
# Each MODERN auth method is its OWN feature-gated provider leaf; `validate_request`
# only builds a provider whose feature this build pinned (an unpinned method then
# authenticates nothing — fail-closed; `warn_unpinned_providers` shouts at boot).
auth-bearer = ["dep:nornir-auth-bearer"]
auth-oidc = ["dep:nornir-auth-oidc"]
auth-oauth2 = ["dep:nornir-auth-oauth2"]
auth-mtls = ["dep:nornir-auth-mtls"]
# `auth-passkey` — WebAuthn / FIDO2 passkeys, the passwordless HUMAN login for a
# deployment that has no IdP and cannot have one (airgap). Pulls the
# nornir-auth-webauthn leaf with its DEFAULT pure-Rust backend: p256 + ciborium,
# no FFI, no C toolchain, no system libssl. The openssl-backed webauthn-rs
# backend stays where it was, behind that crate's own off-by-default `webauthn`
# feature, for a deployment that wants attestation chains and can afford them.
auth-passkey = ["dep:nornir-auth-webauthn"]

[dependencies]
# The ONE shared auth-provider seam (`provider::AuthProvider` + `Principal` +
# `verify_any` / `verify_any_cert`) this policy layer dispatches through.
nornir-service = { version = "0.1.11", path = "../nornir-service", features = ["auth-provider"] }
serde = { version = "1", features = ["derive"] }
log = "0.4"
# Load a declarative `AuthConfig` from an on-disk file (`load_or_static`) — the
# switch that turns the rich holger-style login (OIDC / OAuth2 / mTLS / RBAC) ON.
# RON is the constellation convention; TOML is accepted too (picked by extension).
ron = "0.12"
toml = "1"

# The ASYNC tonic auth seam (`PolicyAuthLayer`): a tower `Layer`/`Service` applied
# via `Server::builder().layer(..)` so the async `validate_request` can be awaited
# per request (a sync `with_interceptor` cannot). We link only tonic's CORE
# (`Status`, `metadata`, `body::Body`) — NOT its transport/TLS stack (default
# features OFF) — plus the bare `http` request/response types and the tower
# `Layer`/`Service` traits. No hyper, no server runtime pulled into this leaf.
tonic = { version = "0.14", default-features = false }
http = "1"
tower-layer = "0.3"
tower-service = "0.3"

# ── Pluggable AUTH PROVIDER sub-crates — feature-gated + optional, so a tier links
#    ONLY the providers it pinned (embedded/mini = bearer + mtls tiny; full adds
#    oidc + oauth2). Same set + gating holger carried in-tree before the promotion.
nornir-auth-bearer = { version = "0.1.0", path = "../nornir-auth-bearer", optional = true }
nornir-auth-oidc = { version = "0.2.0", path = "../nornir-auth-oidc", optional = true }
nornir-auth-mtls = { version = "0.1.0", path = "../nornir-auth-mtls", optional = true }
nornir-auth-oauth2 = { version = "0.1.0", path = "../nornir-auth-oauth2", optional = true }
# Default features ON deliberately: the default IS the pure-Rust backend, and the
# heavy webauthn-rs one is opt-in inside that crate. `default-features = false`
# here would link the leaf with no backend at all, which authenticates nobody.
nornir-auth-webauthn = { version = "0.2.0", path = "../nornir-auth-webauthn", optional = true }

[dev-dependencies]
# Drive the async `validate_request` dispatch tests.
tokio = { version = "1", features = ["macros", "rt"] }
# The OIDC provider's test-support (throwaway RSA keypair + JWT minting) so the
# `#[cfg(feature = "auth-oidc")]` dispatch tests can mint a signed admin/writer
# token verified offline against an inline test JWKS.
nornir-auth-oidc = { path = "../nornir-auth-oidc", features = ["test-support"] }
# The passkey dispatch tests write a session key to a throwaway file, because the
# resolver's fail-closed behaviour on an unreadable / wrong-length file is half of
# what they are proving.
tempfile = "3"