<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Far away to be identical</title>
    <description>Identity management chaos or a development of a fun</description>
    <link>https://vda.li/en/</link>
    <atom:link href="https://vda.li/en/freeipa.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Sat, 04 Apr 2026 23:21:24 +0300</pubDate>
    <lastBuildDate>Sat, 04 Apr 2026 23:21:24 +0300</lastBuildDate>
    <generator>Jekyll v4.4.1</generator>
    
    
    
    
    
      <item>
        <title>kurbu5: MIT Kerberos plugins in Rust</title>
        <description>&lt;p&gt;For a couple of years, Andreas Schneider and I have been working on a project we call the ‘local authentication hub’: an effort to use the Kerberos protocol to track authentication and authorization context for applications, regardless of whether the system they run on is enrolled into a larger organizational domain or is standalone. We aim to reuse the code and experience we got while developing Samba and FreeIPA over the past twenty years.&lt;/p&gt;

&lt;h2 id=&quot;local-authentication-hub&quot;&gt;Local authentication hub&lt;/h2&gt;

&lt;p&gt;The local authentication hub relies on a Kerberos KDC available on demand on each system. We achieved this by allowing MIT Kerberos to communicate over UNIX domain sockets. On Linux systems, systemd allows processes to be started on demand when someone connects to a UNIX domain socket, and MIT Kerberos 1.22 has support for this mode.&lt;/p&gt;

&lt;p&gt;A KDC accessible over a UNIX domain socket is not very useful in itself: it is only available within the context of a single machine (or a single container, or pod, if UNIX domain sockets are shared across multiple containers). Otherwise, it is a fully featured KDC with its own quirks. And we can start looking at what could be improved based on the enhanced context locality we have achieved. For example, a KDB driver can see host-specific network interfaces and thus be able to react to requests such as &lt;code&gt;host/&amp;lt;ip.ad.dr.ess&amp;gt;@LOCALKDC-REALM&lt;/code&gt; dynamically—something that a centrally-managed KDC would only do through statically registered service principal names (SPNs), which are a pain to update as machines move across networks.&lt;/p&gt;

&lt;p&gt;Adding support for dynamic features means new code needs to be written. MIT Kerberos is written in C, so our choices are either to continue writing in C or to integrate with whatever new language we choose. Initially, we kept the local KDC database driver written in C and decided to build the infrastructure we need in Rust. The end goal is to have most bits written in Rust.&lt;/p&gt;

&lt;p&gt;The local KDC database isn’t supposed to handle millions of principal entries, but even for millions of them, MIT Kerberos has a pretty good default database driver built on LMDB: &lt;code&gt;klmdb&lt;/code&gt;. We wanted to get out of the data store business and instead focus on higher-level logic. Thus, we made the same change I made in Samba around 2003 for virtual file system modules: we introduced support for stackable KDB drivers. This is also a part of the MIT Kerberos 1.22 release: a KDB driver implementation can ask the KDC to load a different KDB driver and choose to delegate some requests to it. The local KDC driver is using &lt;code&gt;klmdb&lt;/code&gt; for that purpose.&lt;/p&gt;

&lt;p&gt;With the database handled for us by &lt;code&gt;klmdb&lt;/code&gt;, we focused on the local KDC-specific logic. We wanted to dynamically discover user principals from the operating system so that administrators do not need to maintain separate databases for them. systemd provides a userdb API to query such information over a varlink interface (also available over a UNIX domain socket) in a structured way, using JSON format. Thus, the &lt;a href=&quot;https://gitlab.com/kirmes/kirmes&quot;&gt;Kirmes&lt;/a&gt; project was born. Kirmes is a Rust data library backed by the userdb API. It handles varlink communication through the wonderful &lt;a href=&quot;https://github.com/z-galaxy/zlink&quot;&gt;Zlink&lt;/a&gt; library and exposes both asynchronous and synchronous access to user and group information.&lt;/p&gt;

&lt;p&gt;The local KDC database driver prototype used the Kirmes C API. We demonstrated it at &lt;a href=&quot;https://archive.fosdem.org/2025/schedule/event/fosdem-2025-5618-localkdc-a-general-local-authentication-hub/&quot;&gt;FOSDEM 2025&lt;/a&gt;: a user lookup is done over varlink, and if a user is present on the system, their Kerberos key is then looked up in &lt;code&gt;klmdb&lt;/code&gt; using a specially-formatted &lt;code&gt;userdb:&amp;lt;username&amp;gt;&lt;/code&gt; principal. You still need to handle those keys somehow, but there is a way to avoid that: use RADIUS.&lt;/p&gt;

&lt;h2 id=&quot;pre-authentication&quot;&gt;Pre-authentication&lt;/h2&gt;

&lt;p&gt;A bit of historical reference. In 2012, Red Hat collaborated with MIT to introduce a &lt;a href=&quot;https://k5wiki.kerberos.org/wiki/Projects/OTPOverRADIUS&quot;&gt;KDC-side implementation&lt;/a&gt; of &lt;a href=&quot;https://datatracker.ietf.org/doc/html/rfc6560&quot;&gt;RFC 6560&lt;/a&gt; (the OTP pre-authentication mechanism; at that point implemented in a proprietary solution by the RSA corporation). This mechanism allowed the KDC to get a hint out of a KDB driver and ask a RADIUS server to authenticate the credentials provided by the Kerberos client. Unlike traditional Kerberos symmetric keys, in this case, the client is sending a plain-text credential over the Kerberos protocol, and this credential can be forwarded to the RADIUS server. The plain-text nature of the RADIUS credential requires the use of a secure communication channel, and a good part of RFC 6560 relies on Flexible Authentication Secure Tunneling (FAST, &lt;a href=&quot;https://datatracker.ietf.org/doc/html/rfc6113&quot;&gt;RFC6113&lt;/a&gt;), where a pre-existing Kerberos ticket is used to encrypt the content of that tunnel.&lt;/p&gt;

&lt;p&gt;Since ~2013, FreeIPA has used this mechanism to provide multi-factor authentication mechanisms: HOTP/TOTP tokens, RADIUS proxying to remote servers, the OAuth2 device authorization grant flow, and FIDO2 tokens. The list of mechanisms can be extended, as long as the model fits into the somewhat constrained Kerberos exchange flow. FreeIPA handles all communication from the KDC side via a local UNIX domain socket-activated daemon, &lt;code&gt;ipa-otpd&lt;/code&gt;, which performs a user principal lookup and then decides on the details of how that user will be authenticated.&lt;/p&gt;

&lt;p&gt;For the local KDC case, we used a similar approach but wrote a simplified version, &lt;code&gt;localkdc-pam-auth&lt;/code&gt;, which uses PAM to authenticate user credentials. It works well and allows for a drop-in replacement: once the local KDC is set up, users defined on the system will automatically be able to receive Kerberos tickets, with no need to change any passwords or migrate their credentials into the Kerberos KDC. All we need now is the business logic to guide the KDC to use the OTP pre-authentication mechanism so that our RADIUS ‘proxy’ (&lt;code&gt;localkdc-pam-auth&lt;/code&gt;) gets activated. This logic is implemented and will be available in the first localkdc release soon.&lt;/p&gt;

&lt;h2 id=&quot;api-bindings&quot;&gt;API bindings&lt;/h2&gt;

&lt;p&gt;But back to the KDC side. As mentioned above, our goal was to write the local KDC database driver in a modern, safe language. Interfacing Rust with the MIT Kerberos KDC means building an interface that allows aligning code on both sides. This is what this blog is actually about (sorry for the long prelude…): how to make an MIT Kerberos KDB driver in Rust.&lt;/p&gt;

&lt;p&gt;Today I published &lt;a href=&quot;https://codeberg.org/abbra/kurbu5&quot;&gt;Kurbu5&lt;/a&gt;, a project that aims to provide these API bindings to Rust. The name is a transliteration of “krb5” into Mesopotamian cuneiform phonology: Kurbu-ḫamšat-qaqqadī—”The Blessed Five-Headed One”.&lt;/p&gt;

&lt;p&gt;Creating API bindings is tedious work: there are many interfaces, each representing multiple functions and structures. MIT Kerberos has 12 interfaces which altogether expose roughly 117 methods that plugin authors implement, backed by around 70 supporting types (data structures passed into and out of those methods). It all sounds like a Tolkien tale: nine interfaces for core Kerberos functionality (checking password quality, mapping hostnames to Kerberos realms, mapping Kerberos principals to local accounts, selecting which credential cache to use, handling pre-authentication on both the client and server side, enforcing KDC policy, authorizing PKINIT certificates, and auditing events on the KDC side), the database backend interface, and two administrative interfaces. This is something that could be automated with agentic workflows—which I did to allow a parallel porting effort. The resulting agent &lt;a href=&quot;https://codeberg.org/abbra/kurbu5/src/branch/main/.agents/agents/implement-plugin.md&quot;&gt;instructions&lt;/a&gt; are useful artifacts in themselves: they show how to work when porting MIT Kerberos C code to Rust.&lt;/p&gt;

&lt;p&gt;The result is split over several Rust crates to allow targeted reuse. The bulk of the code lives in three crates. The core Kerberos plugin crate (kurbu5-rs) is the largest at around 12,600 lines. The database backend crate (kurbu5-kdb-rs) follows at 5,600 lines, and the administration crate (kurbu5-kadm5-rs) at 3,100 lines. The remaining crates—the proc-macro derives and the raw FFI sys crates—are much smaller, with the sys crates being almost trivially thin (the KDB and kadm5 ones are under 40 lines each, since they mostly just re-export bindings from the main sys crate).&lt;/p&gt;

&lt;p&gt;All crates are available on &lt;code&gt;crates.io&lt;/code&gt; and share the same MIT license as the original MIT Kerberos.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://crates.io/crates/kurbu5-sys&quot;&gt;kurbu5-sys&lt;/a&gt; — Raw FFI bindings to the MIT Kerberos libkrb5 and KDB plugin API&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://crates.io/crates/kurbu5-derive&quot;&gt;kurbu5-derive&lt;/a&gt; — Proc-macro derives for kurbu5-rs non-KDB plugin interfaces&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://crates.io/crates/kurbu5-rs&quot;&gt;kurbu5-rs&lt;/a&gt; — Safe, idiomatic Rust API for writing MIT Kerberos non-KDB plugin modules&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://crates.io/crates/kurbu5-kdb-sys&quot;&gt;kurbu5-kdb-sys&lt;/a&gt; — KDB plugin API re-export — thin wrapper over kurbu5-sys adding libkdb5 linkage&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://crates.io/crates/kurbu5-kdb-derive&quot;&gt;kurbu5-kdb-derive&lt;/a&gt; — Proc-macro derive for kurbu5-kdb-rs KDB driver plugins&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://crates.io/crates/kurbu5-kdb-rs&quot;&gt;kurbu5-kdb-rs&lt;/a&gt; — Safe, idiomatic Rust API for writing MIT Kerberos KDB driver plugins&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://crates.io/crates/kurbu5-kadm5-sys&quot;&gt;kurbu5-kadm5-sys&lt;/a&gt; — KADM5 plugin API bindings — links libkadm5srv_mit and re-exports kurbu5-sys types&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://crates.io/crates/kurbu5-kadm5-derive&quot;&gt;kurbu5-kadm5-derive&lt;/a&gt; — Proc-macro derives for kurbu5-kadm5-rs KADM5_AUTH and KADM5_HOOK plugin interfaces&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://crates.io/crates/kurbu5-kadm5-rs&quot;&gt;kurbu5-kadm5-rs&lt;/a&gt; — Safe, idiomatic Rust API for writing MIT Kerberos KADM5_AUTH and KADM5_HOOK plugin modules&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the localkdc project, we use kurbu5 to build a KDB driver and provide our audit plugin. We also have an experimental re-implementation of the OTP pre-authentication mechanism, both client and KDC sides, that was used to test interoperability with MIT Kerberos versions. The core of the KDB driver is ~520 lines of heavily documented Rust code, mostly handling business logic.&lt;/p&gt;
</description>
        <pubDate>Sat, 04 Apr 2026 22:10:00 +0300</pubDate>
        <link>https://vda.li/en/posts/2026/04/04/kurbu5/</link>
        <guid isPermaLink="true">https://vda.li/en/posts/2026/04/04/kurbu5/</guid>
        
        <category>rust</category>
        
        <category>freeipa</category>
        
        <category>localkdc</category>
        
        <category>kerberos</category>
        
        <category>samba</category>
        
        <category>fedora</category>
        
        
        <category>posts</category>
        
      </item>
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
      <item>
        <title>ASN.1 for legacy apps: Synta</title>
        <description>&lt;p&gt;Pretty much everything I deal with requires parsing ASN.1 encodings. ASN.1 definitions published as part of internet RFCs: certificates are encoded using DER, LDAP exchanges use BER, Kerberos packets are using DER as well. ASN.1 use is a never ending source of security issues in pretty much all applications. Having safer ASN.1 processing is important to any application developer.&lt;/p&gt;

&lt;p&gt;In FreeIPA we are using three separate ASN.1 libraries: &lt;code&gt;pyasn1&lt;/code&gt; and &lt;code&gt;x509&lt;/code&gt; (part of PyCA) for Python code, and &lt;code&gt;asn1c&lt;/code&gt; code generator for C code. In fact, we use more: LDAP server plugins also use OpenLDAP’s &lt;code&gt;lber&lt;/code&gt; library, while Kerberos KDC plugins also use internal MIT Kerberos parsers.&lt;/p&gt;

&lt;p&gt;The PyCA developers noted in their &lt;a href=&quot;https://cryptography.io/en/latest/statements/state-of-openssl/&quot;&gt;State of OpenSSL&lt;/a&gt; statement:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;[…] when pyca/cryptography migrated X.509 certificate parsing from OpenSSL to our own Rust code, we got a 10x performance improvement relative to OpenSSL 3 (n.b., some of this improvement is attributable to advantages in our own code, but much is explainable by the OpenSSL 3 regressions). Later, moving public key parsing to our own Rust code made end-to-end X.509 path validation 60% faster — just improving key loading led to a 60% end-to-end improvement, that’s how extreme the overhead of key parsing in OpenSSL was.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That’s 16x performance improvement over the OpenSSL 3. OpenSSL did improve their performance since then but it still pays an overhead for a very flexible design to allow loading cryptographic implementations from dynamic modules (providers). Enablement for externally-provided modules is essential to allow adding new primitives and support for government-enforced standards (such as FIPS 140) where implementations have to be validated in advance and code changes cannot come without expensive and slow re-validation process.&lt;/p&gt;

&lt;p&gt;Nevertheless, in FreeIPA we focus on integrating with Linux distributions. Fedora, CentOS Stream, and RHEL enforce crypto consolidation rules, where all packaged applications must be using the same crypto primitives provided by the operating system. We can process metadata ourselves but all cryptographic operations still have to go through OpenSSL and NSS. And paying large performance costs during metadata processing would be hurting to infrastructure components such as FreeIPA.&lt;/p&gt;

&lt;p&gt;FreeIPA is a large beast. Aside from its management component, written in Python, it has more than a dozen plugins for 389-ds LDAP server, plugins for MIT Kerberos KDC, plugins for Samba, and tight integration with SSSD, all written in C. Its default certificate authority software, Dogtag PKI, is written in Java and relies on own stack of Java and C dependencies. We are using PyCA’s x509 module for certificate processing in Python code but we cannot use it and underlying ASN.1 libraries in C as those libraries aren’t exposed to C applications or intentionally limited in their functionality to PKI-related tasks.&lt;/p&gt;

&lt;p&gt;For the 2026-2028, I’m focusing on enabling FreeIPA to handle post-quantum cryptography (PQC), as a part of the &lt;a href=&quot;https://qarc.vut.cz&quot;&gt;Quantum-Resistant Cryptography in Practice (QARC)&lt;/a&gt; project. The project is funded by the European Union under the Horizon Europe framework programme (Grant Agreement No. 101225691) and supported by the European Cybersecurity Competence Centre. One of well publicized aspects of moving to PQC certificates is their sizes. The following table 5 is from &lt;a href=&quot;https://datatracker.ietf.org/doc/draft-ietf-pquip-pqc-engineers/&quot;&gt;Post-Quantum Cryptography for Engineers&lt;/a&gt; IETF draft summarizes it well:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;PQ Security Level&lt;/th&gt;
      &lt;th&gt;Algorithm&lt;/th&gt;
      &lt;th&gt;Public key size (bytes)&lt;/th&gt;
      &lt;th&gt;Private key size (bytes)&lt;/th&gt;
      &lt;th&gt;Signature size(bytes)&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Traditional&lt;/td&gt;
      &lt;td&gt;RSA2048&lt;/td&gt;
      &lt;td&gt;256&lt;/td&gt;
      &lt;td&gt;256&lt;/td&gt;
      &lt;td&gt;256&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Traditional&lt;/td&gt;
      &lt;td&gt;ECDSA-P256&lt;/td&gt;
      &lt;td&gt;64&lt;/td&gt;
      &lt;td&gt;32&lt;/td&gt;
      &lt;td&gt;64&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;FN-DSA-512&lt;/td&gt;
      &lt;td&gt;897&lt;/td&gt;
      &lt;td&gt;1281&lt;/td&gt;
      &lt;td&gt;666&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;2&lt;/td&gt;
      &lt;td&gt;ML-DSA-44&lt;/td&gt;
      &lt;td&gt;1312&lt;/td&gt;
      &lt;td&gt;2560&lt;/td&gt;
      &lt;td&gt;2420&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;3&lt;/td&gt;
      &lt;td&gt;ML-DSA-65&lt;/td&gt;
      &lt;td&gt;1952&lt;/td&gt;
      &lt;td&gt;4032&lt;/td&gt;
      &lt;td&gt;3309&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;5&lt;/td&gt;
      &lt;td&gt;FN-DSA-1024&lt;/td&gt;
      &lt;td&gt;1793&lt;/td&gt;
      &lt;td&gt;2305&lt;/td&gt;
      &lt;td&gt;1280&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;5&lt;/td&gt;
      &lt;td&gt;ML-DSA-87&lt;/td&gt;
      &lt;td&gt;2592&lt;/td&gt;
      &lt;td&gt;4896&lt;/td&gt;
      &lt;td&gt;4627&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Public keys for ML-DSA-65 certificates 7.6x bigger than RSA-2048 ones. You need to handle public keys in multiple situations: when performing certificates’ verification against known certificate authorities (CAs), when matching their properties for validation and identity derivation during authorization, when storing them. FreeIPA uses LDAP as a backend, so storing 7.6 times more data directly affects your scalability when number of users or machines (or Kerberos services) grow up. And since certificates are all ASN.1 encoded, I naturally wanted to establish a performance baseline to ASN.1 parsing.&lt;/p&gt;

&lt;h3 id=&quot;synta-asn1-library&quot;&gt;Synta, ASN.1 library&lt;/h3&gt;

&lt;p&gt;I started with a small task: created a Rust library, &lt;code&gt;synta&lt;/code&gt;, to decode and encode ASN.1 with the help of AI tooling. It quickly grew up to have its own ASN.1 schema parser and code generation tool. With those in place, I started generating more code, this time to process X.509 certificates, handle Kerberos packet structures, and so on. Throwing different tasks at Claude Code led to iterative improvements. Over couple months we progressed to a project with more than 60K lines of Rust code.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Language&lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;files&lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;blank&lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;comment&lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;code&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Rust&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;207&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;9993&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;17492&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;67284&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Markdown&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;52&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;5619&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;153&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;18059&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Python&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;41&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;2383&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;2742&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;7679&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;C&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;17&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;852&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;889&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;4333&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Bourne Shell&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;8&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;319&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;482&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;1640&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;C/C++ Header&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;4&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;319&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;1957&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;1138&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;TOML&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;20&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;196&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;97&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;896&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;YAML&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;1&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;20&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;46&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;561&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;make&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;4&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;166&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;256&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;493&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;CMake&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;3&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;36&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;25&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;150&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;JSON&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;6&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;38&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;diff&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;1&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;6&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;13&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;29&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;SUM&lt;/strong&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;364&lt;/strong&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;19909&lt;/strong&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;24152&lt;/strong&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;102300&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;I published some of the &lt;code&gt;synta&lt;/code&gt; crates yesterday on &lt;a href=&quot;https://crates.io/users/abbra&quot;&gt;crates.io&lt;/a&gt;, the whole project is available at &lt;a href=&quot;https://codeberg.org/abbra/synta&quot;&gt;codeberg.org/abbra/synta&lt;/a&gt;. In total, there are 11 crates, though only seven are published (and &lt;code&gt;synta-python&lt;/code&gt; is also available at PyPI):&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Crate&lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;Lines (src/ only)&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;synta&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;10572&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;synta-derive&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;2549&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;synta-codegen&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;17578&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;synta-certificate&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;4549&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;synta-python&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;8953&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;synta-ffi&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;7843&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;synta-krb5&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;2765&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;synta-mtc&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;7876&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;synta-tools&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;707&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;synta-bench&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;synta-fuzz&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;3551&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Benchmarking, fuzzer, and tools aren’t published. They only needed for development purposes.&lt;/p&gt;

&lt;h3 id=&quot;performance&quot;&gt;Performance&lt;/h3&gt;

&lt;p&gt;The numbers below were obtained on Lenovo ThinkPad P1 Gen 5, 12th Gen Intel(R) Core(TM) i7-12800H, 64 GB RAM, on Fedora 42. This is pretty much a 3-4 years old hardware.&lt;/p&gt;

&lt;p&gt;Benchmarking is what brought this project to life, let’s look at the numbers. When dealing with certificates, ASN.1 encoding can be parsed in different ways: you can visit every structure or stop at outer shells and only visit the remaining nested structures when you really need them. The former is “parse+fields” and the latter is “parse-only” in the following table that summarizes comparison between &lt;code&gt;synta&lt;/code&gt; and various Rust crates (and OpenSSL/NSS which were accessible through their Rust FFI bindings):&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Library&lt;/th&gt;
      &lt;th&gt;Parse-only&lt;/th&gt;
      &lt;th&gt;Parse+fields&lt;/th&gt;
      &lt;th&gt;vs synta (parse-only)&lt;/th&gt;
      &lt;th&gt;vs synta (parse+fields)&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;synta&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;0.48 µs&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;1.32 µs&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;—&lt;/td&gt;
      &lt;td&gt;—&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;cryptography-x509&lt;/td&gt;
      &lt;td&gt;1.45 µs&lt;/td&gt;
      &lt;td&gt;1.43 µs&lt;/td&gt;
      &lt;td&gt;3.0× slower&lt;/td&gt;
      &lt;td&gt;1.1× slower&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;x509-parser&lt;/td&gt;
      &lt;td&gt;2.01 µs&lt;/td&gt;
      &lt;td&gt;1.99 µs&lt;/td&gt;
      &lt;td&gt;4.2× slower&lt;/td&gt;
      &lt;td&gt;1.5× slower&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;x509-cert&lt;/td&gt;
      &lt;td&gt;3.16 µs&lt;/td&gt;
      &lt;td&gt;3.15 µs&lt;/td&gt;
      &lt;td&gt;6.6× slower&lt;/td&gt;
      &lt;td&gt;2.4× slower&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;NSS&lt;/td&gt;
      &lt;td&gt;7.90 µs&lt;/td&gt;
      &lt;td&gt;7.99 µs&lt;/td&gt;
      &lt;td&gt;16× slower&lt;/td&gt;
      &lt;td&gt;6.1× slower&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;rust-openssl&lt;/td&gt;
      &lt;td&gt;15.4 µs&lt;/td&gt;
      &lt;td&gt;15.1 µs&lt;/td&gt;
      &lt;td&gt;32× slower&lt;/td&gt;
      &lt;td&gt;11× slower&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;ossl&lt;/td&gt;
      &lt;td&gt;16.1 µs&lt;/td&gt;
      &lt;td&gt;15.8 µs&lt;/td&gt;
      &lt;td&gt;33× slower&lt;/td&gt;
      &lt;td&gt;12× slower&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;“Parse+fields” tests access every named field: serial number, issuer/subject DNs, signature algorithm OID, signature bytes, validity period, public key algorithm OID, public key bytes, and version. The “parse+fields” speedup is the fair end-to-end comparison: &lt;code&gt;synta&lt;/code&gt;’s parse-only advantage is large because most fields are stored as zero-copy slices deferred until access, while other libraries must materialise all fields eagerly at parse time.&lt;/p&gt;

&lt;p&gt;The dominant cost in X.509 parsing is Distinguished Name traversal: a certificate’s issuer and subject each contain a SEQUENCE OF SET OF SEQUENCE with per-attribute OID lookup. &lt;code&gt;synta&lt;/code&gt; defers this entirely by storing the &lt;code&gt;Name&lt;/code&gt; as a &lt;code&gt;RawDer&amp;lt;&apos;a&amp;gt;&lt;/code&gt; — a pointer+length into the original input with no decoding. &lt;code&gt;cryptography-x509&lt;/code&gt; takes a similar deferred approach. The &lt;code&gt;nom&lt;/code&gt;-based and &lt;code&gt;RustCrypto&lt;/code&gt; libraries decode Names eagerly. &lt;code&gt;NSS&lt;/code&gt; goes further and formats them into C strings, which is the dominant fraction of its 16× parse overhead.&lt;/p&gt;

&lt;p&gt;For benchmarking I used certificates from PyCA test vectors. There are few certificates with different properties, so we parse them multiple times and then average numbers:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Certificate&lt;/th&gt;
      &lt;th&gt;synta&lt;/th&gt;
      &lt;th&gt;cryptography-x509&lt;/th&gt;
      &lt;th&gt;x509-parser&lt;/th&gt;
      &lt;th&gt;x509-cert&lt;/th&gt;
      &lt;th&gt;NSS&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;cert_00 (NoPolicies)&lt;/td&gt;
      &lt;td&gt;1333.7 ns&lt;/td&gt;
      &lt;td&gt;1386.7 ns&lt;/td&gt;
      &lt;td&gt;1815.9 ns&lt;/td&gt;
      &lt;td&gt;2990.6 ns&lt;/td&gt;
      &lt;td&gt;7940.3 ns&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;cert_01 (SamePolicies-1)&lt;/td&gt;
      &lt;td&gt;1348.8 ns&lt;/td&gt;
      &lt;td&gt;1441.0 ns&lt;/td&gt;
      &lt;td&gt;2033.4 ns&lt;/td&gt;
      &lt;td&gt;3174.3 ns&lt;/td&gt;
      &lt;td&gt;7963.8 ns&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;cert_02 (SamePolicies-2)&lt;/td&gt;
      &lt;td&gt;1338.6 ns&lt;/td&gt;
      &lt;td&gt;1440.1 ns&lt;/td&gt;
      &lt;td&gt;2120.1 ns&lt;/td&gt;
      &lt;td&gt;3205.6 ns&lt;/td&gt;
      &lt;td&gt;8206.8 ns&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;cert_03 (anyPolicy)&lt;/td&gt;
      &lt;td&gt;1362.4 ns&lt;/td&gt;
      &lt;td&gt;1468.3 ns&lt;/td&gt;
      &lt;td&gt;2006.2 ns&lt;/td&gt;
      &lt;td&gt;3194.5 ns&lt;/td&gt;
      &lt;td&gt;7902.4 ns&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;cert_04 (AnyPolicyEE)&lt;/td&gt;
      &lt;td&gt;1232.9 ns&lt;/td&gt;
      &lt;td&gt;1424.7 ns&lt;/td&gt;
      &lt;td&gt;1968.6 ns&lt;/td&gt;
      &lt;td&gt;3168.1 ns&lt;/td&gt;
      &lt;td&gt;7913.1 ns&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Average&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;1323 ns&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;1432 ns&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;1989 ns&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;3147 ns&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;7985 ns&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The gap between synta (1.32 µs) and cryptography-x509 (1.43 µs) is tighter here than in parse-only (3.0×) because synta’s field access includes two &lt;code&gt;format_dn()&lt;/code&gt; calls (~800 ns combined) that cryptography-x509 does for effectively free (its offsets were computed at parse time). Synta leads by ~8% overall.&lt;/p&gt;

&lt;p&gt;Now, when parsing PQC certificates, an interesting thing happens. First, it is faster to parse ML-DSA than traditional certificates.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Certificate&lt;/th&gt;
      &lt;th&gt;synta&lt;/th&gt;
      &lt;th&gt;cryptography-x509&lt;/th&gt;
      &lt;th&gt;x509-parser&lt;/th&gt;
      &lt;th&gt;x509-cert&lt;/th&gt;
      &lt;th&gt;NSS&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;ML-DSA-44&lt;/td&gt;
      &lt;td&gt;1030.9 ns&lt;/td&gt;
      &lt;td&gt;1256.4 ns&lt;/td&gt;
      &lt;td&gt;1732.2 ns&lt;/td&gt;
      &lt;td&gt;2666.0 ns&lt;/td&gt;
      &lt;td&gt;7286.9 ns&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;ML-DSA-65&lt;/td&gt;
      &lt;td&gt;1124.9 ns&lt;/td&gt;
      &lt;td&gt;1237.5 ns&lt;/td&gt;
      &lt;td&gt;1690.5 ns&lt;/td&gt;
      &lt;td&gt;2664.2 ns&lt;/td&gt;
      &lt;td&gt;7222.1 ns&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;ML-DSA-87&lt;/td&gt;
      &lt;td&gt;1102.6 ns&lt;/td&gt;
      &lt;td&gt;1226.5 ns&lt;/td&gt;
      &lt;td&gt;1727.2 ns&lt;/td&gt;
      &lt;td&gt;2696.6 ns&lt;/td&gt;
      &lt;td&gt;7284.6 ns&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Average&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;1086 ns&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;1240 ns&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;1717 ns&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;2675 ns&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;7265 ns&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;code&gt;synta&lt;/code&gt;’s ML-DSA parse+fields (1.09 µs) is faster than its traditional parse+fields (1.32 µs)
because ML-DSA test certificates have shorter Distinguished Names (one attribute each in issuer and subject vs multiple attributes in traditional certificates in the test above). The signature BIT STRING — which is 2,420–4,627 bytes for ML-DSA — is accessed as a zero-copy slice with no size-dependent cost.&lt;/p&gt;

&lt;h3 id=&quot;processing-ca-databases&quot;&gt;Processing CA databases&lt;/h3&gt;

&lt;p&gt;Imaging your app needs to test whether the certificate presented by a client is known to you (e.g. belongs to a trusted CAs set). A library like OpenSSL looks at the client’s certificate, extracts identifiers of the certificate issuer, looks up whether such issuer is known in the CA database. That would require looking up properties of the certificates in the database. The fast we can do that, the better.&lt;/p&gt;

&lt;p&gt;All those numbers in the previous section are for a single certificate being parsed millions of times. In a real app we often need to validate the certificate against a system-wide database of certificate authorities. The database used by Fedora and other Linux distributions comes from Firefox. It contains 180 self-signed root CA certificates for all public CAs with diverse key types (RSA 2048/4096, ECDSA P-256/P-384) and DN structures. The median cert by DER size is “Entrust.net Premium 2048 Secure Server CA” (1,070 bytes); the benchmark uses this cert for single-certificate and field-access sub-benchmarks to get stable results that are not sensitive to certificate-size outliers.&lt;/p&gt;

&lt;p&gt;Another data I tried to benchmark against is 9,898 certificates from the Common CA Database (CCADB), covering the full multi-level hierarchy used by Mozilla, Chrome, Apple, and Microsoft:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;Depth&lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;Count&lt;/th&gt;
      &lt;th&gt;Description&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;919&lt;/td&gt;
      &lt;td&gt;Root CAs (self-signed)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;1&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;6,627&lt;/td&gt;
      &lt;td&gt;Intermediates issued directly by roots&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;2&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;2,212&lt;/td&gt;
      &lt;td&gt;Two levels deep&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;3&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;137&lt;/td&gt;
      &lt;td&gt;Three levels deep&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;4&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;3&lt;/td&gt;
      &lt;td&gt;Four levels deep&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Intermediate CA certificates tend to have more complex DNs and more extensions than the root
CAs in the Mozilla store. The CCADB median cert is “Bayerische SSL-CA-2014-01” (10,432 bytes). These certificates from CCADB cover past 30 years of certificate issuance on the internet.&lt;/p&gt;

&lt;p&gt;To see how those benchmarks would behave if CA roots database would be built with post quantum cryptography, I rebuilt the CCADB corpus as ML-DSA certificates. Nine CCADB certificates were skipped: OpenSSL’s &lt;code&gt;x509 -x509toreq -copy_extensions copy&lt;/code&gt; step failed to convert them to CSR form, typically because those certs use non-standard DER encodings or critical extensions that the &lt;code&gt;x509toreq&lt;/code&gt; pipeline cannot copy into a PKCS#10 request. (The failures are in OpenSSL’s cert→CSR conversion; synta parses all 9,898 original CCADB certs without error.) This leaves 9,889 of the original 9,898 certs in the synthetic database.&lt;/p&gt;

&lt;p&gt;The median cert by DER size is “TrustCor Basic Secure Site (CA1)” (6,705 bytes). ML-DSA certs range from 5,530 B to 16,866 B; the distribution is shifted left relative to the CCADB RSA/ECDSA median (10,432 B) because the smallest CCADB certs (compact root CAs with few extensions) become the new median position after ML-DSA key replacement enlarges all certs uniformly.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Benchmark&lt;/th&gt;
      &lt;th&gt;Library&lt;/th&gt;
      &lt;th&gt;Dataset&lt;/th&gt;
      &lt;th&gt;Time&lt;/th&gt;
      &lt;th&gt;Throughput&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code&gt;synta_parse_all&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;synta&lt;/td&gt;
      &lt;td&gt;Mozilla (180 certs)&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;87.8 µs&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;2.0 M/sec&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code&gt;nss_parse_all&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;NSS&lt;/td&gt;
      &lt;td&gt;Mozilla (180 certs)&lt;/td&gt;
      &lt;td&gt;1.577 ms&lt;/td&gt;
      &lt;td&gt;114 K/sec&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code&gt;openssl_parse_all&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;rust-openssl&lt;/td&gt;
      &lt;td&gt;Mozilla (180 certs)&lt;/td&gt;
      &lt;td&gt;3.552 ms&lt;/td&gt;
      &lt;td&gt;50.7 K/sec&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code&gt;ossl_parse_all&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;ossl&lt;/td&gt;
      &lt;td&gt;Mozilla (180 certs)&lt;/td&gt;
      &lt;td&gt;3.617 ms&lt;/td&gt;
      &lt;td&gt;49.8 K/sec&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code&gt;synta_parse_and_access&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;synta&lt;/td&gt;
      &lt;td&gt;Mozilla (180 certs)&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;261 µs&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;690 K/sec&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code&gt;synta_build_trust_chain&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;synta&lt;/td&gt;
      &lt;td&gt;Mozilla (180 certs)&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;11.6 µs&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;—&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code&gt;synta_parse_all&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;synta&lt;/td&gt;
      &lt;td&gt;CCADB (9,898 certs)&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;5.10 ms&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;1.94 M/sec&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code&gt;nss_parse_all&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;NSS&lt;/td&gt;
      &lt;td&gt;CCADB (9,898 certs)&lt;/td&gt;
      &lt;td&gt;106 ms&lt;/td&gt;
      &lt;td&gt;93 K/sec&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code&gt;openssl_parse_all&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;rust-openssl&lt;/td&gt;
      &lt;td&gt;CCADB (9,898 certs)&lt;/td&gt;
      &lt;td&gt;203 ms&lt;/td&gt;
      &lt;td&gt;48.8 K/sec&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code&gt;ossl_parse_all&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;ossl&lt;/td&gt;
      &lt;td&gt;CCADB (9,898 certs)&lt;/td&gt;
      &lt;td&gt;214 ms&lt;/td&gt;
      &lt;td&gt;46.3 K/sec&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code&gt;synta_parse_and_access&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;synta&lt;/td&gt;
      &lt;td&gt;CCADB (9,898 certs)&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;16.1 ms&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;615 K/sec&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code&gt;synta_parse_roots&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;synta&lt;/td&gt;
      &lt;td&gt;CCADB (919 roots)&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;457.7 µs&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;2.01 M/sec&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code&gt;synta_parse_intermediates&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;synta&lt;/td&gt;
      &lt;td&gt;CCADB (8,979 intermediates)&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;4.735 ms&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;1.90 M/sec&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code&gt;synta_build_dependency_tree&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;synta&lt;/td&gt;
      &lt;td&gt;CCADB (9,898 certs)&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;559 µs&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;—&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code&gt;synta_parse_all&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;synta&lt;/td&gt;
      &lt;td&gt;ML-DSA synth (9,889 certs)&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;5.78 ms&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;1.71 M/sec&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code&gt;nss_parse_all&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;NSS&lt;/td&gt;
      &lt;td&gt;ML-DSA synth (9,889 certs)&lt;/td&gt;
      &lt;td&gt;103 ms&lt;/td&gt;
      &lt;td&gt;96.4 K/sec&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code&gt;openssl_parse_all&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;rust-openssl&lt;/td&gt;
      &lt;td&gt;ML-DSA synth (9,889 certs)&lt;/td&gt;
      &lt;td&gt;239 ms&lt;/td&gt;
      &lt;td&gt;41.4 K/sec&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code&gt;ossl_parse_all&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;ossl&lt;/td&gt;
      &lt;td&gt;ML-DSA synth (9,889 certs)&lt;/td&gt;
      &lt;td&gt;256 ms&lt;/td&gt;
      &lt;td&gt;38.6 K/sec&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code&gt;synta_parse_and_access&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;synta&lt;/td&gt;
      &lt;td&gt;ML-DSA synth (9,889 certs)&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;17.5 ms&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;566 K/sec&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code&gt;synta_parse_roots&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;synta&lt;/td&gt;
      &lt;td&gt;ML-DSA synth (919 roots)&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;463 µs&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;1.98 M/sec&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code&gt;synta_parse_intermediates&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;synta&lt;/td&gt;
      &lt;td&gt;ML-DSA synth (8,970 ints.)&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;5.10 ms&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;1.76 M/sec&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code&gt;synta_build_dependency_tree&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;synta&lt;/td&gt;
      &lt;td&gt;ML-DSA synth (9,889 certs)&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;549 µs&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;—&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;NSS is &lt;strong&gt;18–21× slower&lt;/strong&gt; than &lt;code&gt;synta&lt;/code&gt; across all three datasets; &lt;code&gt;rust-openssl&lt;/code&gt; is &lt;strong&gt;40–41× slower&lt;/strong&gt; and &lt;code&gt;ossl&lt;/code&gt; is &lt;strong&gt;41–44× slower&lt;/strong&gt;. All three C-backed libraries successfully parse ML-DSA certificates (NSS 3.120+ and OpenSSL 3.4+ support ML-DSA natively). NSS’s absolute parse time is nearly identical across CCADB traditional certs (106 ms) and ML-DSA synthetic certs (103 ms) — confirming that NSS’s dominant cost is eager DN formatting at parse time, which depends on DN attribute count rather than the signature algorithm. The slightly lower relative slowdown for NSS on ML-DSA (18× vs 21×) is entirely because synta is slower on ML-DSA (5.78 ms vs 5.10 ms), not because NSS is faster.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;synta&lt;/code&gt;’s throughput is consistent at ~1.7–2.0 M certs/sec across all three datasets, confirming linear O(n) scaling. Parse rate is slightly lower for the ML-DSA synthetic hierarchy (1.71 M/sec) than for the CCADB traditional hierarchy (1.94 M/sec) because the larger ML-DSA SubjectPublicKeyInfo and signature BIT STRING fields add bytes to the tag+length-header scan that synta performs at parse time. The intermediates-only sub-benchmark is slightly lower than roots-only in each dataset (1.76 M/sec vs 1.98 M/sec for ML-DSA; 1.90 M/sec vs 2.01 M/sec for CCADB) because intermediate CAs tend to have more complex DNs and extension lists.&lt;/p&gt;

&lt;p&gt;Finally, individual property access for a pre-parsed certificate, single field read, no allocation unless noted:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Field&lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;Mozilla (1,070 B)&lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;CCADB (10,432 B)&lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;ML-DSA (6,705 B)&lt;/th&gt;
      &lt;th&gt;Notes&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code&gt;issuer_raw&lt;/code&gt; / &lt;code&gt;subject_raw&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;4.1 / 4.1 ns&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;4.2 / 4.1 ns&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;4.5 / 4.4 ns&lt;/td&gt;
      &lt;td&gt;Zero-copy slice&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code&gt;public_key_bytes&lt;/code&gt; / &lt;code&gt;signature_bytes&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;4.1 / 4.1 ns&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;4.2 / 4.2 ns&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;4.6 / 4.4 ns&lt;/td&gt;
      &lt;td&gt;Zero-copy slice&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code&gt;signature_algorithm&lt;/code&gt; / &lt;code&gt;public_key_algorithm&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;5.9 / 5.4 ns&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;5.9 / 5.5 ns&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;6.3 / 6.4 ns&lt;/td&gt;
      &lt;td&gt;OID → &lt;code&gt;&amp;amp;&apos;static str&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code&gt;serial_number&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;10.9 ns&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;6.8 ns&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;7.5 ns&lt;/td&gt;
      &lt;td&gt;Integer → i64, length-dependent&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code&gt;validity&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;180 ns&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;206 ns&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;231 ns&lt;/td&gt;
      &lt;td&gt;Two time-string allocations&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code&gt;issuer_dn&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;401 ns&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;224 ns&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;246 ns&lt;/td&gt;
      &lt;td&gt;&lt;code&gt;format_dn()&lt;/code&gt; → &lt;code&gt;String&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code&gt;subject_dn&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;404 ns&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;292 ns&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;324 ns&lt;/td&gt;
      &lt;td&gt;&lt;code&gt;format_dn()&lt;/code&gt; → &lt;code&gt;String&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Zero-copy fields (&lt;code&gt;issuer_raw&lt;/code&gt;, &lt;code&gt;subject_raw&lt;/code&gt;, &lt;code&gt;public_key_bytes&lt;/code&gt;, &lt;code&gt;signature_bytes&lt;/code&gt;) cost
~4–5 ns — the price of reading a pointer and length from a struct field. The slightly higher
cost for CCADB and ML-DSA fields vs Mozilla is within measurement noise.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;identify_signature_algorithm()&lt;/code&gt; and &lt;code&gt;identify_public_key_algorithm()&lt;/code&gt; match the OID
component array against a static table and return &lt;code&gt;&amp;amp;&apos;static str&lt;/code&gt; — no allocation, no string
formatting. The ~5–6 ns cost is a few comparisons and a pointer return.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;serial_number&lt;/code&gt; cost depends on the integer’s byte length: the Entrust Mozilla cert carries
a 16-byte serial number (parsed via &lt;code&gt;SmallVec&amp;lt;[u8; 16]&amp;gt;&lt;/code&gt;), while the CCADB and ML-DSA
synthetic medians have shorter serials. At 10.9, 6.8, and 7.5 ns respectively, all are
negligible.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;validity&lt;/code&gt; (~180–231 ns) allocates two strings: UTCTime and GeneralizedTime are formatted
from their raw DER bytes into owned &lt;code&gt;String&lt;/code&gt;s. The two calls account for essentially all
of the cost; the &lt;code&gt;YYMMDDHHMMSSZ&lt;/code&gt; to RFC 3339 formatting is the dominant work.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;format_dn()&lt;/code&gt; is the most variable field: it walks the Name DER bytes, decodes each
SEQUENCE OF SET OF SEQUENCE, looks up each attribute OID by name, and formats the result
into an owned &lt;code&gt;String&lt;/code&gt;. The Mozilla cert’s issuer DN is more complex (multiple attributes,
longer values: 401 ns) than the CCADB median (224 ns) or the ML-DSA synthetic median
(246 ns). The ML-DSA synthetic median’s subject DN (324 ns) is slightly more expensive
than the CCADB median (292 ns) because a different cert occupies the median position after
key replacement. &lt;code&gt;format_dn()&lt;/code&gt; cost is proportional to the DN’s attribute count and string
lengths.&lt;/p&gt;

&lt;h3 id=&quot;why-c-libraries-are-slower&quot;&gt;Why C Libraries Are Slower&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;CERT_NewTempCertificate&lt;/code&gt; (NSS) and OpenSSL’s &lt;code&gt;d2i_X509&lt;/code&gt; perform significantly more work
per certificate than synta:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Eager DN formatting&lt;/strong&gt; — NSS formats the issuer and subject Distinguished Names into
internal C strings during &lt;code&gt;CERT_NewTempCertificate&lt;/code&gt;, even when the caller never reads
them. Distinguished Name formatting is the single most expensive operation in certificate
parsing; doing it unconditionally at parse time accounts for roughly 80% of NSS’s total
parse cost. OpenSSL decodes DN structure eagerly as well.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Arena and heap allocation&lt;/strong&gt; — each NSS certificate allocates a &lt;code&gt;PLArena&lt;/code&gt; block and
copies the full DER buffer into it (&lt;code&gt;copyDER = 1&lt;/code&gt;). OpenSSL allocates from the C heap.
These allocations are additional work beyond decoding.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Library state and locking&lt;/strong&gt; — NSS acquires internal locks on every
&lt;code&gt;CERT_NewTempCertificate&lt;/code&gt; call to update the certificate cache, even when the resulting
certificate is marked as temporary. This serialises concurrent parsing in multi-threaded
applications.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;FFI boundary costs&lt;/strong&gt; — the &lt;code&gt;rust-openssl&lt;/code&gt; and &lt;code&gt;ossl&lt;/code&gt; measurements include the overhead
of crossing from Rust into the C library via &lt;code&gt;extern &quot;C&quot;&lt;/code&gt; calls and pointer marshalling.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;synta&lt;/code&gt; defers all of (1): &lt;code&gt;issuer&lt;/code&gt; and &lt;code&gt;subject&lt;/code&gt; are stored as &lt;code&gt;RawDer&amp;lt;&apos;a&amp;gt;&lt;/code&gt; (borrowed byte
spans) and decoded only when the caller calls &lt;code&gt;format_dn()&lt;/code&gt;. There is no locking, no arena,
and no FFI boundary.&lt;/p&gt;

&lt;p&gt;In these tests I also found out that PyCA’s &lt;code&gt;cryptography-x509&lt;/code&gt; doesn’t have optimizations for multiple accesses to the same fields. It is typically not a problem if you are just loading a certificate and use it once. If you have to return back to it multiple times, that becomes visible and hurts your performance. So I submitted &lt;a href=&quot;https://github.com/pyca/cryptography/pull/14441&quot;&gt;a pull request&lt;/a&gt; to apply some of the optimizations I found with &lt;code&gt;synta&lt;/code&gt;. The pull request had to be split into smaller ones and few of them were already merged, so performance to access issuer, subject, and public key in certificates and to some attributes in CSRs was improved 100x. The rest waits for improvements in PyO3 to save some of memory use.&lt;/p&gt;
</description>
        <pubDate>Mon, 23 Mar 2026 10:33:00 +0200</pubDate>
        <link>https://vda.li/en/posts/2026/03/23/synta/</link>
        <guid isPermaLink="true">https://vda.li/en/posts/2026/03/23/synta/</guid>
        
        <category>asn1</category>
        
        <category>rust</category>
        
        <category>freeipa</category>
        
        <category>kerberos</category>
        
        <category>samba</category>
        
        <category>fedora</category>
        
        
        <category>posts</category>
        
      </item>
    
    
    
    
    
    
    
    
    
    
    
      <item>
        <title>FreeIPA local tests and FOSDEM demos</title>
        <description>&lt;p&gt;&lt;a href=&quot;https://fosdem.org/2025/&quot;&gt;FOSDEM 2025&lt;/a&gt; is behind us. We ran &lt;a href=&quot;https://fosdem.org/2025/schedule/track/iam/.&quot;&gt;Identity and
Access Management devroom&lt;/a&gt; at
FOSDEM. At the devroom, my team did few talks and demos about FreeIPA and
Kerberos. While preparing to those talks, we tried to create demonstrations
that could be repeated by others as well. First, this was an attempt to help
ourselves, as we need to communicate our advances to others in the teams. Then
we started to look at how to show our progress to folks outside of the development
groups.&lt;/p&gt;

&lt;p&gt;We iterated over our tools and finally ended up with something that is based on
what we use in upstream CIs: we use podman containers to run what ends up being
ephemeral VMs hosting the software. This doesn’t give ability to handle all
possible scenarios. It is not a way to run actual production environments as well.
Yet, it allows us a quick reuse and share:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;descriptive definition of the deployment configuration&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;standard tooling to provision the configuration as containers with &lt;code&gt;podman-compose&lt;/code&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;use of Ansible playbooks to run repeatable actions against the hosts, with
inventory taken from the podman-compose integration&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The tool, &lt;a href=&quot;https://github.com/rjeffman/ipalab-config&quot;&gt;&lt;code&gt;ipalab-config&lt;/code&gt;&lt;/a&gt;,
quickly became flexible enough to be used in multiple scenarios. It powers
&lt;code&gt;ansible-freeipa&lt;/code&gt;’s own upstream CI, we aim to reuse it for new FreeIPA Web UI
development and for the FreeIPA workshop.&lt;/p&gt;

&lt;p&gt;For the demos at FOSDEM IAM devroom we put a separate repository that has all
the scenarios and even recording files to reproduce the demos:
&lt;a href=&quot;https://github.com/abbra/freeipa-local-tests/&quot;&gt;&lt;code&gt;freeipa-local-tests&lt;/code&gt;&lt;/a&gt;. You can
try yourself how local authentication hub or IPA-IPA trust or IPA-IPA migration
do work.&lt;/p&gt;

&lt;p&gt;This project demonstrates how complex multi-system FreeIPA deployments can be
tested locally or in your CI/CD. The test environment is built with the help of
&lt;a href=&quot;https://podman.io&quot;&gt;podman&lt;/a&gt; and orchestrated with
&lt;a href=&quot;https://github.com/rjeffman/ipalab-config&quot;&gt;ipalab-config&lt;/a&gt; and
&lt;a href=&quot;https://github.com/containers/podman-compose&quot;&gt;podman-compose&lt;/a&gt; tools. FreeIPA
environment is deployed with the help of
&lt;a href=&quot;https://github.com/freeipa/ansible-freeipa&quot;&gt;ansible-freeipa&lt;/a&gt;. Upstream, we run
these tests in Github Actions as well.&lt;/p&gt;

&lt;h2 id=&quot;demo-labs&quot;&gt;Demo labs&lt;/h2&gt;

&lt;p&gt;Following configurations provided as ‘labs’ that can be reproduced using
&lt;code&gt;ipalab-config&lt;/code&gt; tool and the configurations from this project:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://github.com/abbra/freeipa-local-tests/blob/main/ipalab-config/minimal/README.md&quot;&gt;minimal deployment&lt;/a&gt;, consisting of a
FreeIPA server and a FreeIPA client enrolled into it.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://github.com/abbra/freeipa-local-tests/blob/main/ipalab-config/localkdc/README.md&quot;&gt;local KDC&lt;/a&gt;, consisting of two
standalone machines, not enrolled into any domain. Each machine runs its own
Kerberos KDC exposed to local applications over UNIX domain socket, with socket
activation handled by systemd. See &lt;a href=&quot;https://fosdem.org/2025/schedule/event/fosdem-2025-5618-localkdc-a-general-local-authentication-hub/&quot;&gt;“localkdc - local authentication hub”&lt;/a&gt;
talk at FOSDEM 2025. This is currently a work in progress.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://github.com/abbra/freeipa-local-tests/blob/main/ipalab-config/ipa-migrate/README.md&quot;&gt;FreeIPA deployment migration&lt;/a&gt;,
demonstrating how IPA data can be migrated between separate test and
production deployments. See &lt;a href=&quot;https://fosdem.org/2025/schedule/event/fosdem-2025-5175-freeipa-to-freeipa-migration-current-capabilities-and-use-cases/&quot;&gt;“FreeIPA-to-FreeIPA Migration: Current
Capabilities and Use Cases”&lt;/a&gt;
talk at FOSDEM 2025.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://github.com/abbra/freeipa-local-tests/blob/main/ipalab-config/ipa-trust/README.md&quot;&gt;FreeIPA trust&lt;/a&gt;, demonstrating how two
separate IPA deployments can be set up to trust each other. See &lt;a href=&quot;https://fosdem.org/2025/schedule/event/fosdem-2025-5178-building-cross-domain-trust-between-freeipa-deployments/&quot;&gt;“Building Cross-Domain Trust Between FreeIPA Deployments”&lt;/a&gt; talk at FOSDEM 2025. This is currently a work in progress.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;demo-recordings&quot;&gt;Demo recordings&lt;/h2&gt;

&lt;p&gt;Some of the demo labs have automated recording of the operations that could be performed on them.
Video recording is built upon excellent
&lt;a href=&quot;https://github.com/charmbracelet/vhs&quot;&gt;VHS&lt;/a&gt; tool. A pre-built version for
Fedora is provided in &lt;a href=&quot;https://copr.fedorainfracloud.org/coprs/abbra/vhs/&quot;&gt;COPR
abbra/vhs&lt;/a&gt;. This build also
includes a fix from the upstream
&lt;a href=&quot;https://github.com/charmbracelet/vhs/pull/551&quot;&gt;PR#551&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;minimal-deployment-demo&quot;&gt;Minimal deployment demo&lt;/h3&gt;

&lt;p&gt;This demo recording includes a minimal use of FreeIPA command line:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;an administrator logs into a client system over SSH using a password&lt;/li&gt;
  &lt;li&gt;Kerberos ticket is obtained automatically by the SSSD&lt;/li&gt;
  &lt;li&gt;IPA command line tool can authenticate to IPA server using Kerberos&lt;/li&gt;
&lt;/ul&gt;

&lt;video controls=&quot;&quot; preload=&quot;metadata&quot; onclick=&quot;(function(el){ if(el.paused) el.play(); else el.pause() })(this)&quot;&gt;&lt;source src=&quot;https://vda.li/en/img/2025-freeipa-local-tests/basic-demo.webm&quot; type=&quot;video/webm; codecs=&amp;quot;vp8, vorbis&amp;quot;&quot; /&gt;&lt;/video&gt;

&lt;h3 id=&quot;local-kdc-demo&quot;&gt;Local KDC demo&lt;/h3&gt;

&lt;p&gt;The local KDC demo is more evolved:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;a user logs into their own machine over SSH using a password&lt;/li&gt;
  &lt;li&gt;Kerberos ticket is obtained automatically by the SSSD from the local KDC which is activated on demand&lt;/li&gt;
  &lt;li&gt;User then uses a Kerberos ticket to authenticate to SUDO and obtain root privileges&lt;/li&gt;
  &lt;li&gt;The user also uses the Kerberos ticket to authenticate to Samba server running locally&lt;/li&gt;
  &lt;li&gt;Finally, the user authenticates with Kerberos IAKerb extension to a remotely running Samba server, removing completely a need for NTLM authentication protocol&lt;/li&gt;
&lt;/ul&gt;

&lt;video controls=&quot;&quot; preload=&quot;metadata&quot; onclick=&quot;(function(el){ if(el.paused) el.play(); else el.pause() })(this)&quot;&gt;&lt;source src=&quot;https://vda.li/en/img/2025-freeipa-local-tests/localkdc-demo.webm&quot; type=&quot;video/webm; codecs=&amp;quot;vp8, vorbis&amp;quot;&quot; /&gt;&lt;/video&gt;

&lt;h3 id=&quot;ipa-to-ipa-trust-demo&quot;&gt;IPA to IPA trust demo&lt;/h3&gt;

&lt;p&gt;This is a minimalistic demo of how users and groups from one IPA environment
can be resolved in the other IPA environment. There is a trust agreement
established between both IPA environments, similarly how IPA can establish a
forest level trust with Active Directory.&lt;/p&gt;

&lt;video controls=&quot;&quot; preload=&quot;metadata&quot; onclick=&quot;(function(el){ if(el.paused) el.play(); else el.pause() })(this)&quot;&gt;&lt;source src=&quot;https://vda.li/en/img/2025-freeipa-local-tests/ipa2ipa-trust-demo.webm&quot; type=&quot;video/webm; codecs=&amp;quot;vp8, vorbis&amp;quot;&quot; /&gt;&lt;/video&gt;

</description>
        <pubDate>Fri, 14 Feb 2025 13:15:00 +0200</pubDate>
        <link>https://vda.li/en/posts/2025/02/14/FreeIPA-local-tests/</link>
        <guid isPermaLink="true">https://vda.li/en/posts/2025/02/14/FreeIPA-local-tests/</guid>
        
        <category>freeipa</category>
        
        <category>kerberos</category>
        
        <category>iakerb</category>
        
        <category>localkdc</category>
        
        <category>samba</category>
        
        <category>fedora</category>
        
        
        <category>posts</category>
        
      </item>
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
      <item>
        <title>Local authentication hub</title>
        <description>&lt;p&gt;FOSDEM 2025 is just behind us and it was a great event. I had a chance to talk
about the local authentication hub project. The talk was well received and I got
a lot of questions about the project. We ran Identity and Access Management
devroom for the second time in row and it was a great success. I had two talks
at the IAM devroom, both were process reports on the activity we have announced
at FOSDEM 2024. Now that both recordings of the both talks published, I can
share articles which go into more details.&lt;/p&gt;

&lt;h2 id=&quot;local-authentication-hub&quot;&gt;Local authentication hub&lt;/h2&gt;

&lt;p&gt;Our FOSDEM talk is &lt;a href=&quot;https://fosdem.org/2025/schedule/event/fosdem-2025-5618-localkdc-a-general-local-authentication-hub/&quot;&gt;“localkdc - a general local authentication
hub”&lt;/a&gt;.
You can watch it and come back here for more details.&lt;/p&gt;

&lt;p&gt;But before going into details, let me provide a bit of a background. It is 2025 now
and we should go almost three decades back (ugh!).&lt;/p&gt;

&lt;h3 id=&quot;history-dive&quot;&gt;History dive&lt;/h3&gt;

&lt;p&gt;Authentication on Linux systems is interwoven with the identity of the users.
Once a user logged in, a process is running under a certain POSIX account
identity. Many applications validate the presence of the account prior to the
authentication itself. For example, the OpenSSH server does check the POSIX
account and its properties and if the user was not found, will intentionally
corrupt the password passed to the PAM authentication stack request. An
authentication request will fail but the attempt will be recorded in the system
journal.&lt;/p&gt;

&lt;p&gt;This joint operation between authentication and identification sources in Linux
makes it important to maintain a coherent information state. No wonder that in
corporate environments it is often handled centrally: user and group identities
stored at a central server and sourced from that one by a local software, such
as SSSD. In order to consume these POSIX users and groups, SSSD needs to be
registered with the centralized authority or, in other words, enrolled into the
domain. Domain enrollment allows not only identity and authentication of users:
both the central server and the enrolled client machine can mutually
authenticate each other and be sure they talk to the right authority when
authenticating the user.&lt;/p&gt;

&lt;p&gt;FreeIPA provides a stable mechanism for building a centralized domain
management system. Each user account has POSIX attributes associated with it and
each user account is represented by the Kerberos principal. Kerberos
authentication can be used to transfer the authentication state across multiple
services and provides a chance for services to discover user identity
information beyond POSIX. It also makes strong linking between the POSIX level
identity and authentication structure possible: for example, a Kerberos service
may introspect a Kerberos ticket presented by a user’s client application to see
how this user was authenticated originally: with a password or some specific
passwordless mechanism. Or, perhaps, that a client application performs
operations on behalf of the user after claiming it was authenticated using a
different (non-Kerberos) authentication.&lt;/p&gt;

&lt;p&gt;Local user accounts’ use lacks this experience. Each individual service needs to
reauthenticate a user again and again. Local system login: authenticate.
Elevating privileges through SUDO? Authenticate again, if not explicitly
configured otherwise. Details of the user session state, like how long this
particular session is active, is not checked by the applications, making it also
harder to limit access. There is no information on how this user was
authenticated. Finally, overall user experience between local (standalone)
authentication and domain-enrolled one differs, making it harder to adjust and
educate users.&lt;/p&gt;

&lt;p&gt;Local authentication is also typically password-based. This is not a bad thing
in itself but depending on applications and protocols, worse choices could be
made, security-wise. For example, contemporary SMB 3.11 protocol is quite secure
if authenticated using Kerberos. For non-Kerberos usage, however, it is left to
rely on NTLM authentication protocol which requires use of RC4 stream cipher.
There are multiple attacks known to break RC4-based encryption, yet it is still
used in majority of non-domain joined communications using SMB protocol simply
because there was no (so far) alternative. To be correct, there was always an
alternative, use of Kerberos protocol, but setting it up for individual isolated
systems wasn’t practical.&lt;/p&gt;

&lt;p&gt;The Kerberos protocol assumes the use of three different parties: a client, a
service, and a key distribution center (KDC). In corporate environments a KDC is
part of the domain controller system, a client and a service are both domain
members, computers are enrolled in the domain. The client authenticates to KDC
and obtains a Kerberos ticket granting ticket (TGT). It then requests a service
ticket from the KDC by presenting its TGT and then presents this service ticket
to the service. The service application, on its side, is able to decrypt the
service ticket presented by the client and authenticate the request.&lt;/p&gt;

&lt;p&gt;In the late 2000s Apple realised that for individual computers a number of user
accounts is typically small and a KDC can be run as a service on the individual
computer itself. When both the client and server are on the same computer, this
works beautifully. The only problem is that when a user needs to authenticate to
a different computer’s service, the client cannot reach the KDC hosted on the
other computer because it is not exposed to the network directly. Luckily, MIT
Kerberos folks already thought about this problem a decade prior to that: in
1997 a first idea was published for a Kerberos extension that allowed to tunnel
Kerberos requests over a different application protocol. This specification
became later known as “Initial and Pass Through Authentication Using Kerberos V5
and the GSS-API” (IAKerb). An initial implementation for MIT Kerberos was done
in 2009/2010 while Apple introduced it in 2007 to enable remote access to your
own Mac across the internet. It came in MacOS X 10.5 as a “Back to My Mac”
feature and even got specified in RFC 6281, only to be retired from MacOS in
2019.&lt;/p&gt;

&lt;h3 id=&quot;modern-days&quot;&gt;Modern days&lt;/h3&gt;

&lt;p&gt;In the 2020s Microsoft continued to work on NTLM removal. In 2023 they announced
that all Windows systems will have a local KDC as their local authentication
source, accessible externally via selected applications through the IAKerb
mechanism. By the end of 2024, we have only seen demos published by Microsoft
engineers at various events but this is a promising path forward. Presence of
the local KDC in Windows raises an interoperability requirement: Linux systems
will have to handle access to Windows machines in a standalone environment over
SMB protocol. Authentication is currently done with NTLM, it will eventually be
removed, thus we need to support the IAKerb protocol extension.&lt;/p&gt;

&lt;p&gt;The NTLM removal for Linux systems requires several changes. First, the Samba
server will need to learn how to accept authentication with the IAKerb protocol
extension. Then, Samba client code needs to be able to establish a client
connection and advertise IAKerb protocol extension. For kernel level access, the
SMB filesystem driver needs to learn how to use IAKerb as well, this will also
need to be implemented in the user space cifs-utils package. Finally, to be able
to use the same feature in a pure Linux environment, we need to be able to
deploy Kerberos KDC locally and do it in an easy manner on each machine.&lt;/p&gt;

&lt;p&gt;This is where we had an idea. If we are going to have a local KDC running on
each system, maybe we should use it to handle all authentication and not just
for the NTLM removal? This way we can make both the local and domain-enrolled
user experience the same and provide access locally to a whole set of
authentication methods we support for FreeIPA: passwords, smartcards, one-time
passwords and remote RADIUS server authentication, use of FIDO2 tokens, and
authentication against an external OAuth2 Identity Provider using a device
authorization grant flow.&lt;/p&gt;

&lt;h3 id=&quot;how-local-a-local-kdc-should-be&quot;&gt;How “local” a local KDC should be?&lt;/h3&gt;

&lt;p&gt;On standalone systems it is often not desirable to run daemons continuously.
Also, it is not desirable to expose these services to the connected network if
they really don’t need to be exposed. A common approach to solve this problem is
by providing a local inter-process communication (IPC) mechanism to communicate
with the server components. We chose to expose a local KDC via UNIX domain
sockets. A UNIX domain socket is a well-known mechanism and has known security
properties. With the help of a systemd feature called socket activation, we also
can start local KDC on demand, when a Kerberos client connects over the UNIX
domain socket. Since on local systems actual authentication requests don’t
happen often, this helps to reduce memory and CPU usage in the long run.&lt;/p&gt;

&lt;p&gt;If a local KDC is only accessible over a UNIX domain socket, remote applications
could not get access to it directly. This means they would need to have help
from a server application that can utilize the IAKerb mechanism to pass-through
the communication between a client and the KDC. It would enable us to
authenticate as a local user remotely from a different machine. Due to how the
IAKerb mechanism is designed and integrated into GSS-API, this only allows
password-based authentication. Anything that requires passwordless methods
cannot obtain initial Kerberos authentication over IAKerb, at least at this point.&lt;/p&gt;

&lt;p&gt;Here is &lt;a href=&quot;https://youtu.be/D5vzc2Qo4k0&quot;&gt;a small demo&lt;/a&gt; on Fedora,
using our &lt;code&gt;localkdc&lt;/code&gt; tool to start a local KDC, obtain a Kerberos ticket upon
login. The tickets can then be used effortlessly to authenticate to local
services such as SUDO or Samba. For remote access we rely on Samba support for
IAKerb and authenticate with GSSAPI but local &lt;code&gt;smbclient&lt;/code&gt; uses a password first
to obtain the initial ticket over IAKerb. This is purely a limitation of
the current patches we have to Samba.&lt;/p&gt;

&lt;div class=&quot;embed-container&quot;&gt;
&lt;iframe width=&quot;740&quot; height=&quot;480&quot; src=&quot;https://www.youtube.com/embed/D5vzc2Qo4k0&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;encrypted-media; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt; 
&lt;/div&gt;

&lt;p&gt;Make a pause here and think about the implications. We have an initial Kerberos
ticket from the local system. The Kerberos ticket embeds details of how this
authentication happened. We might have used a password to authenticate, or a
smartcard. Or any other supported pre-authentication methods. We could reuse the
same methods FreeIPA already provides in the centralized environment.&lt;/p&gt;

&lt;p&gt;The Kerberos ticket also can contain details about the user session, including
up to date group membership. It does not currently have that in the local KDC
case but we aim to fix that. This ticket can be used to authenticate to any
GSS-API or Kerberos-aware service on this machine. If a remote machine accepts
Kerberos, it theoretically could accept a ticket presented by a client
application running on the local machine as well. Only, to do that it needs to
be able to communicate with our local KDC and it couldn’t access it.&lt;/p&gt;

&lt;h3 id=&quot;trust-management&quot;&gt;Trust management&lt;/h3&gt;

&lt;p&gt;Luckily, a local KDC deployment is a full-featured Kerberos realm and thus can
establish cross-realm agreements with other Kerberos realms. If two “local” KDC
realms have trust agreements between each other, they can issue cross-realm
Kerberos tickets which applications can present over IAKerb to the remote
“local” KDC. Then a Kerberos ticket to a service running on the target system
can be requested and issued by the system’s local KDC.&lt;/p&gt;

&lt;p&gt;Thus, we can achieve passwordless authentication locally on Linux systems and
have the ability to establish peer to peer agreements across multiple systems,
to allow authentication requests to flow and operate on commonly agreed
credentials. A problem now moves to the management area: how to manage these
peer to peer agreements and permissions in an easy way?&lt;/p&gt;

&lt;h3 id=&quot;systemd-usergroup-api-support&quot;&gt;Systemd User/Group API support&lt;/h3&gt;

&lt;p&gt;MIT Kerberos KDC implementation provides a flexible way to handle Kerberos
principals’ information. A database backend (KDB) implementation can be
dynamically loaded and replaced. This is already used by both FreeIPA and Samba
AD to integrate MIT Kerberos KDC with their own database backends based on different
LDAP server implementations. For a local KDC use case running a full-featured
LDAP server is not required nor intended. However, it would be great if
different applications could expose parts of the data needed by the KDB
interfaces and cooperate together. Then a single KDB driver implementation could
be used to streamline and provide uniform implementation of Kerberos-specific
details in a local KDC.&lt;/p&gt;

&lt;p&gt;One of the promising interfaces to achieve that is the &lt;a href=&quot;https://systemd.io/USER_GROUP_API/&quot;&gt;User/Group record lookup
API&lt;/a&gt; via varlink from systemd. Varlink
allows applications to register themselves and listen on UNIX domain sockets for
communication similar to D-Bus but with much less implementation overhead. The
User/Group API technically also allows to merge data coming from different
sources when an application inquires the information. “Technically”, because
&lt;code&gt;io.systemd.Multiplexer&lt;/code&gt; API endpoint currently does not support merging
non-overlapping data representing the same account from multiple sources. Once
it would become possible, we could combine the data dynamically and may interact
with users on demand when corresponding requsts come in. Or we can implement our
own blending service.&lt;/p&gt;

&lt;p&gt;Blending data requests from multiple sources within MIT KDC needs a specialized
KDB driver. We certainly don’t want this driver to duplicate the code from other
drivers, so making these drivers stackable would be a good option. Support for
one level of stacking has been merged to MIT Kerberos through &lt;a href=&quot;https://github.com/krb5/krb5/pull/1396&quot;&gt;a quickly
processed pull request&lt;/a&gt; and will be
available in the next MIT Kerberos release. This allows us to have a single KDB
driver that loads other drivers specialized in storing Kerberos principals and
processing additional information like &lt;a href=&quot;https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-pac/166d8064-c863-41e1-9c23-edaaa5f36962&quot;&gt;MS-PAC
structure&lt;/a&gt;
or applying additional authorization details.&lt;/p&gt;

&lt;h3 id=&quot;establishing-trusts&quot;&gt;Establishing trusts&lt;/h3&gt;

&lt;p&gt;If Alice and Bob are in the same network and want to exchange some files, they
could do this using SMB and Samba. But that Alice can authenticate on Bob’s
machine, they would need to establish a Kerberos cross realm trust. With the
current tooling this is a complex task. For users we need to make this more
accessible. We want to allow users to request trust on demand and validate these
requests interactively. We also want to allow trust to be present for a limited
timeframe, automatically expiring or manually removed.&lt;/p&gt;

&lt;p&gt;If we have a Kerberos principal lookup on demand through a curated varlink API
endpoint, we also can have a user-facing service to initiate establishing the
trust between two machines on demand. Imagine a user trying to access SMB share
on one desktop system that triggers a pop-up to establish trust relationship
with a corresponding local KDC on the remote desktop system. Both owners of the
systems would be able to communicate out of band that provided information is
correct and can be trusted. Once it is done, we can return back the details of
the specific Kerberos principal that represents this trust relationship. We can
limit lifetime of this agreement so that it would disappear automatically in one
hour or a day, or a week.&lt;/p&gt;

&lt;h3 id=&quot;current-state-of-local-authentication-hub&quot;&gt;Current state of local authentication hub&lt;/h3&gt;

&lt;p&gt;We started with two individual implementation paths early in 2024:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;support IAKerb in MIT Kerberos and Samba&lt;/li&gt;
  &lt;li&gt;enable MIT Kerberos to be used locally without network exposure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;MIT Kerberos did have support for IAKerb protocol extension for more than a
decade but since Microsoft introduced some changes to the protocol, those
changes needed to be integrated as well. This was completed during summer 2024,
though no upstream release is available yet. MIT Kerberos typically releases new
versions yearly in January so we hope to get some updates early 2025.&lt;/p&gt;

&lt;p&gt;Samba integration with IAKerb is currently under implementation. Originally,
Microsoft was planning to release Windows 11 and Windows Server 2025 with IAKerb
support enabled during autumn 2024. However, the Windows engineering team faced
some issues and IAKerb is still not enabled in the Windows Server 2025 and
Windows 11 releases. We are looking forward to getting access to Windows builds
that enable IAKerb support to ensure interoperability before merging Samba
changes upstream. We also need to complete the Samba implementation to properly
support locally-issued Kerberos tickets and not only do acquisition of the
ticket based on the password.&lt;/p&gt;

&lt;p&gt;Meanwhile, our cooperation with MIT Kerberos development team led to
advancements in the local KDC support. The MIT Kerberos KDC can now be run over
a UNIX domain socket. Also on systemd-enabled systems we allow socket
activation, transforming local KDC into an on-demand service. We will continue
our work on a dynamic database for a local KDC, to allow on-demand combination
of resources from multiple authoritative local sources (Samba, FreeIPA, SSSD,
local KDC, future dynamic trust application).&lt;/p&gt;

&lt;p&gt;For experiments and ease of deployments, a new configuration tool was developed,
localkdc. The tool is available at
&lt;a href=&quot;https://gitlab.com/cryptomilk/localkdc&quot;&gt;localkdc&lt;/a&gt; and &lt;a href=&quot;https://copr.fedorainfracloud.org/coprs/asn/localkdc&quot;&gt;COPR
repository&lt;/a&gt; can be used to
try the whole solution on Fedora.&lt;/p&gt;

&lt;p&gt;If you want to get that test tried in a simple setup, you might be interested in
a tool that we developed initially for FreeIPA: &lt;a href=&quot;https://github.com/abbra/freeipa-local-tests/&quot;&gt;FreeIPA local
tests&lt;/a&gt;. This tool allows to
provision and run a complex test environment in podman containers. The video of
the local KDC usage was actually generated automatically by the scripts from
https://github.com/abbra/freeipa-local-tests/tree/main/ipalab-config/localkdc.&lt;/p&gt;
</description>
        <pubDate>Sun, 09 Feb 2025 13:00:00 +0200</pubDate>
        <link>https://vda.li/en/posts/2025/02/09/local-authentication-hub/</link>
        <guid isPermaLink="true">https://vda.li/en/posts/2025/02/09/local-authentication-hub/</guid>
        
        <category>freeipa</category>
        
        <category>kerberos</category>
        
        <category>iakerb</category>
        
        <category>localkdc</category>
        
        <category>samba</category>
        
        <category>fedora</category>
        
        
        <category>posts</category>
        
      </item>
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
      <item>
        <title>IPA-IPA trust progress report</title>
        <description>&lt;p&gt;FreeIPA and SSSD teams are working to enable IPA deployments to trust each
other. This report outlines the progress we have so far.&lt;/p&gt;

&lt;h3 id=&quot;trust-across-enterprise-domains&quot;&gt;Trust across enterprise domains&lt;/h3&gt;

&lt;p&gt;FreeIPA implements an enterprise domain management: systems enrolled into
domain managed centrally and access resources available through the domain
controllers. These resources include information about users and groups,
machines, Kerberos services and different rules that can bind them. FreeIPA
supports a trust to Active Directory forest by posing as a separate Active
Directory forest with a single Active Directory domain (a forest root).&lt;/p&gt;

&lt;p&gt;The approach helps to integrate with a majority of enterprise deployments. New
deployments might not include Active Directory, though. Instead, they tend to
be self-sufficient or integrate with externally managed data sources, often
without retaining compatibility with traditional POSIX or Active Directory
deployments. For example, cloud deployments might rely on OAuth2 identity
providers or federate to social services.&lt;/p&gt;

&lt;p&gt;FreeIPA can also integrate with OAuth2-based identity providers by bridging
authentication over to them. Users would be native IPA users; IPA policies and
rules to access IPA resources would apply to them but authentication and
permission to issue a Kerberos ticket to the users would be delegated to an
external IdP.&lt;/p&gt;

&lt;p&gt;One useful approach is to have a single IPA environment that holds all users
and groups while individual machines all placed in separate IPA deployments.
These deployments would need to trust the environment where users defined. In
this document we’d call such deployment an IPA-IPA trust.&lt;/p&gt;

&lt;p&gt;IPA-IPA trust would look similar to the existing trust to Active Directory. A
core technology is Kerberos: each deployment is a separate Kerberos realm; a
trust on Kerberos level means cross-realm ticket granting tickets (TGT) issued
by the realms’ KDCs. These cross-realm TGTs allow clients from one realm to
request tickets for services located in the other realm.&lt;/p&gt;

&lt;p&gt;Requesting Kerberos tickets is a base feature needed to authenticate across the
trust. For proper relationship, identities of the authenticated objects
(Kerberos principals and services) also need to be resolved. In POSIX
environments these identities have to be associated with POSIX users to be able
to store data on disk or to run processes with individual login sessions. The
process requires not only authentication but also the ability to query
information from a trusted domain’s domain controller.&lt;/p&gt;

&lt;p&gt;In FreeIPA deployments, user and group information from the domain controllers
is retireved by SSSD. When trust to Active Directory forest created, SSSD on
IPA domain controllers is able to use a special entry in the trusted domain
(trusted domain object, TDO) to authenticate against trusted domain’s domain
controllers. SSSD knows how LDAP schema and directory information tree (DIT) on
the Active Directory side are organized and can handle user and group object
mapping for us.&lt;/p&gt;

&lt;p&gt;If SSSD is able to resolve users and groups in the same way as with Active
Directory trusts, this means we can reuse existing support for trusted Active
Directory users and groups in IPA commands and keep the same user experience
when adding HBAC or SUDO rules, managing IPA deployment, and so on. This would
also mean we already would have a comprehensive test suite to validate IPA-IPA
trust functionality.&lt;/p&gt;

&lt;h3 id=&quot;kerberos-trust-infrastructure&quot;&gt;Kerberos trust infrastructure&lt;/h3&gt;

&lt;p&gt;We first focused on making Kerberos infrastructure work when both realms
represented by separate FreeIPA deployments. For past decade Microsoft, Samba
Team, FreeIPA team, MIT Kerberos and Heimdal projects worked together to ensure
there is a solid secure foundation for interoperability between non-POSIX
(Active Directory) and POSIX deployments. In Active Directory world some
crucial POSIX information is not available. When this information required on
POSIX side, it is either synthesized or mapped onto existing objects by FreeIPA
and Samba AD.&lt;/p&gt;

&lt;p&gt;Kerberos protocol originally didn’t include any means to securely tie Kerberos
principals to identities. For example, one was able to create a Windows machine
named &lt;code&gt;root&lt;/code&gt; in Active Directory and then use its machine account to login to a
different machine as &lt;code&gt;root&lt;/code&gt; POSIX user. This attack approach not possible
anymore if all sides (Kerberos KDCs of the involved realms and a target
machine) use authorization data in Kerberos tickets to exchange identity
details of the original Kerberos principal’s operating system object. In this
case it would mean that a Kerberos principal &lt;code&gt;root&lt;/code&gt; would have its machine
account information associated with the Kerberos ticket and the target machine
would be able to inquire and see that the real Kerberos principal would be
&lt;code&gt;host/root.some.domain&lt;/code&gt; and that this principal’s operating system object type
is a machine account.&lt;/p&gt;

&lt;p&gt;The extensions also give ability to communicate group membership details and
more information about the account. FreeIPA domain controllers already use
these details to check and map properties of trusted Active Directory domains’
objects. For  native IPA objects we also generate this information. IPA-IPA
trust can rely on these details as well.&lt;/p&gt;

&lt;p&gt;This observation allowed us to start with an experiment. Create a trusted
domain object that represents a trusted IPA domain and see what does not work
and needs a fix to make IPA-IPA trust a reality. We originally thought to
replicate Active Directory infrastructure on IPA domain controller side so that
existing &lt;code&gt;ipa trust-add --type=ad ..&lt;/code&gt; command can be used to establish trust.&lt;/p&gt;

&lt;p&gt;These changes are part of the tree I maintain at
&lt;a href=&quot;https://github.com/abbra/freeipa/tree/wip-ipa-ipa-trust&quot;&gt;my github WIP tree&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;identity-information-retrieval&quot;&gt;Identity information retrieval&lt;/h3&gt;

&lt;p&gt;A part of Active Directory infrastructure that we implemented first was Global
Catalog. Global Catalog is a separate, read-only, LDAP instance that contains a
subset of the information about all Active Directory objects in the forest.
Since FreeIPA LDAP tree uses different LDAP schema and structure than Active
Directory LDAP tree, SSSD’s Active Directory identity provider cannot use
normal FreeIPA LDAP tree as “yet another Active Directory domain’s LDAP tree”.
We imagined that adding support for the Global Catalog (which SSSD is able to
query) would make it possible to query IPA users and groups as “Active
Directory” users and groups.&lt;/p&gt;

&lt;p&gt;We soon found out two issues with this approach. It is not possible to force
SSSD to use Global Catalog exclusively. SSSD uses the primary LDAP tree for
retrieving users’ information and only switches to Global Catalog for
retrieving groups information. Adding support for Global Catalog would not
help: existing Active Directory domain identity provider in SSSD would not be
able to work against a trusted IPA domain anyway. A proper support for trusted
IPA domain in SSSD is needed.&lt;/p&gt;

&lt;p&gt;Here we stumbled upon our next issue. SSSD implementation for IPA domain
provider includes ability to handle all trusts to Active Directory domains that
IPA deployment has. Trusted domains (subdomains, in SSSD speak), in theory, can
come from any trust type. Since IPA has only a trust to Active Directory, SSSD
implementation did not have an infrastructure to handle different types of
subdomains. Instead, a single subdomain type is assumed: any subdomain
discovered is an Active Directory domain. Even if we present IPA-IPA trust as
an Active Directory trust, SSSD would still attempt to use Active
Directory-specific LDAP schema and directory information tree arrangement when
making LDAP queries. IPA users and groups from trusted domains aren’t found
because LDAP server would not match that LDAP query to the IPA LDAP tree and
schema.&lt;/p&gt;

&lt;p&gt;SSSD needed a complete refactoring of the subdomains’ infrastructure to allow
more than one subdomain type to be present. This work is still in progress.
Justin Stephenson from the SSSD team tracks his progress in
&lt;a href=&quot;https://github.com/justin-stephenson/sssd/pull/69&quot;&gt;this WIP pull request&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;demo&quot;&gt;Demo&lt;/h3&gt;

&lt;p&gt;With the refactoring work currently being done by Justin, it is possible to
combine two parts: Global Catalog-based FreeIPA changes from
&lt;a href=&quot;https://github.com/abbra/freeipa/tree/wip-ipa-ipa-trust&quot;&gt;my WIP source tree&lt;/a&gt;
and SSSD changes from
&lt;a href=&quot;https://github.com/justin-stephenson/sssd/pull/69&quot;&gt;Justin’s WIP source tree&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We have these modifications to FreeIPA and SSSD prebuilt in Fedora COPR
repository &lt;code&gt;abbra/wip-ipa-trust&lt;/code&gt;. The packages there work in a specific
environment where two FreeIPA deployments named &lt;code&gt;ipa1.test&lt;/code&gt; and &lt;code&gt;ipa2.test&lt;/code&gt;
because we have so far no way to differentiate trusted IPA deployment from a
trusted Active Directory deployment, thus SSSD hardcodes the names of the IPA
domains to trust.&lt;/p&gt;

&lt;p&gt;A trust between &lt;code&gt;ipa1.test&lt;/code&gt; and &lt;code&gt;ipa2.test&lt;/code&gt; can be established using standard
&lt;code&gt;ipa trust-add&lt;/code&gt; command. This approach allowed us to investigate what is
working or not after the trust link is created. Both FreeIPA and SSSD teams can
also work on validating that specific IPA functionality available to handle
trusted Active Directory users and groups is also working with IPA-IPA trust.&lt;/p&gt;

&lt;p&gt;I recorded &lt;a href=&quot;https://youtube.com/watch/?v=z6o1tj9XUMQ&quot;&gt;a small demo&lt;/a&gt; on Fedora 40:&lt;/p&gt;
&lt;div class=&quot;embed-container&quot;&gt;
&lt;iframe width=&quot;740&quot; height=&quot;480&quot; src=&quot;https://www.youtube.com/embed/z6o1tj9XUMQ&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;encrypted-media; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt; 
&lt;/div&gt;

&lt;p&gt;Two administrators establish trust between their environments and then allow
use of resources across the trust. Since the exact details how trust is
established will change, I omitted that step and show pre-created trust entries
along with the ID range details. Only ‘Active Directory trust with POSIX
attributes’ ID range type supported for now. It should not be a problem though
because IPA deployments do provide POSIX information.&lt;/p&gt;

&lt;p&gt;To allow access to IPA API, an administrator of the trusting domain needs to
create ID overrides for user from the trusted domain. Once the overrides are in
place, a user from the trusted domain can issue IPA API calls. In the demo we
do &lt;code&gt;ipa ping&lt;/code&gt; call and show that underlying Kerberos service tickets were
requested and issued.&lt;/p&gt;

&lt;h3 id=&quot;future-work&quot;&gt;Future work&lt;/h3&gt;

&lt;p&gt;Now that we validated the approach, the road splits into two:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;figure out how to get trust established&lt;/li&gt;
  &lt;li&gt;fix remaining bugs to make ‘day two’ operations possible.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Establishing trust is an interesting problem. Or two. For pure IPA-IPA trust we
don’t need to provision the same infrastructure as with Active Directory trust:
we don’t need to run Samba on each domain controller to be able to create
trusted domain objects and respond to DCE RPC requests because we don’t use DCE
RPC in SSSD.&lt;/p&gt;

&lt;p&gt;On top of that, FreeIPA has extensive set of passwordless authentication
methods which require use of a FAST channel when obtaining an initial Kerberos
TGT. When trust to Active Directory created, we first authenticate to AD DC to
get a Kerberos TGT of the Active Directory’s administrator. Windows does not
have support for passwordless authentication methods through Kerberos except
for PKINIT (smartcards), so in most cases we deal with password authentication.
If an IPA administrative account is using passwordless method to authenticate,
we first have to create a FAST channel or a trusted-to-be domain controller
will not even expose supported pre-authentication methods. Any existing
Kerberos ticket could be used to create the FAST channel but it must be from
the trusted domain and we don’t have trust yet. In our own domain we can use a
machine account (on a particular machine) or an Anonymous PKINIT to create the
FAST channel. For a trusted-to-be domain we have to trust the CA who issued
PKINIT certificates to their KDC. And KDCs might be accessible through a HTTPS
proxy (MS-KKDCP protocol). This means some kind of pre-trust exchange needed to
make sure we can authenticate against their KDCs successfully.&lt;/p&gt;

&lt;p&gt;Also, we have no idea what exact pre-authentication methods will be available
to the user. Practically, we only care about being able to authenticate to the
trusted domain’s IPA API and then use that connection to set things up. For
this it would be enough to authenticate to the trusted-to-be domain’s IPA API
endpoint, save received cookies and use them. This method wouldn’t support
passwordless authentication either, except an OTP method. FIDO2 and external
IdP (OAuth2) authentication aren’t yet directly supported in IPA web UI and IPA
API end-points.&lt;/p&gt;

&lt;p&gt;With all those complications, we look at enabling OAuth2-based authentication
and authorization endpoints in IPA first. We then can use them to request a
token from a trusted-to-be domain’s OAuth2 endpoint and use it to establish the
trust. A remote domain controller will handle the authentication of their users
and will be able to supply all required details: trusted CA chains, ID ranges,
scopes for authentication/ID mapping, etc.&lt;/p&gt;

&lt;p&gt;And the OAuth2 endpoint will allow us to handle own passwordless authentication
methods for IPA Web UI and applications on the enrolled systems like Cockpit
which will be able to delegate to IPA for the user login.&lt;/p&gt;

</description>
        <pubDate>Fri, 31 May 2024 12:30:00 +0300</pubDate>
        <link>https://vda.li/en/posts/2024/05/31/ipa-ipa-trust-progress/</link>
        <guid isPermaLink="true">https://vda.li/en/posts/2024/05/31/ipa-ipa-trust-progress/</guid>
        
        <category>freeipa</category>
        
        <category>fedora</category>
        
        <category>kerberos</category>
        
        <category>samba</category>
        
        
        <category>posts</category>
        
      </item>
    
    
    
    
    
    
    
    
    
    
    
      <item>
        <title>CentOS Connect 2024 report</title>
        <description>&lt;p&gt;February 1st-4th I participated in two events in Brussels: CentOS Connect and
FOSDEM. FOSDEM is getting closer to its quarter a century anniversary next
year. With 67 mini-conferences and another 30 events around it, it is
considered one of the largest conferences in Europe, any topic included. This
report is about CentOS Connect.&lt;/p&gt;

&lt;h2 id=&quot;centos-connect&quot;&gt;CentOS Connect&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://connect.centos.org&quot;&gt;CentOS Connect&lt;/a&gt; was a two-day event preceding
FOSDEM. Organized by the CentOS project, it brought together contributors from
multiple projects around CentOS Stream upstreams (such as Fedora Project) and
downstreams (from Red Hat Enterprise Linux, AlmaLinux, Rocky Linux, and
others), long-time users and community members. A lot of talks were given on
both days and several special interest groups (SIGs) ran their workshops on the
first day.&lt;/p&gt;

&lt;h2 id=&quot;centos-integration-sig&quot;&gt;CentOS Integration SIG&lt;/h2&gt;

&lt;p&gt;I have attended a workshop organized by the CentOS Integration SIG. The focus
of this group is to define and run integration tests around CentOS Stream
delivery to the public. While CentOS Stream composes are built using the
messages on how RHEL next minor version is composed after being thoroughly
tested by Red Hat’s quality engineering group, there is a value in testing
CentOS Stream composes by other community members independently as their use
cases might differ. Right now the set of tests is defined as a &lt;code&gt;t_functional&lt;/code&gt;
suite maintained by the CentOS Core SIG but this suite is not enough for the
complex scenarios.&lt;/p&gt;

&lt;p&gt;The Integration SIG is looking at improving the situation. Two projects were
present and interested in this work: RDO (RPM-based distribution of OpenStack)
and RHEL Identity Management. Both teams have to deal with coordinated package
deliveries across multiple components and both need to get multi-host
deployments tested. RDO can be treated as a product built on top of CentOS
Stream where its own RDO deliveries are installed on top of CentOS Stream
images. RHEL Identity Management (IdM), on the other hand, is a part of RHEL.
It is famously known as a ‘canary in the RHEL mine’ (thanks to Stephen
Gallagher’s being poetic a decade ago): if anything is broken in RHEL, chances
are it will be visible in RHEL IdM testing. With RHEL IdM integration scope
expanding to provide passwordless desktop login support, this becomes even more
important and also requires multi-host testing.&lt;/p&gt;

&lt;p&gt;CentOS Integration SIG’s proposal to address these requirements is interesting.
Since CentOS Stream compose event is independent of the tests, a proposal by
Aleksandra Fedorova and Adam Samalik is to treat the compose event in a way
similar to a normal development workflow. Producing CentOS Stream compose would
generate a merge request of a metadata associated with it to a particular git
repository. This merge request then can be reacted to by the various bots and
individuals. Since CentOS Stream compose is public, it is already accessible to
third-party developers to run their tests and report back the results. This way
qualification of the compose promotion to CentOS Stream mirrors can be affected
by all parties and will help to keep already published composes in a
non-conflicting state.&lt;/p&gt;

&lt;p&gt;Since most of the projects involved already have their own continuous
integration systems, adding another trigger for those would be trivial. For
RHEL IdM and its upstream components (FreeIPA, SSSD, 389-ds, Dogtag PKI, etc.)
it would also be possible finally to react to changes to CentOS Stream well
ahead of time too. In the past this was complicated by a relative turbulence in
the CentOS Stream composes early in RHEL next minor release development time
when everybody updates their code and stabilization needs a lot of
coordination. I am looking forward to Aleksandra’s proposal to land in the
Integration SIG’s materials soon.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;: Aleksandra has published her proposal at the &lt;a href=&quot;https://discussion.fedoraproject.org/t/centos-connect-follow-up-proposal-for-the-git-interface-to-the-compose-gate/104981&quot;&gt;Fedora Discussion board&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;centos-stream-and-epel&quot;&gt;CentOS Stream and EPEL&lt;/h2&gt;

&lt;p&gt;Two talks, by Troy Dawson and Carl George, described the current state of EPEL
repository and its future interactions with CentOS 10 Stream. Troy’s discussion
was fun, as usual: a lot of statistics obtained from the DNF repository
trackers shows that old habits are hard to get rid off and moving forward is a
struggle to many users despite security and supportability challenges with
older software. Both CentOS 7 and CentOS 8 Stream end of life dates are coming
in 2024, adding enough pressure themselves to that.&lt;/p&gt;

&lt;p&gt;There are interesting statistics from the EPEL evolution. In August 2023 at
Flock to Fedora conference Troy and Carl pointed out that 727 packagers
maintained 7298 packages in EPEL 7, 489 packagers handled 4968 packages in EPEL
8, and 396 packagers were handling 5985 packages in EPEL 9. Half a year later
we have 7874 packages in EPEL 7, 5108 packages in EPEL 8, and 6868 packages in
EPEL 9. Pace seems to pick up EPEL 9 with upcoming end of life dates for older
versions. Since soon only EPEL 9 and EPEL 10 would be actively built, there are
probably more packagers that would be active in them as well.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/en/img/resized/2024-centos-connect/epel-packages-800-2bb1c63e5.jpg&quot; srcset=&quot;/en/img/resized/2024-centos-connect/epel-packages-400-2bb1c63e5.jpg 400w, /en/img/resized/2024-centos-connect/epel-packages-600-2bb1c63e5.jpg 600w, /en/img/resized/2024-centos-connect/epel-packages-800-2bb1c63e5.jpg 800w, /en/img/resized/2024-centos-connect/epel-packages-1000-2bb1c63e5.jpg 1000w&quot; /&gt;&lt;/p&gt;

&lt;p&gt;EPEL 10 is coming soon. It will bring a slight difference in package suffixes
and overall reduction of complexity to packagers. It is great to see how close
EPEL work tracks to ELN activities in Fedora. One thing worth noting is that
every Fedora package maintainer is a potential EPEL maintainer as well because
EPEL reuses Fedora infrastructure for package maintenance. Even if someone is
not maintaining EPEL branches on their Fedora packages (I am not doing that
myself – my packages are mostly in RHEL), it allows easy jump-in and
collaboration. After all, if packages aren’t in RHEL but are in Fedora, their
EPEL presence is just one git branch (and Fedora infrastructure ticket) away.&lt;/p&gt;

&lt;h2 id=&quot;20-years-of-centos-project&quot;&gt;20 years of CentOS project&lt;/h2&gt;

&lt;p&gt;First day of the CentOS Connect event ended with a party to celebrate 20 years
of the CentOS Project. First release (“CentOS version 2”) went out on May 14th,
2004 but since CentOS Connect is the closest big event organized by the project
this year, getting a lot of contributors together to celebrate this anniversary
seemed appropriate. A huge cake was presented, so big that it wasn’t possible
to consume it completely during the party. It was delicious (like a lot of
Belgian chocolate!) and next day coffee breaks allowed me to enjoy it a lot.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/en/img/resized/2024-centos-connect/centos-20y-cake-800-92c46ff66.jpg&quot; srcset=&quot;/en/img/resized/2024-centos-connect/centos-20y-cake-400-92c46ff66.jpg 400w, /en/img/resized/2024-centos-connect/centos-20y-cake-600-92c46ff66.jpg 600w, /en/img/resized/2024-centos-connect/centos-20y-cake-800-92c46ff66.jpg 800w, /en/img/resized/2024-centos-connect/centos-20y-cake-1000-92c46ff66.jpg 1000w&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;freeipa-and-centos-project-infrastructure&quot;&gt;FreeIPA and CentOS project infrastructure&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://talks.vda.li/talks/2024/CentOS-Connect-Discuss-Your-FreeIPA.pdf&quot;&gt;My own talk&lt;/a&gt; was originally planned to gather feedback from all projects which
build on top of CentOS as they use a very similar infrastructure. CentOS
Project infrastructure is shared with Fedora Project which is built around
FreeIPA as a backend and Noggin as a user management frontend. I asked in
advance for some feedback from Fedora, CentOS, AlmaLinux, and RockyLinux
infrastructure teams and haven’t gotten that much which prompted my own
investigation. It is not an easy job since most organizations aren’t really
interested in telling the world details of their core infrastructure. Hope was
that I’d be able to see real world usage and maybe take some lessons from it
back to the development teams.&lt;/p&gt;

&lt;p&gt;While working on my talk, we also experienced an outage in Fedora
infrastructure related to the upgrade of the FreeIPA setup used there. My team
has been helping Fedora infrastructure administrators so I finally got the
feedback I was looking for. That led to several fixes upstream and they have
recently been backported to RHEL and CentOS Stream as well. However, the
overall lack of feedback is concerning – or at least I thought so.&lt;/p&gt;

&lt;p&gt;During CentOS Connect I had the opportunity to discuss this with both AlmaLinux
(Jonathan) and RockyLinux (Luis) projects’ sysadmins. “It just works” is a common
response I get. Well, that’s nice to hear but what was more exciting to hear is
that these projects went a bit further than we did in Fedora and CentOS Stream
with their environments. Luis &lt;a href=&quot;https://talks.vda.li/talks/2024/CentOS-Connect-Discuss-Your-FreeIPA.pdf&quot;&gt;has published the whole RockyLinux infrastructure&lt;/a&gt;
code responsible for FreeIPA deployment. It is based heavily on
ansible-freeipa, reuses the same components we developed for Fedora
Infrastructure. Rocky also runs FreeIPA tests in OpenQA instance, similarly to
Fedora, and hopefully Luis would contribute more tests to cover passwordless
login, already available in CentOS Stream. This would be a very welcome
contribution in the light of the Integration SIG activities, helping us to test
more complex scenarios community-wide. AlmaLinux infrastructure also uses
ansible-freeipa but the code is not publicly available, for whatever reason.
Jonathan promised to rectify this problem.&lt;/p&gt;

&lt;h2 id=&quot;hallway-tracks&quot;&gt;Hallway tracks&lt;/h2&gt;

&lt;p&gt;I had a number of discussions with people from all kinds of CentOS communities.
FreeIPA sits at a unique position by providing secure infrastructure to run
POSIX workloads and linking it with modern requirements to web authentication.
Our effort to improve passwordless login to Linux environments with reuse of
Kerberos to propagate authorization state across multiple machines helps to
solve the ‘between the worlds’ problems. That is something that many academic
institutions have noticed already and many talks I had in the hallways were
related to it.&lt;/p&gt;

</description>
        <pubDate>Tue, 13 Feb 2024 09:25:00 +0200</pubDate>
        <link>https://vda.li/en/posts/2024/02/13/CentOS-Connect-report/</link>
        <guid isPermaLink="true">https://vda.li/en/posts/2024/02/13/CentOS-Connect-report/</guid>
        
        <category>freeipa</category>
        
        <category>fedora</category>
        
        <category>centos</category>
        
        
        <category>posts</category>
        
      </item>
    
    
    
    
    
    
    
    
    
      <item>
        <title>Multi-homed FreeIPA server investigation</title>
        <description>&lt;p&gt;Once in a while people come and ask for FreeIPA servers to work in multi-homed
environments. A multi-homed environment in this context is a deployment where
the same server is accessible through multiple network interfaces which connect
together networks which are not routable to each other. This is typical for
administrative and operational networks but there are other types of
environments which employ disconnected networks for their operations. FreeIPA
server right now has a single host name that resolves to the same IP address in
all networks and if one cannot reach the server through that IP address, access
to IPA server would not be possible. This typically assumes use of unicast
networking as well.&lt;/p&gt;

&lt;p&gt;A solution many people look for is to be able to access IPA servers by their
interface-specific addresses. Since all secure communication over HTTPS and other
protocols (LDAP, Kerberos, etc.) uses name-based resolution in the first place,
use of different host names is implied. For example, if FreeIPA is deployed at
DNS domain &lt;code&gt;example.test&lt;/code&gt;, it would be using Kerberos realm &lt;code&gt;EXAMPLE.TEST&lt;/code&gt; and
then the original IPA server would be deployed at a host named
&lt;code&gt;ipa.example.test&lt;/code&gt; (the server host name is not that important here, rather the
fact that is is an individual host name). Let’s look at possible communications
with this server in a non-multihomed environment first.&lt;/p&gt;

&lt;h2 id=&quot;single-homed-environment&quot;&gt;Single-homed environment&lt;/h2&gt;

&lt;p&gt;An IPA client uses HTTPS to communicate with IPA management API, SSSD on the
IPA client would use LDAP(S) and Kerberos protocols. In both HTTPS and LDAP(S)
cases TLS negotiation would force checking server TLS certificate correctness.
A hostname of the host we connect to (&lt;code&gt;ipa.example.test&lt;/code&gt;) would have to be
present as a dNS SAN record in the TLS certificate presented by the IPA server.&lt;/p&gt;

&lt;p&gt;In Kerberos protocol case a different mechanism is used. Yet, Kerberos KDC must
know the name of the service principal that a client is asking a service ticket
for. If the client wants to acquire a service ticket to
&lt;code&gt;ldap/ipa.example.test@EXAMPLE.TEST&lt;/code&gt;, this service principal must exist in the
Kerberos database that KDC is looking up at.&lt;/p&gt;

&lt;h2 id=&quot;multi-homed-environment&quot;&gt;Multi-homed environment&lt;/h2&gt;

&lt;p&gt;There are multiple ways of exposing a single hostname in multi-homed
environment but they generally involve use of DNS views specific to the
individual networking. In such cases DNS serves visible to clients in one
network would resolve &lt;code&gt;ipa.example.test&lt;/code&gt; to an IP address in that specific
network. FreeIPA DNS integration does not support DNS views; this means any of
DNS manipulations would have to be done externally to FreeIPA. This is, of
course possible, but it really is not then different from a single-homed
environment from FreeIPA perspective.&lt;/p&gt;

&lt;p&gt;Thus, we would have to have not a single &lt;code&gt;ipa.example.test&lt;/code&gt; hostname but for
each independent network’s address present on the IPA server a different host
name must be present. Let’s assume these are &lt;code&gt;ipa1.example.test&lt;/code&gt; and
&lt;code&gt;ipa2.example.test&lt;/code&gt;. Had we not done this split and simply added multiple
addresses for the same &lt;code&gt;ipa.example.test&lt;/code&gt; name, clients might resolve the name
to an IP address which they could not reach through their own networking routing.&lt;/p&gt;

&lt;h2 id=&quot;requirements&quot;&gt;Requirements&lt;/h2&gt;

&lt;p&gt;Immediately we get a set of requirements here:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;TLS certificates issued by IPA CA for HTTPS and LDAP(S) use on IPA server
must include dNS SAN records for each hostname represented by the
multi-homed server.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Kerberos principals for at least LDAP (&lt;code&gt;ldap/&lt;/code&gt;), HTTP (&lt;code&gt;HTTP/&lt;/code&gt;), and the
system (&lt;code&gt;host/&lt;/code&gt;) service principals must have aliases for all multi-homed
hostnames.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The latter requirement means that if &lt;code&gt;ipa1.example.test&lt;/code&gt; is the primary name,
then &lt;code&gt;ldap/ipa1.example.test&lt;/code&gt; should have an alias of &lt;code&gt;ldap/ipa2.example.test&lt;/code&gt;,
&lt;code&gt;HTTP/ipa1.example.test&lt;/code&gt; should have an alias of &lt;code&gt;HTTP/ipa2.example.test&lt;/code&gt;, and
&lt;code&gt;host/ipa1.example.test&lt;/code&gt; should have an alias of &lt;code&gt;host/ipa2.example.test&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The same would apply to any other service hosted on IPA server: SMB (&lt;code&gt;cifs/..&lt;/code&gt;)
or DNS services would need those aliases as well. However, this is not enough.&lt;/p&gt;

&lt;h2 id=&quot;implementation-considerations&quot;&gt;Implementation considerations&lt;/h2&gt;

&lt;h3 id=&quot;hostname-aliases&quot;&gt;Hostname aliases&lt;/h3&gt;
&lt;p&gt;FreeIPA does additional checks when issuing certificiates prior to passing the
request to the Dogtag CA that is integrated into FreeIPA. For hosts and
services on those hosts we also check whether a requestor is granted to issue
these certificates. In FreeIPA terms, a host &lt;code&gt;ipa1.example.test&lt;/code&gt; would be
allowed to issue certificates with dNS SAN record of &lt;code&gt;ipa2.example.test&lt;/code&gt; if a
host object of &lt;code&gt;ipa1.example.test&lt;/code&gt; manages the host object &lt;code&gt;ipa2.example.test&lt;/code&gt;
in FreeIPA.&lt;/p&gt;

&lt;p&gt;Here lies our first problem. A host object in FreeIPA represents the host
principal in Kerberos, &lt;code&gt;host/ipa1.example.test&lt;/code&gt;. If we created two host
objects, &lt;code&gt;ipa1.example.test&lt;/code&gt; and &lt;code&gt;ipa2.example.test&lt;/code&gt;, then they cannot be
aliases to each other on Kerberos level because they’d be two completely
different objects from FreeIPA perspective.&lt;/p&gt;

&lt;p&gt;Perhaps, we can avoid creating two different host objects? DNS records for
hosts are different from the host objects themselves, we only need to have
different IP addresses for the hostnames represented by these host entries, not
the host entries themselves. May be we could mark one hostname an alias of the
other host object?&lt;/p&gt;

&lt;p&gt;On Kerberos level FreeIPA does have Kebreros principal name aliasing already.
However, it does not exist for hosts as this task has never appeared in past. We
would need to add a way to add multiple names to the host object. One way to
achieve that is to rely on the fact that &lt;code&gt;fqdn&lt;/code&gt; LDAP attribute is multi-valued.
Unfortunately, it is also enforced to be a primary key in IPA API – while the
underlying LDAP attribute is a multi-valued one, IPA API will enforce its single
value:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;$ ipa host-mod ipa1.example.test --addattr fqdn=ipa2.example.test
ipa: ERROR: fqdn: Only one value allowed.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This happens because in IPA API any parameter which could be a multi-valued one
should explicitly set &lt;code&gt;multivalue=True&lt;/code&gt; in its definition. We probably would
need to change the multi-valued state for &lt;code&gt;fqdn&lt;/code&gt; parameter:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;...
        Str(&apos;fqdn&apos;, hostname_validator,
            cli_name=&apos;hostname&apos;,
            label=_(&apos;Host name&apos;),
            primary_key=True,
            normalizer=normalize_hostname,
&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;      multivalue=True,
        ),
...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and review countless places where its single value is assumed through the code,
like in the &lt;code&gt;resolve_fqdn()&lt;/code&gt; helper below. LDAP does not guarantee a particular
order of returned values for the multi-valued attributes. From LDAP protocol
point of view they all equal, there is no particular order.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;def resolve_fqdn(name):
    hostentry = api.Command[&apos;host_show&apos;](name)[&apos;result&apos;]
    return hostentry[&apos;fqdn&apos;][0]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;An alternative would be to introduce a separate attribute purely for the
hostname alias management. We don’t need to use it anywhere else at Kerberos
level because there we use Kerberos-specific attributes to handle Kerberos
principal names and aliases.&lt;/p&gt;

&lt;h3 id=&quot;ldap-access-controls&quot;&gt;LDAP Access Controls&lt;/h3&gt;

&lt;p&gt;A big part of the FreeIPA access control mechanism relies on 389-ds LDAP server
access control interface. Permissions and roles in FreeIPA effectively define a
set of ACIs for 389-ds to check access rights. IPA servers verified to be
present in certain resource groups (like &lt;code&gt;cn=masters,cn=ipa,cn=etc,$BASEDN&lt;/code&gt;).
For host aliases this means they should be present in the same groups to be able
to operate as their own entities when checking permissions. This is important
for internal logic in IPA LDAP plugins and in KDC driver. For the cases when
authentication would be done via GSSAPI a resulting Kerberos principal will be
normalized to he primary name of the system anyway.&lt;/p&gt;

&lt;h3 id=&quot;certificate-issuance&quot;&gt;Certificate issuance&lt;/h3&gt;

&lt;p&gt;Issuing a certificate is a whole separate topic which still awaits its write
up. An abridged version of it can be found in &lt;a href=&quot;https://lists.fedorahosted.org/archives/list/freeipa-users@lists.fedorahosted.org/message/7NAZ2AT7FXXVBL42DTKJHCUQNOJBZB27/&quot;&gt;my freeipa-users@ mailing list
response&lt;/a&gt;
from May 2022. I need to turn that into a proper document one day.&lt;/p&gt;

&lt;p&gt;From the perspective of aliases, we would need to teach the certificate request
processing code to look at the host and service aliases when validating SAN
records.&lt;/p&gt;

&lt;h3 id=&quot;installer-integration&quot;&gt;Installer integration&lt;/h3&gt;

&lt;p&gt;There are two approaches to setting up this multi-homed environment. We can
provide all information upfront or we can add a tool that adds individual
aliases after deployment. This would mean to (re-)generate certificates, create
host aliases and services, create configuration snippets and other details which
are required to handle multiple host names for the same host from different
networks.&lt;/p&gt;

&lt;p&gt;The after-deployment case would cause re-issuance of certificates. For external
CA providers it could be handled with existing tool that allows to replace
existing TLS certificates with externally provided ones. We need to create a
checker to verify that all required dNS SAN names were added and are available.
In general, troubleshooting this environment would be non-trivial so a special
module for &lt;code&gt;ipa-healthcheck&lt;/code&gt; definitely would help.&lt;/p&gt;

&lt;h2 id=&quot;final-thoughts&quot;&gt;Final thoughts&lt;/h2&gt;

&lt;p&gt;Multi-homed environments are hard to automate as many assumptions aren’t
actually known to us. They are partly implicit to system and network
administrator’s work and cannot be derived merely from the system state. It
means administrators would need to aid IPA installers with an information. At
this point, it is unclear how to structure this information and which of it
going to be useful enough. In contemporary Linux environments you might have
DNS resolution depend on a specific network interface thanks to
&lt;code&gt;systemd-resolved&lt;/code&gt; or VPN connection properties. We might not have that
information for introspection in advance. While automatically issuing
certificates with required names to cover multi-homed setup is not going to be
easy, writing down requirements for external CAs and verifying those
certificates before applying them at the second stage of external CA enrollment
would further complicate things.&lt;/p&gt;

&lt;p&gt;All these problems could be solved, of course. Prioritization of this work
against other, more urging tasks, is what we need to figure first…&lt;/p&gt;

</description>
        <pubDate>Wed, 16 Aug 2023 10:04:00 +0300</pubDate>
        <link>https://vda.li/en/posts/2023/08/16/Support-multi-homed-FreeIPA-Server/</link>
        <guid isPermaLink="true">https://vda.li/en/posts/2023/08/16/Support-multi-homed-FreeIPA-Server/</guid>
        
        <category>freeipa</category>
        
        
        <category>posts</category>
        
      </item>
    
    
    
    
    
      <item>
        <title>Flock to Fedora 2023 report</title>
        <description>&lt;p&gt;On August 2nd-4th, 2023, Fedora Project ran its annual contributors conference, &lt;a href=&quot;https://flocktofedora.org&quot;&gt;Flock to Fedora&lt;/a&gt;, in Cork, Ireland. After a previous successful Flock in 2019 in Budapest, Fedora contributors did not meet in person due to rough pandemia years and had created Nest with Fedora online event instead. Nest ran for three years but online meetings aren’t a full replacement for face to face collaboration. Cork’s Flock was supposed to combine both online and offline events together.&lt;/p&gt;

&lt;p&gt;I have been attending and presenting at various Flock and Nest events over past seven years. I was looking forward to see and collaborate with many other project participants and users and get to know new people as well.&lt;/p&gt;

&lt;p&gt;My travel to Cork was unremarkable. I took a direct flight from Helsinki to Dublin and then an Aircoach bus to Cork. The ‘unremarkable’ part was really about the unexpected delays people did report over the Matrix channel. The only ‘trouble’ I had was to catch a taxi at 11pm after arrival to Cork to get to my B&amp;amp;B. The Aircoach bus from Dublin airport is very popular in summer and whatever taxi fleet is in Cork was DDoSed by the passengers.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/en/img/resized/2023-flock/hotel-stay-800-480d673e0.jpg&quot; srcset=&quot;/en/img/resized/2023-flock/hotel-stay-400-480d673e0.jpg 400w, /en/img/resized/2023-flock/hotel-stay-600-480d673e0.jpg 600w, /en/img/resized/2023-flock/hotel-stay-800-480d673e0.jpg 800w, /en/img/resized/2023-flock/hotel-stay-1000-480d673e0.jpg 1000w&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Cork is hilly. I stayed in excellent B&amp;amp;B across the road from the conference hotel. The hotel and its conference facilities are in separate buildings; the events building is up hill from the hotel. Walking is helpful, climbing harder but given we are sitting most of the time, was a welcoming ‘struggle’. Perhaps, my stay outside of the conference hotel has also helped to avoid COVID-19 which few other participants, sadly, contracted. It is hit or miss every time.&lt;/p&gt;

&lt;p&gt;Unfortunately, not everyone made to Cork. &lt;a href=&quot;https://sfconservancy.org/news/2022/jun/14/remembering-marina/&quot;&gt;Marina Zhurakhinskaya&lt;/a&gt; passed away in June 2022. &lt;a href=&quot;https://funnelfiasco.com/blog/2023/05/12/inaction-bcotton/&quot;&gt;Ben Cotton&lt;/a&gt;, Fedora Program Manager, has been let go as a part of Red Hat’s layoffs earlier this year. Both had definitely changed Fedora project dramatically, in many ways, both leading to openness and friendliness Fedora is known for. Many presenters remembered both Marina and Ben during their sessions.&lt;/p&gt;

&lt;p&gt;2023’s edition of Flock to Fedora was also the first Fedora Project’s event collocated with CentOS Connect. As a result, it brought together Red Hat Enterprise Linux distribution upstreams and downstreams together.&lt;/p&gt;

&lt;h2 id=&quot;talks&quot;&gt;Talks&lt;/h2&gt;

&lt;p&gt;In total, there were up to four parallel tracks, dedicated to different areas of a distribution development and a project’s life and spanned over three days. That, unsurprisingly, made it challenging to visit all talks and activities. It is a common trait shared by many successful events. And for those who wanted to continue discussions after a talk has ended, there is always a ‘hallway track’.&lt;/p&gt;

&lt;h3 id=&quot;state-of-fedora-2023&quot;&gt;State of Fedora 2023&lt;/h3&gt;
&lt;p&gt;The first talk was ‘State of Fedora 2023’ by the project leader, Matthew Miller. Recording is available &lt;a href=&quot;https://www.youtube.com/live/LhLEV4fi2xw?feature=share&amp;amp;t=21327&quot;&gt;here&lt;/a&gt;. I am linking to the re-take of the talk as the original streaming was off by 20 minutes and Matthew had to reprise it again.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/en/img/resized/2023-flock/state-of-fedora-800-4a2f915c0.jpg&quot; srcset=&quot;/en/img/resized/2023-flock/state-of-fedora-400-4a2f915c0.jpg 400w, /en/img/resized/2023-flock/state-of-fedora-600-4a2f915c0.jpg 600w, /en/img/resized/2023-flock/state-of-fedora-800-4a2f915c0.jpg 800w, /en/img/resized/2023-flock/state-of-fedora-1000-4a2f915c0.jpg 1000w&quot; /&gt;&lt;/p&gt;

&lt;p&gt;A major announcement made during the talk was a hiring one. &lt;a href=&quot;https://communityblog.fedoraproject.org/job-posting-fedora-operations-architect/&quot;&gt;Fedora Operations Architect role&lt;/a&gt; has been introduced after a program manager role that Ben Cotton so masterfully executed was eliminated. Hopefully, this new role will be filled soon and will allow to capture the same benefits that Ben brought to Fedora. The role is a bit different, though, as it is focused on cross-project and cross-distro impact across Fedora and RHEL.&lt;/p&gt;

&lt;p&gt;Fedora contributors’ survey results were also unveiled by Matthew in the talk. In general, contributors keep trust in the project and continue their participation at the pre-pandemia levels. Recent social networking turmoil around Red Hat actions hasn’t influenced the results too much. The screenshots below are from the video stream as the talk’s slides aren’t yet available.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/en/img/resized/2023-flock/state-of-fedora-stats-1-800-17d2108e9.png&quot; srcset=&quot;/en/img/resized/2023-flock/state-of-fedora-stats-1-400-17d2108e9.png 400w, /en/img/resized/2023-flock/state-of-fedora-stats-1-600-17d2108e9.png 600w, /en/img/resized/2023-flock/state-of-fedora-stats-1-800-17d2108e9.png 800w, /en/img/resized/2023-flock/state-of-fedora-stats-1-1000-17d2108e9.png 1000w&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/en/img/resized/2023-flock/state-of-fedora-stats-2-800-ba2fcdd53.png&quot; srcset=&quot;/en/img/resized/2023-flock/state-of-fedora-stats-2-400-ba2fcdd53.png 400w, /en/img/resized/2023-flock/state-of-fedora-stats-2-600-ba2fcdd53.png 600w, /en/img/resized/2023-flock/state-of-fedora-stats-2-800-ba2fcdd53.png 800w, /en/img/resized/2023-flock/state-of-fedora-stats-2-1000-ba2fcdd53.png 1000w&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The talk went into details on what Matthew and Fedora Council aim for Fedora Project’s future. Growing a project with thousands of contributors spread around the world and representing different cultures is hard. A lot of effort is put into making Fedora a welcoming place to everyone who is willing to work together towards a common goal.&lt;/p&gt;

&lt;h3 id=&quot;rpminspect-lessons-from-three-distributions&quot;&gt;&lt;code&gt;rpminspect&lt;/code&gt;: Lessons from three distributions&lt;/h3&gt;

&lt;p&gt;David Cantrell created and maintains a tool that helps RHEL maintainers to keep their packages sane over years of maintenance. It is run as a part of CentOS Stream merge request process, as part of Fedora gating and pull request testing, and as a gating test for RHEL.&lt;/p&gt;

&lt;p&gt;The talk itself is an excellent retrospective on what one should consider when creating a new Open Source project while working on it full time. David provided observations on how to sell the idea to your management, how to get people interested in becoming a community for your project, how to sustain development in a long run. This is one of rare gems of a ‘lone wolf’ maintainership stories that everybody needs to absorb when they start their new journey. Believe me, it is worth it.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/en/img/resized/2023-flock/rpminspect-1-800-b79dc5331.jpg&quot; srcset=&quot;/en/img/resized/2023-flock/rpminspect-1-400-b79dc5331.jpg 400w, /en/img/resized/2023-flock/rpminspect-1-600-b79dc5331.jpg 600w, /en/img/resized/2023-flock/rpminspect-1-800-b79dc5331.jpg 800w, /en/img/resized/2023-flock/rpminspect-1-1000-b79dc5331.jpg 1000w&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;using-aiml-to-process-automated-test-results-from-openqa&quot;&gt;Using AI/ML to process automated test results from OpenQA&lt;/h3&gt;

&lt;p&gt;Tim Flink from Fedora QE team decided to apply AI/ML to a problem of identifying hanging or failing jobs in OpenQA. OpenQA runs full-VM tests and records screencasts of everything what is shown on a VM screen. A crash of a graphical environment is abruptly visible there as graphics would be replaced by a terminal with a Wayland’s stacktrace. What followed is an experiment on processing these screens to reliably detect a particular type of a crash.&lt;/p&gt;

&lt;p&gt;We spent some time with Tim discussing how these experiments can be applied to finding out possible issues in other system reports. Since Fedora is upstream of CentOS Stream or RHEL, it means certain issues – and their fixes – would often appear in Fedora first. If we could train a model on those issues in Fedora, can we detect automatically whether a particular fix is required in RHEL later? This is quite relevant to FreeIPA and SSSD as we do run their tests in OpenQA as a part of Fedora Server release criteria.&lt;/p&gt;

&lt;p&gt;Another possible use case is to do a reverse training. Since we do know how a potential failure could look like, we can intentionally build an OpenQA test environment that would reproduce the failure and then train a model to recognize logs from such failures in real life scenarios. For example, establishing trust to Active Directory in FreeIPA is reliant on a working DNS setup, working firewall, etc. Failure to communicate through an incomplete firewall would be reflected with timeouts in the logs which we could train to recognize. There are endless possibilities here to aid through &lt;em&gt;known errors&lt;/em&gt;…&lt;/p&gt;

&lt;h3 id=&quot;hallway-track&quot;&gt;Hallway track&lt;/h3&gt;

&lt;p&gt;On a similar note, I had discussion with Amazon’s David Duncan in the ‘hallway track’ which started from an observation that Cloud SIG would really benefit from our passwordless work: distributing VMs with pre-set passwords is not ideal, an ability to inject FIDO2 passkey information and have everything obey it at login in cloud would be great to have. Somewhere along this way, discussion switched to CoreOS-based environments and I realised my experiments with Fedora Silverblue to develop passwordless support for FreeIPA would probably be a subject to a talk that would be interesting to others as well.&lt;/p&gt;

&lt;p&gt;I am running my own Silverblue images which source SSSD and FreeIPA upstream test builds to allow me easily to switch between different potential options in one go, without messing with an installation environment. It is quite important for the integration work we do and would be crucial for end-to-end testing of upcoming GNOME changes.&lt;/p&gt;

&lt;p&gt;This also provided me an insight into what container-based environments need from FreeIPA and overall from enterprise domains to fit nicely. I should have submitted a talk about that to Flock! Well, I will do one next year, for sure. (And, TODO: file issues to track for that integration to FreeIPA upstream!)&lt;/p&gt;

&lt;p&gt;Another interesting discussion we had with Jonathan Dieter. Jonathan is a long term Fedora contributor and FreeIPA user. For past several years Jonathan works with a local Irish company that provides services around the world to test local phone numbers. They maintain an infrastructure in more than 80 countries where there might be no global cloud providers at all. To keep that infrastructure reliable, they use &lt;a href=&quot;https://www.jdieter.net/posts/2021/11/30/piv-vs-sk/&quot;&gt;FreeIPA&lt;/a&gt; (not alone, of course) and &lt;a href=&quot;https://www.jdieter.net/posts/2020/10/31/switching-to-ostree/&quot;&gt;OStree-based images&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;asahi-linux-and-fedora&quot;&gt;Asahi Linux and Fedora&lt;/h3&gt;

&lt;p&gt;It is one of the talks that I missed to attend in person as conflicts are inevitable: Mo Duffy’s Podman Desktop talk and Adam Williamson’s Fedora CI state talk were running at the same time.&lt;/p&gt;

&lt;p&gt;Asahi Linux is a project which aims to upstream support for Apple’s ARM64 architecture, best known through Apple’s M1 and M2 systems. At the Flock Asahi Linux project members &lt;a href=&quot;https://asahilinux.org/2023/08/fedora-asahi-remix/&quot;&gt;have announced&lt;/a&gt; that not only Fedora Asahi Remix will be the flagship distribution for the project, but also &lt;a href=&quot;https://discussion.fedoraproject.org/c/neighbors/asahi/92&quot;&gt;Fedora Discourse instance&lt;/a&gt; will be used to handle Asahi Linux community collaborations.&lt;/p&gt;

&lt;p&gt;Asahi’s announcement also an example of how friendly has become Fedora Project as a community over years. I am definitely looking forward to see the remix to become one of official builds of Fedora.&lt;/p&gt;

&lt;h3 id=&quot;podman-desktop-from-fedora-to-kubernetes-for-beginners&quot;&gt;Podman desktop: from Fedora to Kubernetes for beginners&lt;/h3&gt;

&lt;p&gt;Mo Duffy gave an outstanding talk about using Podman desktop to deliver workloads for non-technical people. It was a highlight of the conference, for sure. She also made few interesting points. For one, running cloud-based workloads locally to allow offline operations is nice. Mo demonstrated a &lt;a href=&quot;https://blog.linuxgrrl.com/2022/01/19/running-penpot-locally-docker-free-with-podman/&quot;&gt;Penpot instance&lt;/a&gt;, which is a design and prototyping application. Running it locally helps to maintain the same workflow while on an intercontinental flight. However, even more interesting is that this approach also allows to use a cloud software that otherwise is considered insecure. For example, running a Wordpress setup locally to benefit from its nice UI in a local browser and export static web site content to push to the actual web hosting.&lt;/p&gt;

&lt;p&gt;By lowering a barrier to use containerised applications through Podman Desktop we may hope to get more people join our community and contribute. Starting with Podman Desktop’s friendliness would allow these newcomers to discover other Fedora flavors and features. It is certainly an interesting aspect we could expand further in a way similar how this ‘F’ in Fedora got expanded in Mo’s presentation.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/en/img/resized/2023-flock/podmandesktop-1-800-ecc520d5f.jpg&quot; srcset=&quot;/en/img/resized/2023-flock/podmandesktop-1-400-ecc520d5f.jpg 400w, /en/img/resized/2023-flock/podmandesktop-1-600-ecc520d5f.jpg 600w, /en/img/resized/2023-flock/podmandesktop-1-800-ecc520d5f.jpg 800w, /en/img/resized/2023-flock/podmandesktop-1-1000-ecc520d5f.jpg 1000w&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;panel-upstream-collaboration--cooperation-in-the-enterprise-linux-ecosystem&quot;&gt;Panel: Upstream collaboration &amp;amp; cooperation in the Enterprise Linux ecosystem&lt;/h3&gt;

&lt;p&gt;Another conference highlight was the panel that brought representatives of Fedora, RHEL, Rocky Linux, Alma Linux, and CentOS Stream together on stage. Distributions upstream and downstream of RHEL presented their views on various development and community topics. It is worth to &lt;a href=&quot;https://www.youtube.com/watch?v=r9iy9f80nic&amp;amp;t=24804s&quot;&gt;watch the stream&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;state-of-epel&quot;&gt;State of EPEL&lt;/h3&gt;

&lt;p&gt;Trow Dawson and Carl George did present another state of EPEL. EPEL has a solid contributors’ base who keep thousands of packages available to RHEL and downstream distributions’ users. EPEL is using Fedora infrastructure and for many packages it shares maintainers with Fedora (EPEL branches are branches in Fedora dist-git for the same package, if this package is not in RHEL). So all EPEL contributors are Fedora contributors. ;)&lt;/p&gt;

&lt;p&gt;One interesting aspect in every “State of EPEL” talk is a long tail of the EPEL demographics. Much like “State of Fedora” shows demographics of Fedora releases, EPEL statistics includes details on who is running the lowest number of downstream systems:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/en/img/resized/2023-flock/epelstate-1-800-5bf2b26ad.jpg&quot; srcset=&quot;/en/img/resized/2023-flock/epelstate-1-400-5bf2b26ad.jpg 400w, /en/img/resized/2023-flock/epelstate-1-600-5bf2b26ad.jpg 600w, /en/img/resized/2023-flock/epelstate-1-800-5bf2b26ad.jpg 800w, /en/img/resized/2023-flock/epelstate-1-1000-5bf2b26ad.jpg 1000w&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;passwordless-fedora&quot;&gt;Passwordless Fedora&lt;/h3&gt;

&lt;p&gt;My talk was on the morning of the second day. People were still recovering from the night of International Candy Swap and table games so at start I had may be a couple of attendies. Eventually, we’ve got more people in the room and there were also online attendees so it wasn’t so feeling so lonely.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=GkYURkrIzx0&amp;amp;t=3226s&quot;&gt;My talk&lt;/a&gt; was similar to previous ones at FOSDEM and SambaXP. What was new is a demo from Ray Strode on how potentially a user experience could look like in GNOME for a passwordless login. Ray implemented a prototype of external identity provider login flow that Allan Day &lt;a href=&quot;https://gitlab.gnome.org/Teams/Design/os-mockups/-/issues/220&quot;&gt;has shared recently&lt;/a&gt;. This flow could be used for login through Microsoft’s Entra ID (a.k.a. Azure AD) or any OAuth2 provider supported by FreeIPA. We aren’t fully there yet but the goal is to do this work once for GNOME and reuse for various passwordless authentication approaches supported through SSSD.&lt;/p&gt;

&lt;p&gt;I also showed an &lt;a href=&quot;https://youtu.be/zK2FmP0j6tY&quot;&gt;old demo&lt;/a&gt; from my FOSDEM and Flock 2016. It shows how we integrated 2FA tokens (Yubikeys in this example) with FreeIPA to authenticate and obtain Kerberos tickets through a KDC proxy over HTTPS. These tickets then were used to login onto a VPN. This is something that is possible in Fedora and RHEL for almost a decade now.&lt;/p&gt;

&lt;h3 id=&quot;openqa-hacking&quot;&gt;OpenQA hacking&lt;/h3&gt;

&lt;p&gt;Before Flock, Adam Williamson started to work on integrating Samba AD tests into OpenQA for Fedora. It almost worked well but there were few issues Adam wasn’t able to resolve so we set down at the Flock and figured out at least few of those. The only remaining one was an apparent race condition within a test that enrolls a system to Samba AD using kickstart. SSSD, it seems, starts before networking is up and stable, and decides that it is offline. When the test tries to resolve an Active Directory user, SSSD fails to do so as it thinks to be offline.&lt;/p&gt;

&lt;p&gt;Interestingly, the same test against FreeIPA works fine. The same test done past kickstart works fine as well, for both FreeIPA and Samba AD. There is probably a need to add a waiting period to settle a network state. We saw this in past too but never found a good way to trigger a proper event for SSSD to recover.&lt;/p&gt;

&lt;h3 id=&quot;social-events&quot;&gt;Social events&lt;/h3&gt;

&lt;p&gt;I am trying to reduce candy consumption so I skipped the social events on the first day but attended the conference dinner on the second day. All social events during the Flock well organized and this one wasn’t exception either. We had interesting discussions with Fedora and Rocky folks, getting to know there is a lot of similarity in how people do their lives across the world.&lt;/p&gt;

&lt;p&gt;On Friday’s night another social event was a Ghost Tour. However, we skipped it and together with few other people went to do a bit of memorabilia road through another Mexican place and (of course!) a local bar. Life in IT and development in 90’s and early 2000’s weren’t that much different in US and Europe, really. Thanks to Spot and Amazon for covering the dinner, thanks to other folks for beer and a company.&lt;/p&gt;

&lt;p&gt;I left on Saturday at noon using the same Aircoach bus towards Dublin airport. The bus was full – make sure you have booked your seat online in advance. My flight back to Finland was uneventful as well. Overall, it was a great conference, as usual. I’d like to say thank you to all volunteers and organizers who keep Flock so wonderful and Fedora project so welcoming. Thank you!&lt;/p&gt;

</description>
        <pubDate>Fri, 11 Aug 2023 13:46:00 +0300</pubDate>
        <link>https://vda.li/en/posts/2023/08/11/Flock-report/</link>
        <guid isPermaLink="true">https://vda.li/en/posts/2023/08/11/Flock-report/</guid>
        
        <category>freeipa</category>
        
        <category>fedora</category>
        
        <category>centos</category>
        
        
        <category>posts</category>
        
      </item>
    
    
    
    
    
    
    
    
    
      <item>
        <title>FreeIPA authentication improvements and Fedora Infrastructure part 2</title>
        <description>&lt;p&gt;This article continues the &lt;a href=&quot;https://vda.li/en/en/posts/2022/10/28/FreeIPA-Authentication-Improvements-and-Fedora-Infra/&quot;&gt;discussion&lt;/a&gt;
about FreeIPA authentication improvements and how they could benefit Fedora
Infrastructure.&lt;/p&gt;

&lt;p&gt;FreeIPA 4.9.10 has added support for &lt;a href=&quot;https://freeipa.readthedocs.io/en/latest/workshop/12-external-idp-support.html&quot;&gt;relaying
authentication&lt;/a&gt;
to OAuth2 identity providers (IdPs). Users would get their access to FreeIPA
resources mediated by an external OAuth2 identity provider which supports OAuth2
device authorization grant flow (RFC 8628). This is not too dissimilar from how
smart TVs connect to Youtube and other media services on your behalf. A user
would be able to grant access to a scoped information to a FreeIPA OAuth2 client
registered with such IdP. In order to authorize the access, the user might need
to login to the IdP first and this is performed with the help of a browser
running elsewhere. Most common browsers do have support for Webauthn/FIDO2
tokens, thus it is possible to build a system where a login to FreeIPA-enrolled
system is authenticated by the FIDO2 token exclusively.&lt;/p&gt;

&lt;p&gt;Based on the result of the external IdP authorization grant, FreeIPA would then
issue a Kerberos ticket to the user. The ticket can then be used for single
sign-on across all FreeIPA services.&lt;/p&gt;

&lt;p&gt;The functionality to authenticate against an external IdP is already available
in Fedora 36 versions of FreeIPA and SSSD. It is also available in RHEL 8.7 and
9.1 beta versions published in late September 2022.&lt;/p&gt;

&lt;p&gt;Relying on an external identity provider to authenticate your FreeIPA users
would also mean rethinking the relationship between the IdP and the FreeIPA
deployment. Typically, when people integrated FreeIPA with OAuth2 or SAML
identity providers, an assumption was made that user authentication is handled
by the FreeIPA servers and identity provider issues a token for a web
application. Turning this situation around means FreeIPA only becomes a user
data store – maybe even not the data store for the IdP itself. IdP would only
need to know about the user identity from its own point of view while FreeIPA
would have a POSIX identity of the same user, consumed by other applications.
Whether it is visible through the IdP grants or via POSIX interfaces is more of
an application implementation detail. Decoupling these details leads to a bit of
duplication, of course, but allows for better flexibility. A user might come
from a federated source and have their authentication handled by a different
identity provider – their public service provider like Google, Github, Gitlab,
or Microsoft Azure. Or Facebook and any other social media.&lt;/p&gt;

&lt;p&gt;All this, however, would mean a change to the way Fedora Accounts system
and Fedora IdP, Ipsilon, interact with each other. Right now Ipsilon
sources accounts information from the FreeIPA instance directly and
delegates authentication to it as well (though PAM service provided by
SSSD). Fedora Accounts system, in its turn, manages passwords and tokens
in the FreeIPA instance. Since FreeIPA does not have support for
Webauthn/FIDO2 web-based authentication yet, Ipsilon would need to
manage that itself. So some user accounts would need to source their
authentication details from FreeIPA and some would need to use Ipsilon’s
internal source. That is a bit complicated as Ipsilon has no way to
combine data sources.&lt;/p&gt;

&lt;p&gt;Ipsilon does not have any support for both OAuth2 device authorization
grant flow and Webauthn/FIDO2 tokens. Even if the FreeIPA instance used
by both Fedora project and CentOS project would be updated to provide
external IdP authentication, the Ipsilon instance would not be able to
utilize this new feature.&lt;/p&gt;

&lt;p&gt;Another alternative would be to use Keycloak (free software project upon which
Red Hat Single Sign-On product is built). Keycloak 21 is adding multiple user
stores support and the FreeIPA team works on &lt;a href=&quot;https://github.com/justin-stephenson/scim-keycloak-user-storage-spi&quot;&gt;a new
provider&lt;/a&gt;
to utilize it. This new Keycloak user store plugin supports SCIM v2 API and also
needs a &lt;a href=&quot;https://github.com/freeipa/ipa-tuura&quot;&gt;new FreeIPA application&lt;/a&gt; that
abstracts out access to FreeIPA resources as a SCIM v2 API. In the end, it is
the same SSSD as a backend as in case of the Ipsilon IdP but with the ability to
split the data store across multiple sources. Keycloak already has support for
both OAuth2 device authorization grant flow and the Webauthn/FIDO2 tokens. How
this all works together is shown in our &lt;a href=&quot;https://www.youtube.com/watch?v=NorXJN3tw3Q&amp;amp;list=PL0x39xti0_65yq9EuNtSLts0qm9_T-YiI&amp;amp;index=34&quot;&gt;&lt;em&gt;Nest with Fedora 2022
talk&lt;/em&gt;&lt;/a&gt;.
Talk slides can be &lt;a href=&quot;https://vda.li/talks/2022/2022-Nest-With-Fedora-FreeIPA-and-OAuth2.pdf&quot;&gt;found here&lt;/a&gt;
but the video includes a live demo session.&lt;/p&gt;

&lt;p&gt;On mobile devices front, both Google and Apple are gearing towards introduction
of software tokens for Webauthn/FIDO2, often called ‘passkeys’ in the
user-oriented marketing materials. These passkeys effectively shared across
devices where a user is logged in and uses a shared password wallet. The Google
Security team &lt;a href=&quot;https://security.googleblog.com/2022/10/SecurityofPasskeysintheGooglePasswordManager.html&quot;&gt;goes at
length&lt;/a&gt;
explaining why this is secure, although some researchers &lt;a href=&quot;https://medium.com/@arkenoi/what-is-wrong-with-apple-passkeys-1d044072c5a3&quot;&gt;aren’t
convinced&lt;/a&gt;
(this is more about Apple implementation, though).&lt;/p&gt;

&lt;p&gt;Consuming software tokens stored in a mobile device from a computer for
authentication would need additional support from the identity providers.
Neither Ipsilon nor Keycloak implement that. For native Android applications
&lt;a href=&quot;https://android-developers.googleblog.com/2022/10/bringing-passkeys-to-android-and-chrome.html&quot;&gt;Google just announced&lt;/a&gt;
they’ll provide an API in what remains of 2022.&lt;/p&gt;

&lt;p&gt;Finally, going outside of Fedora Project’s infrastructure, supporting
Webauthn/FIDO2 to login to Linux servers and desktops in a centrally
managed way is still not there.&lt;/p&gt;

&lt;p&gt;Both FreeIPA and SSSD teams are working on a more direct integration
with FIDO2 tokens. Instead of relying on an OAuth2 identity provider to
handle Webauthn/FIDO2 operations in the browser, SSSD is integrating
with libfido2 library to make FIDO2 token’s use on the machine locally.
This would replace the pam_u2f module and would allow FreeIPA to provide
centralized management of the FIDO2-based passkeys. On top of that,
FreeIPA will provide Kerberos integration: login with the FIDO2 token
would be turned into a Kerberos ticket and single sign-on operations
would be ensured across multiple services, like it is done today for
traditional Kerberos pre-authentication methods. A benefit is that
passwords can be completely removed for the users with direct FIDO2
token enrollment.&lt;/p&gt;

&lt;p&gt;FreeIPA-enrolled clients (Fedora 36+, RHEL 8.7/9.1 betas) already can login via
external IdP as outlined above but only for the SSH or a direct console login.
Login over graphical desktop is not working well: a message telling to visit an
IdP page and authorize the device access does not fit into a gdm login entry
which is used to show the message coming from the PAM stack. GDM is also not
able to go to that URL directly as there is still no support for opening a
browser instance pre-login in GNOME or any other desktop manager. We are looking
at implementing this with GNOME developers similar to how a smartcard selection
was added in 2017. Hopefully, this will come to one of the next Fedora versions
…&lt;/p&gt;

&lt;p&gt;Notwithstanding open issues, we are pretty much close to enabling
FreeIPA-enrolled Linux systems to go passwordless. It is not yet a year
of passwordless Linux like not a year of Linux on the desktop but making
it reality is not that far away. Perhaps I am too optimistic, though –
like we were all before with Linux on the desktop.&lt;/p&gt;
</description>
        <pubDate>Fri, 28 Oct 2022 09:50:00 +0300</pubDate>
        <link>https://vda.li/en/posts/2022/10/28/FreeIPA-Authentication-Improvements-and-Fedora-Infra-2/</link>
        <guid isPermaLink="true">https://vda.li/en/posts/2022/10/28/FreeIPA-Authentication-Improvements-and-Fedora-Infra-2/</guid>
        
        <category>freeipa</category>
        
        <category>fedora</category>
        
        
        <category>posts</category>
        
      </item>
    
    
    
    
    
    
    
      <item>
        <title>FreeIPA authentication improvements and Fedora Infrastructure part 1</title>
        <description>&lt;p&gt;The Fedora project exists because of its contributors. Their contributions shape
the landscape of Linux distributions in a direct way but they also have made a
significant influence on the Open Source projects themselves. Fedora
contributors are not only people who participate in package maintenance, there
are upstream developers, documentation writers, quality assurance engineers
across multiple industries, students, volunteers and many many others. As with
many other areas, this participation is bi-directional and practices established
in the Fedora project may apply elsewhere too.&lt;/p&gt;

&lt;p&gt;One area dear to me is authentication. The FreeIPA project serves as an umbrella
to provide a consistent centralized identity management and authentication
solution for Linux systems (in the first place, though standards-compliant,
UNIX-like operating systems benefit from its use as well). FreeIPA’s core is
built around Kerberos authentication protocol and SSSD daemon. It makes use of
Kerberos’ features for single sign-on ease on the client side.&lt;/p&gt;

&lt;p&gt;Many Free Software and Open Source projects use FreeIPA to deploy centralized
identity management, authentication and authorization for their own
contributors. Examples can be found small and large: GNOME project was one of
the earliest, &lt;a href=&quot;https://mail.gnome.org/archives/infrastructure-announce/2014-October/msg00001.html&quot;&gt;&lt;em&gt;migrating its infrastructure&lt;/em&gt;&lt;/a&gt;
to FreeIPA in 2014. The Fedora project is not an exception, it has been using
FreeIPA for quite some time, though FreeIPA deployment was only handling
Kerberos – user accounts were stored in a different place and synchronized with
FreeIPA. The old Fedora account system was gradually rewritten to be built on
top of FreeIPA and in 2021 all accounts were migrated to the new system.&lt;/p&gt;

&lt;p&gt;Fedora accounts system allows users to login with a password and
optionally to use two-factor authentication with the help of TOTP
tokens. Users can also associate GnuPG or SSH public keys with
themselves. These details get consumed by various Fedora applications
but there are several important use cases:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Issue Kerberos ticket which can be used to authenticate against a
build system used by Fedora&lt;/li&gt;
  &lt;li&gt;Access servers over SSH protocol, with Kerberos tickets or SSH keys&lt;/li&gt;
  &lt;li&gt;Use Kerberos ticket or authenticate with password to Fedora
Project’s identity provider and authorize Fedora applications to
access user data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;FreeIPA supports more authentication methods in its Kerberos implementation but
they aren’t used by the Fedora project. On the other hand, the CentOS Project
shares its FreeIPA instance with Fedora and uses certificates issued by the
FreeIPA CA for its authentication. These certificates can be used to obtain
Kerberos tickets as well. For both projects this FreeIPA instance is maintained
by the Community Platform Engineering team who looks after both communities’
needs.&lt;/p&gt;

&lt;p&gt;Since the Fedora Project is an important gateway to Red Hat Enterprise Linux,
many Fedora contributors were recently raising security concerns around secure
software delivery and asking how we can improve authentication and authorization
for Fedora infrastructure. For gory details, &lt;a href=&quot;https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.org/thread/UG3UOKBVJLUWZYEHWL52KPMITPEPEBNF/&quot;&gt;&lt;em&gt;the
thread&lt;/em&gt;&lt;/a&gt;
about removing access of inactive packagers after Fedora 37 release has a
&lt;a href=&quot;https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.org/message/42GIRNMSLPVU7AUMAJZRIYKAR7Y5S3PY/&quot;&gt;&lt;em&gt;few&lt;/em&gt;&lt;/a&gt;
&lt;a href=&quot;https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.org/message/AB2X2SMKVEZBW4XLUMGIMLMB2YFB3HT4/&quot;&gt;&lt;em&gt;examples&lt;/em&gt;&lt;/a&gt;.
A common agreement is that use of Webauthn and FIDO2 tokens &lt;a href=&quot;https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.org/message/3FIMWGN233AFMPPYSRNSLQKYYRPHUNGC/&quot;&gt;&lt;em&gt;would definitely
improve the security&lt;/em&gt;&lt;/a&gt;,
especially coupled with the prevention of an authentication methods’ downgrades.&lt;/p&gt;

&lt;p&gt;Moving to Webauthn/FIDO2 would probably be relatively easy if every single
application to access in the Fedora infrastructure would be a web-based. For
example, OAuth2 clients could be forced to operate on specific scopes of the
user data which would only be granted if strong authentication methods were used
to authenticate. For SSH-based access it would also be possible to get SSH keys
based on a native FIDO2 support in OpenSSH and prevent use of other key types.
However, a single sign-on functionality would be lost then as currently it is
not possible to convert SSH public key access to Kerberos tickets nor is it
possible to use FIDO2 keys natively in Kerberos flows.&lt;/p&gt;

&lt;p&gt;Use of FIDO2 tokens introduces another problem, though, this time a social one.
Fedora Project is famous for its wide contributor base, spanning many countries
and continents. Fedora Project contributors come from all kinds of backgrounds
and so far the only requirement to enable their contributions from a technical
point of view was internet access. Even enforcement of the two-factor
authentication with the help of TOTP tokens could have been mitigated by use of
a software token on a mobile device or simulated on a computer. In many
countries access to mobile devices is easier than to any hardware token. It is
still a cost and somebody has to pay for it. The cheapest FIDO2 token is around
10 EUR, although a single token can be used against many resources (websites).
There is a cost to enforce stronger authentication methods and somebody would
need to pay it if the Fedora project chooses to raise the requirements. Perhaps,
companies benefiting from the secure software development processes around
Fedora distribution would be willing to step up?&lt;/p&gt;

&lt;p&gt;In &lt;a href=&quot;/en/posts/2022/10/28/FreeIPA-Authentication-Improvements-and-Fedora-Infra-2/&quot;&gt;the next article&lt;/a&gt;
I will look at how FreeIPA could help with the technical side of supporting
Webauthn/FIDO2 use by Fedora contributors.&lt;/p&gt;
</description>
        <pubDate>Fri, 28 Oct 2022 08:50:00 +0300</pubDate>
        <link>https://vda.li/en/posts/2022/10/28/FreeIPA-Authentication-Improvements-and-Fedora-Infra/</link>
        <guid isPermaLink="true">https://vda.li/en/posts/2022/10/28/FreeIPA-Authentication-Improvements-and-Fedora-Infra/</guid>
        
        <category>freeipa</category>
        
        <category>fedora</category>
        
        
        <category>posts</category>
        
      </item>
    
    
    
    
    
  </channel>
</rss>
