# Spec for the ahdapa OAuth2/OIDC identity provider workspace. # # DO NOT edit ahdapa.spec directly — it is generated from this file by # 'make srpm'. Edit ahdapa.spec.in and run 'make srpm' to regenerate. # # Source tarball ('make tarball'): # git archive --format=tar.gz --prefix=ahdapa-{version}/ HEAD \ # -o ahdapa-{version}.tar.gz # # Vendor tarball ('make vendor'): # Resolves all optional backend features first so that postgres/mariadb # driver crates are included, then vendors with --versioned-dirs: # cargo check --features backend-sqlite,backend-postgres,backend-mariadb # cargo vendor --versioned-dirs vendor/ # cp -a vendor/synta-{ver}/asn1 vendor/asn1 # for synta-codegen build.rs # tar czf ahdapa-{version}-vendor.tar.gz \ # --exclude='*.profraw' -C . vendor/ Cargo.lock # # Crates in the vendor tarball absent from Fedora or at incompatible versions: # axum 0.8 — Fedora ships 0.7.x (incompatible API) # sqlx 0.8 — not packaged in Fedora / RHEL 10 # toml 0.8 — Fedora ships 1.1 (incompatible API) # native-ossl 0.1.8 — not packaged in Fedora (wraps system OpenSSL via bindgen) # rustls-native-ossl 0.1.8 — not packaged in Fedora # reqwest 0.12 — Fedora version may differ; vendored for compatibility # synta* 0.2.x — packaged separately in COPR (not in Fedora main) # sqlx-{postgres,mysql} — needed when %%{with backend_postgres/mariadb} # tonic 0.14.x — gRPC server (SPIFFE Workload API); Fedora ships 0.11.x # tonic-prost 0.14.x — prost codec for tonic 0.14.x; not in Fedora # prost 0.14.x — protobuf runtime for gRPC; Fedora ships 0.13.x # prost-types 0.14.x — protobuf well-known types; not in Fedora # tonic-build 0.14.x — build-time only (proto → Rust code generation) # tonic-prost-build 0.14.x — build-time only (proto → Rust code generation) # criterion 0.5 — benchmarking framework (ahdapa-bench dev-dep); compiled # into the criterion harness executables when --with tools; # excluded from __cargo_common_opts via -Z avoid-dev-deps # for the main %%cargo_build pass. criterion and its unique # deps (criterion-plot, anes, cast, oorandom, tinytemplate, # plotters/plotters-backend/plotters-svg, rayon/rayon-core, # crossbeam-deque/crossbeam-epoch, is-terminal, same-file, # walkdir, futures umbrella, itertools 0.10.x) are filtered # from cargo-vendor.txt so bundled(crate()) Provides reflect # the main ahdapa binary only; ahdapa-tools bundles them. # # PREREQUISITE: install synta* into the mock chroot before rebuilding: # mock --install rust-synta-devel rust-synta-certificate-devel # Snapshot release identifiers — substituted by 'make srpm' via sed. # Do not edit these lines manually; the sed pattern matches the whole line. %global snapdate 202606041558 %global snapcommit 21eacbe9 %bcond check 1 # SELinux policy module — labels /usr/bin/ahdapa, /run/ahdapa/, /var/lib/ahdapa, # and /etc/ahdapa with custom types. Covers: httpd_t (mod_proxy) Unix socket # forwarding; gssproxy GSSAPI integration including keytab in /etc/httpd/conf/ # (httpd_config_t); FreeIPA co-deployment (/var/lib/ipa/ search); Kerberos # KEYRING ccache; proc_t anonymous inode association; systemd runtime symlinks. # Disable with: rpmbuild --without selinux %bcond selinux 1 # Optional database backends (in addition to the always-on SQLite default). # Disable with: rpmbuild --without backend_postgres or --without backend_mariadb %bcond backend_postgres 1 %bcond backend_mariadb 1 # Optional management web UI built from webui/ using npm. # Requires Source6 (ahdapa-%%{version}-webui-dist.tar.gz, see 'make webui-dist'). # When disabled, webui assets are not installed but the ahdapa binary still works. # Disable with: rpmbuild --without webui %bcond webui 1 # Optional load-testing / benchmark tools (ahdapa-bench CLI + criterion harness # executables + bench.sh orchestration script). # Disable with: rpmbuild --without tools %bcond tools 1 # Optional system userdb lookup via io.systemd.UserDatabase varlink interface. # Requires systemd 246+. Disable with: rpmbuild --without varlink %bcond varlink 1 # Optional PAM password authentication backend (pam_sss, pam_winbind, etc.). # Requires pam-devel at build time and /etc/pam.d/ahdapa at runtime. # Disable with: rpmbuild --without pam %bcond pam 1 # SPIFFE Workload Proxy daemon — forwards SPIFFE Workload API requests from # IPA-enrolled non-Ahdapa hosts to an Ahdapa node via Kerberos credentials. # Disable with: rpmbuild --without spiffe_proxy %bcond spiffe_proxy 1 # Force --locked for all cargo invocations. Without it, cargo resolves the # dependency graph from scratch in the offline build environment and fails to # locate the vendored crates. --locked tells cargo to use Cargo.lock as-is. %global __cargo_common_opts %{?_smp_mflags} -Z avoid-dev-deps --locked # Feature list passed to cargo: sqlite is always on; postgres/mariadb are opt-in. %global _ahdapa_features backend-sqlite %if %{with backend_postgres} %global _ahdapa_features %{_ahdapa_features},backend-postgres %endif %if %{with backend_mariadb} %global _ahdapa_features %{_ahdapa_features},backend-mariadb %endif %if %{with varlink} %global _ahdapa_features %{_ahdapa_features},varlink %endif %if %{with pam} %global _ahdapa_features %{_ahdapa_features},pam %endif Name: ahdapa Version: 0.1.0 Release: 1.%{snapdate}.git%{snapcommit}%{?dist} Summary: OAuth2/OIDC identity provider with FreeIPA integration License: GPL-3.0-or-later URL: https://codeberg.org/abbra/ahdapa # git archive --format=tar.gz --prefix=ahdapa-{version}/ HEAD \ # -o ahdapa-{version}.tar.gz Source0: ahdapa-%{version}.tar.gz # Full vendor tarball — see the generation instructions at the top of this spec. # Contains all Cargo dependencies, including several crates not yet available # in Fedora (axum 0.8, sqlx 0.8, native-ossl 0.1.8, rustls-native-ossl 0.1.8). Source1: ahdapa-%{version}-vendor.tar.gz # Systemd service unit (from contrib/systemd/ in the source tree; copied into # _sourcedir by the 'make srpm' target). Source2: ahdapa.service # Systemd socket unit — enables socket activation (optional; see docs). Source7: ahdapa.socket # Example configuration file; installed as %%{_sysconfdir}/ahdapa/ahdapa.toml.example Source3: ahdapa.toml.example # sysusers.d — system user/group definition Source4: ahdapa-sysusers.conf # tmpfiles.d — /var/lib/ahdapa state directory creation Source5: ahdapa-tmpfiles.conf # Pre-built management web UI static assets (Vite/npm output from webui/dist/). # Generated with: cd webui && npm install && npm run build && \ # tar czf ahdapa-{version}-webui-dist.tar.gz dist/ # See 'make webui-dist' in contrib/packages/. Source6: ahdapa-%{version}-webui-dist.tar.gz # PAM service file — installed as /etc/pam.d/ahdapa when --with pam. Source8: ahdapa-pam.conf # SPIFFE Workload Proxy systemd service unit (from contrib/systemd/). Source9: ahdapa-spiffe-proxy.service # sysusers.d — system user for the SPIFFE Workload Proxy (spiffe-proxy). Source10: ahdapa-spiffe-proxy-sysusers.conf # Example configuration; installed as %%{_sysconfdir}/ahdapa/spiffe-proxy.toml.example. Source11: spiffe-proxy.toml.example ExclusiveArch: %{rust_arches} BuildRequires: cargo-rpm-macros >= 26 # System OpenSSL — native-ossl-sys links against it via bindgen-generated FFI. # Rebuild this package whenever openssl-devel is updated in Fedora. BuildRequires: pkgconfig(openssl) BuildRequires: openssl-devel # SQLite — required by the always-on backend-sqlite feature (libsqlite3-sys). BuildRequires: pkgconfig(sqlite3) BuildRequires: sqlite-devel # LDAP / SASL / GSSAPI — required by the ahdapa-ldap and ahdapa-gssapi FFI crates. BuildRequires: openldap-devel BuildRequires: cyrus-sasl-devel BuildRequires: krb5-devel # Optional backend: PostgreSQL (libpq) %if %{with backend_postgres} BuildRequires: pkgconfig(libpq) BuildRequires: libpq-devel %endif # Optional backend: MariaDB / MySQL (Connector/C) %if %{with backend_mariadb} BuildRequires: pkgconfig(libmariadb) BuildRequires: mariadb-connector-c-devel %endif # Optional varlink userdb feature: kirmes is pure Rust, no system library needed. # Optional PAM authentication backend: links against libpam. %if %{with pam} BuildRequires: pam-devel %endif # The native-ossl-sys build script generates FFI bindings via bindgen, which # requires libclang. Rebuild this package whenever openssl-devel changes. BuildRequires: clang-devel # protobuf-compiler (protoc) — required by the ahdapa-spiffe build script # (tonic-prost-build) to compile the SPIFFE Workload API .proto file into Rust. BuildRequires: protobuf-compiler # synta* crates are packaged separately (COPR); install them into the mock # chroot before rebuilding this SRPM: # mock --install rust-synta-devel rust-synta-certificate-devel BuildRequires: rust-synta-devel BuildRequires: rust-synta-certificate-devel # Systemd scriptlet support BuildRequires: systemd-rpm-macros # Management web UI static assets are pre-built (see 'make webui-dist') and # bundled in Source6; no Node.js or npm is needed inside the mock chroot. # Man page compiler (docs/man/*.scd → gzipped groff). BuildRequires: scdoc # SELinux policy module build tooling %if %{with selinux} BuildRequires: selinux-policy-devel BuildRequires: policycoreutils %endif %{?systemd_requires} %if %{with selinux} Requires(post): policycoreutils Requires(postun): policycoreutils %endif %description Ahdapa is a stateless OAuth2 / OpenID Connect identity provider with native FreeIPA / Kerberos integration. It implements the core OAuth2 and OIDC specifications (RFC 6749, RFC 7636, RFC 7662, RFC 8707, RFC 9126, RFC 8628, OIDC Core 1.0) plus WebAuthn passkey authentication, post-quantum signing via ML-DSA (FIPS 204), and OIDC Federation 1.0. State (signing keys, client registrations, cluster membership) is replicated across nodes using a CRDT gossip protocol without a shared database. A SQLite, PostgreSQL, or MariaDB backend can be used for persistence and session storage. %files %license LICENSE %license LICENSE.dependencies %license cargo-vendor.txt %{_bindir}/ahdapa %{_bindir}/ahdapactl %{_mandir}/man8/ahdapa.8.gz %{_mandir}/man5/ahdapa.toml.5.gz %{_mandir}/man1/ahdapactl.1.gz %{_unitdir}/ahdapa.service %{_unitdir}/ahdapa.socket %{_sysusersdir}/ahdapa.conf %{_tmpfilesdir}/ahdapa.conf %dir %{_sysconfdir}/ahdapa %config(noreplace) %{_sysconfdir}/ahdapa/ahdapa.toml.example %ghost %dir %attr(0750,ahdapa,ahdapa) %{_sharedstatedir}/ahdapa %doc docs/src %doc contrib/demo/ahdapa.sample.toml %doc contrib/demo/ipa %doc contrib/demo/cluster %doc contrib/demo/federation %doc contrib/demo/github %doc contrib/demo/passkey %if %{with pam} %config(noreplace) %{_sysconfdir}/pam.d/ahdapa %endif %if %{with webui} %{_datadir}/ahdapa/webui/ %endif %if %{with selinux} %{_datadir}/selinux/packages/%{name}.pp %endif # ── Subpackage: tools (benchmark / load testing) ────────────────────────────── %if %{with tools} %package -n ahdapa-tools Summary: Load-testing and benchmark tools for ahdapa License: GPL-3.0-or-later Requires: ahdapa = %{version}-%{release} # bench.sh uses curl for health-check polling and openssl for TLS PKI generation. Requires: curl Requires: openssl # bench.sh uses python3 for JSON parsing and graph generation (matplotlib optional). Requires: python3 %description -n ahdapa-tools ahdapa-tools provides the ahdapa-bench binary and the bench.sh orchestration script for load-testing and benchmarking a running ahdapa cluster. ahdapa-bench probe — health-check all configured nodes ahdapa-bench converge — measure gossip convergence time across all nodes bench.sh spins up a local N-node cluster (or targets a remote one), runs gossip convergence measurements, and invokes criterion benchmark harness executables for endpoint latency measurements. Set AHDAPA_DEV_MODE=1 to switch to dev mode, which uses cargo to build from source and run benchmarks via "cargo bench". %files -n ahdapa-tools %license LICENSE %{_bindir}/ahdapa-bench %dir %{_libexecdir}/ahdapa-bench %{_libexecdir}/ahdapa-bench/client_credentials %{_libexecdir}/ahdapa-bench/auth_code %{_libexecdir}/ahdapa-bench/introspect %{_libexecdir}/ahdapa-bench/device_flow %dir %{_datadir}/ahdapa/bench %{_datadir}/ahdapa/bench/bench.sh %endif # ── Subpackage: SPIFFE Workload Proxy ───────────────────────────────────────── %if %{with spiffe_proxy} %package -n ahdapa-spiffe-proxy Summary: SPIFFE Workload Proxy for IPA-enrolled hosts License: GPL-3.0-or-later %{?systemd_requires} %description -n ahdapa-spiffe-proxy ahdapa-spiffe-proxy is a standalone daemon that IPA-enrolled hosts can run to expose a local SPIFFE Workload API gRPC endpoint (Unix socket). Instead of issuing SVIDs from a local CA, it forwards requests to an Ahdapa node and authenticates using the host's existing Kerberos credentials (keytab or ccache from IPA enrollment). Workloads on the host connect to the local Unix socket as if it were a native SPIFFE Workload API endpoint. The proxy handles JWT-SVID issuance, X.509-SVID issuance (generating ephemeral keypairs locally so the private key never leaves the host), and SPIFFE bundle distribution. %files -n ahdapa-spiffe-proxy %license LICENSE %{_bindir}/ahdapa-spiffe-proxy %{_unitdir}/ahdapa-spiffe-proxy.service %{_sysusersdir}/ahdapa-spiffe-proxy.conf %dir %{_sysconfdir}/ahdapa %config(noreplace) %{_sysconfdir}/ahdapa/spiffe-proxy.toml.example %endif # ── Prep ─────────────────────────────────────────────────────────────────────── %prep # Unpack the source tarball; -a1 unpacks Source1 (vendor/) inside the build dir. %autosetup -n %{name}-%{version} -p1 -a1 # Set up the cargo build environment using the full vendor tree. # %%cargo_prep -v vendor configures .cargo/config.toml to redirect all # crates-io lookups to vendor/. %cargo_prep -v vendor # Strip executable bits from all vendored source files. # unicode-normalization ships scripts/unicode.py with +x and #!/usr/bin/env python # (no version). find-debuginfo copies it to /usr/src/debug/; brp-mangle-shebangs # then expands the shebang to /usr/bin/python, detects it as ambiguous python # (line 160: fail=1), and aborts the build. Stripping +x prevents this. find vendor/ -type f -exec chmod -x {} \; # ── Generate BuildRequires ───────────────────────────────────────────────────── %generate_buildrequires # The full vendor tarball (Source1) bundles every Rust crate dependency that # is absent from Fedora or at an incompatible version (axum 0.8, sqlx 0.8, # toml 0.8, native-ossl 0.1.8, rustls-native-ossl 0.1.8, reqwest 0.12, # synta* from COPR, the optional postgres/mariadb backends, and criterion 0.5 # used by the ahdapa-tools bench harness). # # %%cargo_generate_buildrequires is intentionally omitted: it runs before # %%prep (before the vendor tarball is unpacked) and emits crate() BuildRequires # for every dependency, including dev-deps like criterion 0.5 that are not # packaged in Fedora. All non-crate build requirements (system libraries, # Rust toolchain) are declared statically in the BuildRequires: lines above. # ── Build ────────────────────────────────────────────────────────────────────── %build # Build the ahdapa binary. # Pass the feature list explicitly; --no-default-features keeps the set minimal # (only what %%{_ahdapa_features} requests, always at least backend-sqlite). %cargo_build -- --workspace --no-default-features --features %{_ahdapa_features} # Build criterion harness executables for the tools subpackage. # These are [[bench]] targets in ahdapa-bench; they have criterion linked in # and are run directly (without cargo) in installed mode by bench.sh. # Must use a direct cargo invocation without -Z avoid-dev-deps so that criterion # (a dev-dependency) is available for compilation. %if %{with tools} cargo build --release --locked --benches -p ahdapa-bench %endif # Generate the bundled-dependency license summary required by Fedora policy. %{cargo_license_summary} %{cargo_license} > LICENSE.dependencies %{cargo_vendor_manifest} # cargo_vendor_manifest is generated with --target=all, which pulls in # platform-specific crates never compiled on Linux. Remove them so that # the bundled(crate()) Provides reflect what is actually linked. sed -i -E \ -e '/^windows[-_]/d' \ -e '/^(schannel|ipconfig|widestring|find-msvc-tools) /d' \ -e '/^core-foundation/d' \ -e '/^security-framework/d' \ -e '/^(js-sys|web-sys) /d' \ -e '/^wasm-bindgen/d' \ -e '/^wit-bindgen/d' \ -e '/^(wasi|wasip2|wasip3|wasite) /d' \ -e '/^(redox_syscall|libredox|r-efi) /d' \ -e '/^hermit-abi /d' \ -e '/^winapi/d' \ -e '/^(wasm-encoder|wasm-metadata|wasmparser) /d' \ -e '/^criterion/d' \ -e '/^(anes|cast|oorandom|tinytemplate) /d' \ -e '/^plotters/d' \ -e '/^rayon/d' \ -e '/^(crossbeam-deque|crossbeam-epoch) /d' \ -e '/^futures /d' \ -e '/^(is-terminal|same-file|walkdir) /d' \ -e '/^itertools 0\.10\./d' \ cargo-vendor.txt # Compile man pages from scdoc sources. scdoc < docs/man/ahdapa.8.scd | gzip -9 > ahdapa.8.gz scdoc < docs/man/ahdapa.toml.5.scd | gzip -9 > ahdapa.toml.5.gz scdoc < docs/man/ahdapactl.1.scd | gzip -9 > ahdapactl.1.gz # Compile the SELinux policy module (.te + .fc + .if → ahdapa.pp). %if %{with selinux} make -C contrib/selinux -f /usr/share/selinux/devel/Makefile ahdapa.pp %endif # Unpack the pre-built management web UI static assets (Source6). %if %{with webui} tar -xzf %{SOURCE6} -C webui/ %endif # ── Install ──────────────────────────────────────────────────────────────────── %install # Copy the built binary from target/rpm/ into the buildroot. # Per Fedora Rust packaging guidelines for workspace projects, %%cargo_install # SHOULD NOT be used; copy executables explicitly from target/rpm/. install -Dpm 0755 target/rpm/ahdapa %{buildroot}%{_bindir}/ahdapa # Man pages (compiled from scdoc sources in %%build) install -Dpm 0644 ahdapa.8.gz %{buildroot}%{_mandir}/man8/ahdapa.8.gz install -Dpm 0644 ahdapa.toml.5.gz %{buildroot}%{_mandir}/man5/ahdapa.toml.5.gz install -Dpm 0644 ahdapactl.1.gz %{buildroot}%{_mandir}/man1/ahdapactl.1.gz # Copy the built binary from target/rpm/ into the buildroot. install -Dpm 0755 target/rpm/ahdapactl %{buildroot}%{_bindir}/ahdapactl # Systemd service and socket units install -Dpm 0644 %{SOURCE2} %{buildroot}%{_unitdir}/ahdapa.service install -Dpm 0644 %{SOURCE7} %{buildroot}%{_unitdir}/ahdapa.socket # sysusers.d — system user/group definition install -Dpm 0644 %{SOURCE4} %{buildroot}%{_sysusersdir}/ahdapa.conf # tmpfiles.d — /var/lib state directory creation install -Dpm 0644 %{SOURCE5} %{buildroot}%{_tmpfilesdir}/ahdapa.conf # Example configuration file install -Dpm 0644 %{SOURCE3} %{buildroot}%{_sysconfdir}/ahdapa/ahdapa.toml.example # SELinux policy module %if %{with selinux} install -Dpm 0644 contrib/selinux/ahdapa.pp \ %{buildroot}%{_datadir}/selinux/packages/%{name}.pp %endif # Tools subpackage: ahdapa-bench CLI binary, criterion harness executables, bench.sh %if %{with tools} install -Dpm 0755 target/rpm/ahdapa-bench \ %{buildroot}%{_bindir}/ahdapa-bench install -dm 0755 %{buildroot}%{_libexecdir}/ahdapa-bench # Bench targets with harness=false are built to target/release/deps/{name}-{hash}. # Find each one by name prefix (hash suffix is not known at install time). for bench_name in client_credentials auth_code introspect device_flow; do bench_exe=$(find target/release/deps -maxdepth 1 -name "${bench_name}-*" \ -type f -perm /111 | head -1) test -n "$bench_exe" || { echo "ERROR: bench $bench_name not found in target/release/deps/"; exit 1; } install -pm 0755 "$bench_exe" \ %{buildroot}%{_libexecdir}/ahdapa-bench/${bench_name} done install -Dpm 0755 contrib/bench/bench.sh \ %{buildroot}%{_datadir}/ahdapa/bench/bench.sh %endif # PAM service file — /etc/pam.d/ahdapa %if %{with pam} install -Dpm 0644 %{SOURCE8} %{buildroot}%{_sysconfdir}/pam.d/ahdapa %endif # SPIFFE Workload Proxy %if %{with spiffe_proxy} install -Dpm 0755 target/rpm/ahdapa-spiffe-proxy \ %{buildroot}%{_bindir}/ahdapa-spiffe-proxy install -Dpm 0644 %{SOURCE9} %{buildroot}%{_unitdir}/ahdapa-spiffe-proxy.service install -Dpm 0644 %{SOURCE10} %{buildroot}%{_sysusersdir}/ahdapa-spiffe-proxy.conf install -Dpm 0644 %{SOURCE11} \ %{buildroot}%{_sysconfdir}/ahdapa/spiffe-proxy.toml.example %endif # Management web UI static assets → %%{_datadir}/ahdapa/webui/ %if %{with webui} install -dm 0755 %{buildroot}%{_datadir}/ahdapa/webui cp -a webui/dist/. %{buildroot}%{_datadir}/ahdapa/webui/ %endif # ── Check ────────────────────────────────────────────────────────────────────── %if %{with check} %check # Documentation tests require external infrastructure (LDAP server, Kerberos # KDC) not available inside the mock build environment. %cargo_test -- --workspace --lib --bins --no-default-features --features %{_ahdapa_features} %endif # ── Systemd scriptlets ───────────────────────────────────────────────────────── %pre %sysusers_create_compat %{SOURCE4} %post %systemd_post ahdapa.service ahdapa.socket %tmpfiles_create %{_tmpfilesdir}/ahdapa.conf %if %{with selinux} semodule -i %{_datadir}/selinux/packages/%{name}.pp 2>/dev/null || : restorecon -R %{_bindir}/ahdapa %{_sysconfdir}/ahdapa \ %{_sharedstatedir}/ahdapa /run/ahdapa 2>/dev/null || : %endif %preun %systemd_preun ahdapa.service ahdapa.socket %postun %systemd_postun_with_restart ahdapa.service ahdapa.socket %if %{with selinux} if [ $1 -eq 0 ]; then semodule -r ahdapa 2>/dev/null || : fi %endif # ── SPIFFE Workload Proxy scriptlets ────────────────────────────────────────── %if %{with spiffe_proxy} %pre -n ahdapa-spiffe-proxy %sysusers_create_compat %{SOURCE10} %post -n ahdapa-spiffe-proxy %systemd_post ahdapa-spiffe-proxy.service %preun -n ahdapa-spiffe-proxy %systemd_preun ahdapa-spiffe-proxy.service %postun -n ahdapa-spiffe-proxy %systemd_postun_with_restart ahdapa-spiffe-proxy.service %endif %changelog %autochangelog