1
0
Fork
You've already forked ahdapa
0
forked from freeipa/ahdapa
No description
  • Rust 77.7%
  • TypeScript 11.4%
  • Shell 8.5%
  • Python 1.5%
  • Makefile 0.6%
  • Other 0.3%
Alexander Bokovoy 7b0b7af9d2 fix: harden federation redirect validation and token expiry overflow
Reject return_to paths starting with /%2F or /%2f in addition to //,
preventing open-redirect via URL-encoded double-slash that some user
agents decode before navigation.
Cap expires_in to i64::MAX and use saturating_add when computing
expires_at to prevent integer overflow on malicious or malformed
upstream token responses.
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
2026年06月26日 14:29:14 +03:00
.github/workflows fix(ci): update project URL to freeipa organization 2026年06月25日 14:30:12 +03:00
contrib Fix spec generation 2026年06月25日 18:19:45 +03:00
crates fix(gssapi): add error code constants, prompter logging, and SecretBuffer 2026年06月26日 14:22:14 +03:00
docs docs: add System: Read AD Trusts to privilege tables in cluster and demo docs 2026年06月25日 14:30:12 +03:00
migrations fix: harden local OTP verification and add schema constraints 2026年06月26日 14:29:14 +03:00
src fix: harden federation redirect validation and token expiry overflow 2026年06月26日 14:29:14 +03:00
webui chore(webui): update node_modules dependencies 2026年06月25日 14:30:12 +03:00
.gitignore fix(demo): remove accidentally committed log file 2026年06月22日 12:39:50 +03:00
Cargo.lock fix(gssapi): add error code constants, prompter logging, and SecretBuffer 2026年06月26日 14:22:14 +03:00
Cargo.toml feat: add DeploymentMode enum, {hostname} placeholder, and localkdc config validation 2026年06月26日 14:21:39 +03:00
LICENSE Add LICENSE file 2026年05月11日 11:33:50 +03:00
README.md docs: document [webui.self_service] config and self-service profile feature 2026年06月18日 18:20:41 +03:00

Ahdapa

Stateless OAuth 2.0 / OpenID Connect identity provider (IdP) written in Rust, designed for FreeIPA-managed Kerberos environments. The name comes from the Adapa, a Mesopotamian mythical figure who unknowingly refused the gift of immortality.

What it does

  • OAuth 2.0 (RFC 6749) — authorization code, refresh token, client credentials, device authorization, and token exchange grant types.
  • OpenID Connect Core 1.0 — ID tokens, UserInfo endpoint, pairwise subjects, OIDC Discovery.
  • SPNEGO/Kerberos SSO — zero-click authentication for domain members via GSSAPI; password form backed by FreeIPA LDAP as fallback.
  • Stateless tokens — self-contained JWTs; authorization codes and refresh tokens are AES-256-GCM encrypted. No per-token server-side storage. Explicit logout records a short-lived session revocation so the invalidated session cookie is rejected immediately.
  • Horizontal scale — signing keys and client registry replicated across nodes with a built-in CRDT gossip protocol; any node handles any request.
  • Post-quantum ready — ML-DSA-44/65/87 signing alongside classical EdDSA/ES256/RS256.
  • Self-service profile editing — authenticated users can view and modify their own IPA attributes (name, contact, SSH keys, certificates, password) through the /ui/me page. Editability is driven by IPA attributelevelrights and admin-configurable visibility rules.
  • Federation — upstream IdP delegation (§6) with client_secret_post/basic and private_key_jwt; supports OIDC Discovery and static endpoint overrides for plain OAuth2 providers (GitHub, Discord, etc.).
  • RBAC — group-based permissions on the admin API; groups sourced from a static users file or FreeIPA LDAP memberOf.
  • Identity HBAC policy — FreeIPA-compatible Handler-Based Access Control enforced at token issuance. Policies control which users (Identity Subjects) may obtain tokens from which OAuth2 clients (Identity Handlers) for which scopes (Scoped Access). Rules are an op-based CRDT (hbac-crdt) replicated via gossip. Empty rule set = allow-all (backward compatible); client_credentials grant is exempt.
  • SPIFFE Workload API — optional SPIFFE trust domain authority and Workload API server. When [spiffe] trust_domain is configured, ahdapa issues X.509-SVIDs and JWT-SVIDs to local workloads via a Unix domain socket gRPC server, publishes the trust bundle at /.well-known/spiffe-bundle, and bridges SPIFFE identity to OAuth2 tokens.
  • ACME Token Authority (RFC 9447) — when [gssapi] is configured, ahdapa issues authority tokens for ACME tkauth-01 challenges at POST /at/account/{id}/token. Authentication is via Kerberos SPNEGO; the resulting authority token JWT carries EnhancedJWTClaimConstraints (RFC 9118) with mustInclude: ["sub"] and permittedValues binding sub to the Kerberos principal, iss to the issuer URL, and (for host/service principals) dns to IPA-managed FQDNs — a Kerberos-identity binding, not the telephony tnauthlist profile.

Standards

RFC / Spec Description
RFC 6749 OAuth 2.0 Authorization Framework
RFC 6750 Bearer Token Usage
RFC 7009 Token Revocation
RFC 7519 JSON Web Token (JWT)
RFC 7521 / 7523 JWT Bearer Assertion + Client Authentication
RFC 7636 PKCE (S256)
RFC 7662 Token Introspection
RFC 8414 Authorization Server Metadata
RFC 8628 Device Authorization Grant
RFC 8693 Token Exchange
RFC 8707 Resource Indicators
RFC 9068 JWT Profile for Access Tokens
RFC 9126 Pushed Authorization Requests (PAR)
RFC 9207 Authorization Server Issuer Identification
RFC 8705 Mutual-TLS Client Authentication
RFC 9449 DPoP
RFC 9700 OAuth 2.0 Security Best Current Practice
RFC 8226 / RFC 9118 JWTClaimConstraints / EnhancedJWTClaimConstraints — used as the Kerberos-identity constraint format in authority tokens
RFC 9447 ACME Token Authority (tkauth-01) — Kerberos-authenticated issuance only
OIDC Core 1.0 OpenID Connect Core
OIDC Discovery 1.0 OpenID Connect Discovery
OIDC Federation 1.0 Entity Statement (self-signed); bilateral trust

Prerequisites

  • Rust 1.80+ (rustup)
  • OpenSSL 3.x development headers
  • MIT Kerberos development libraries
  • OpenLDAP client development libraries
  • Node.js 20+ and npm (WebUI only)

Fedora / RHEL:

sudo dnf install openssl-devel krb5-devel openldap-devel

For --features pam: sudo dnf install pam-devel

Debian / Ubuntu:

sudo apt install libssl-dev libkrb5-dev libldap-dev

For --features pam: sudo apt install libpam0g-dev

Building

cargo build --release # server binary → target/release/ahdapa
cd webui && npm install && npm run build # WebUI → webui/dist/

Quick start

# /etc/ahdapa/config.toml
[server]
issuer = "https://idp.example.com"
realm = "EXAMPLE.COM"
[db]
url = "sqlite:///var/lib/ahdapa/ahdapa.db"
[gssapi]
service = "HTTP"
keytab = "/etc/ahdapa/ahdapa.keytab"
[ipa]
uri = "ldaps://ipa.example.com"
[webui]
static_dir = "/usr/share/ahdapa/webui"
# Without [rbac], the admin API is inaccessible.
[[rbac.role]]
name = "admin"
permissions = ["*"]
[[rbac.group_role]]
group = "admins"
role = "admin"
AHDAPA_CONFIG=/etc/ahdapa/config.toml ./target/release/ahdapa

See docs/src/quickstart/ for a full walkthrough including database initialization and systemd unit setup.

Database backends

Select a backend at compile time via Cargo features (default: SQLite):

Backend Feature flag Connection URL prefix
SQLite backend-sqlite (default) sqlite:///path/to/file.db
PostgreSQL backend-postgres postgres://user:pass@host/db
MariaDB / MySQL backend-mariadb mariadb://user:pass@host/db
cargo build --release --no-default-features --features backend-postgres

Optional features

Feature Default Description
backend-sqlite yes SQLite database backend.
backend-postgres no PostgreSQL database backend.
backend-mariadb no MariaDB / MySQL database backend.
varlink no Enable user/group attribute lookup via the systemd io.systemd.UserDatabase varlink interface ([varlink] config section). Requires systemd 246+. Password authentication is not performed through varlink.
pam no Enable PAM password authentication backend ([pam] config section). Inserts a PAM step between static-user lookup and LDAP simple bind. Supports expired-password change via /login/change-password. Requires pam-devel at build time.

To enable varlink support alongside the default SQLite backend:

cargo build --release --features varlink

Repository layout

src/ Server binary (Rust)
 auth/ Authentication: GSSAPI, LDAP, AEAD, cookies, RBAC, federation
 routes/ Axum route handlers: OAuth2, admin API, federation, discovery, SPIFFE bundle
 crdt/ CRDT types: LWW map, OR-map, grow-set, refresh families, SPIFFE entries
 db/ sqlx pool setup and schema row types
 workload.rs SPIFFE Workload API gRPC server (tonic, Unix domain socket)
crates/
 ahdapa-gssapi/ GSSAPI/SPNEGO acceptor (Kerberos)
 ahdapa-jose/ JOSE: JWK, JWS, JWT signing and verification (incl. ML-DSA)
 ahdapa-ldap/ Async LDAP client for FreeIPA user and group lookup
 ahdapa-varlink/ Varlink userdb client (systemd io.systemd.UserDatabase, optional)
 ahdapa-pam/ PAM authentication backend (inline libpam FFI, optional)
 ahdapa-spiffe/ SPIFFE CA, SVID issuance, trust bundle, Workload API stubs (tonic/prost)
 hbac-crdt/ Identity HBAC policy engine: op-based CRDT, FreeIPA-compatible rule semantics, OAuth2 axes
webui/ React 19 + TypeScript + PatternFly 6 admin panel and login UI
migrations/ SQL migration scripts (sqlite/, postgres/, mariadb/)
contrib/
 demo/ Local demo configurations and run scripts
 cluster/ Three-node gossip cluster demo (see contrib/demo/cluster/README.md)
 spiffe/ SPIFFE Workload API demo (see contrib/demo/spiffe/README.md)
 ci/ local-ci.sh — runs build, fmt, clippy, tests, and docs
 packages/ RPM packaging: ahdapa.spec.in, rust2rpm.toml, Makefile (make srpm / make copr-build)
 systemd/ systemd unit, sysusers.d, and tmpfiles.d templates for the RPM
docs/ mdBook user and developer documentation

CI

contrib/ci/local-ci.sh all # build · fmt · clippy · test · docs
contrib/ci/local-ci.sh build test # specific jobs only

The CI script requires cargo, rustfmt, and clippy. mdbook is optional (docs build).

Documentation

Full configuration reference, architecture notes, and the developer guide are in docs/. Build the book with mdbook build docs/ or browse docs/src/ as plain Markdown.

License

GPL-3.0-or-later — see LICENSE.