Library / SDK
OpenIDC/mod_auth_openidc avatar
OpenIDC/mod_auth_openidc

mod_auth_openidc: putting OpenID Connect and FAPI in front of Apache without touching the app

OpenID Certified™ OpenID Connect and FAPI 2 Relying Party module for Apache HTTPd

1,096 stars332 forksCApache-2.0

At a glance

What is it?
mod_auth_openidc is an Apache HTTP Server module that acts as an OpenID Connect and FAPI 2 Relying Party, relaying authentication to a provider and passing the resulting claims to the application through REMOTE_USER, HTTP headers and environment variables. The point of the design is that the protected application does not need to know OpenID Connect exists at all.
Who is it for?
mod_auth_openidc fits an organisation with existing applications, possibly single page apps, that need standards based single sign-on without a rewrite, and that runs Apache in front of them. It is the wrong tool if your application already does its own token handling well, because then you would have two implementations, and the wrong tool if you are not able to run Apache at all.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly C, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The module's job is to be invisible to the application

mod_auth_openidc is an OpenID Certified authentication and authorization module for the Apache 2.x HTTP server that implements the OpenID Connect 1.x and FAPI 2.x Relying Party functionality. The primary language is C, the licence is Apache-2.0, and the homepage is openidc.com.

The mechanism is a relay. The module enables an Apache 2.x web server to operate as an OpenID Connect Relying Party towards a Provider. It relays end user authentication to that Provider and receives user identity information from it, then passes that identity information, the claims, on to applications protected by the Apache server, and establishes an authentication session for the identified user.

What makes this useful is where it sits. The protected content can be hosted by the Apache server itself, or served from origin servers behind it by configuring Apache as a reverse proxy. That second case is the interesting one, because the README says it allows adding OpenID Connect based authentication to existing applications and single page apps without modifying those applications, possibly migrating them away from legacy authentication mechanisms to standards based single sign on.

So the migration story is that you put Apache in front, turn on this module, and the application keeps working with whatever it did before while the authentication underneath becomes OpenID Connect. The application does not need a library, does not need to handle a token, does not need to know there is an identity provider. That is a much lower barrier than retrofitting OIDC into every service, and it is why a C Apache module still has a large user base in an era of framework-based OIDC clients.

The claims arrive in a conventional shape. By default the module sets the REMOTE_USER variable to the id_token sub claim concatenated with the provider's issuer identifier, in the form sub@iss. Other id_token claims are passed in HTTP headers and environment variables, together with those optionally obtained from the UserInfo endpoint, and the application consumes them the same way it would consume a REMOTE_USER from any other authentication module.

The topic tags name the surface: access-control, apache-httpd, authentication, oidc, openid-connect, sso.

Authorization is done with Apache's own Require primitives

The authorization story is the part that makes this more than a login module, and it is built on something that already exists in Apache rather than on a new policy language.

Custom fine-grained authorization rules, based on Apache's Require primitives, can be specified to match against the set of claims provided in the id_token and userinfo claims. The documentation for that is on a separate wiki page for Authorization.

This matters because the alternative designs all require a decision. Either the module evaluates claims itself with its own rule syntax, or it exposes claims and lets the application decide, or it maps claims onto something the existing server already understands. This one takes the third route, using the Require directive that Apache already has for IP and host based access control.

So a location can require a specific claim value, and the same configuration style that already governs your IP allowlists governs your claim checks. An administrator reading the httpd configuration sees one access control vocabulary. And because the claims are set as headers and environment variables before the Require evaluation runs, the request has already been enriched by the time Apache's normal authorisation phase happens.

The wiki also has a page for configuring multiple providers, which is a real requirement in a federated organisation. The module can talk to more than one OpenID Connect Provider, and the README links that page as the place to look.

For resilience, clustering for resilience and performance can be configured using one of the supported cache backends, with the list on a wiki page for Caching. That is a separate concern from the protocol and worth separating in your head, because the cache is what holds the session state and the provider metadata, and it is the piece that has to be shared across a cluster and shared between processes on the same host.

Two configuration files carry the weight. The complete overview of all configuration options is in auth_openidc.conf, and that file can also serve as an include file for httpd.conf. So the reference documentation and a usable configuration fragment are the same artefact, which is an old but good autoconf tradition.

The final piece of the authorisation model is the session. The module establishes an authentication session for the identified user, which means the browser carries a session token rather than the application handling a token, and that session is what the cache backend holds.

The minimal configuration, and the one line that will bite you

The README gives a minimal working configuration, and it is worth reading closely because one directive in it is doing more work than it looks.

apache
LoadModule auth_openidc_module modules/mod_auth_openidc.so

# OIDCRedirectURI is a vanity URL that must point to a path protected by this module but must NOT point to any content
OIDCRedirectURI https://<hostname>/secure/redirect_uri

# required to persist sessions across restarts and share them across a cluster;
# when omitted a random passphrase is generated at each restart, invalidating existing sessions
OIDCCryptoPassphrase <passphrase-or-"exec:/path/to/generator">

OIDCProviderMetadataURL <issuer>/.well-known/openid-configuration
OIDCClientID <client_id>
OIDCClientSecret <client_secret>

<Location /secure>
   AuthType openid-connect
   Require valid-user
</Location>

The order of the setup steps in the README is: install and load mod_auth_openidc.so, set OIDCRedirectURI to a vanity URL within a location protected by the module, configure OIDCProviderMetadataURL to point at the provider's Discovery metadata on the .well-known/openid-configuration endpoint, register or generate a client identifier and secret and configure them in OIDCClientID and OIDCClientSecret, register that redirect URI as the callback URI for the client at the provider, and then configure the protected locations with AuthType openid-connect.

The redirect URI comment says it must point to a path protected by this module but must not point to any content. It is a URL the identity provider sends the browser back to, and it has to be inside the protected area so the module can handle the authorization code, and it has to be a path with no actual content behind it, because the module intercepts it.

OIDCCryptoPassphrase is the line that will bite you. The comment says it is required to persist sessions across restarts and to share them across a cluster, and that when it is omitted a random passphrase is generated at each restart, invalidating existing sessions.

That behaviour is defensible as a default, since generating a random key is safer than shipping a hardcoded one. But the consequence is that an out-of-the-box install will silently log every user out every time Apache restarts, and in a cluster the nodes will not share sessions unless they all have the same passphrase. The directive accepts either a literal passphrase or an exec: form pointing at a command that generates one, which is the way to keep the key out of the configuration file.

The AuthType openid-connect line and Require valid-user are the two lines that turn a location into a protected one. The Require valid-user primitive is the standard Apache way of saying any authenticated user will do, and the finer claim based rules go on top of it.

Provider specific quickstarts, and why the module stays provider agnostic

The module does not care which provider you use, and the quickstart list in the README is really a list of the cases that most often need extra configuration.

There is a Keycloak page, a Microsoft Entra ID, which the README also refers to as Azure AD, page, a Google Accounts page, a Sign in with Apple page, a GLUU Server page and a Curity Identity Server page, with a link to more useful links at the end of the list.

The existence of a per-provider page for each is a good sign of the project's maturity. A provider that requires a non-standard parameter location, a particular response mode, a client authentication method that is not the default, or a custom scope will not work from the generic discovery based configuration, and a module that is going to be deployed for real has to acknowledge that rather than pretend discovery is enough.

The generalisation to make is that the module talks to any OpenID Connect Provider that implements standard Discovery, and the per-provider pages are the accumulated knowledge of where real providers deviate from the standard. That is a genuinely useful resource, and it is a better test of the module's practical maturity than the specification list, because a provider that works with no special configuration is the exception rather than the rule in a real deployment.

The Apple entry is worth a note, because Sign in with Apple is a common case that is not a straightforward OIDC client. A per-provider page exists because there is a specific thing to configure, and the existence of that page is the kind of detail that separates a module that people deploy from one that people evaluate.

The same pattern holds for the other entries. In each case the module's generic path still applies and the page tells you what to set.

Certification, the specification list, and the C codebase behind it

mod_auth_openidc is OpenID Certified, and the badge in the README links to the certification mark on openid.net. The supported specifications are listed: OpenID Connect Core 1.0 in the Basic, Implicit, Hybrid and Refresh flows, RFC 7636 for Proof Key for Code Exchange by OAuth public clients, the FAPI 2.0 Security Profile, FAPI 2.0 Message Signing, and RFC 9126 for OAuth 2.0 Pushed Authorization, with the list continuing past what is shown here.

Covering all four OIDC flows plus PKCE plus the FAPI 2 profiles is a broader claim than most implementations make, and the certification is what makes it meaningful, since it is an external assessment rather than a self description.

The repository layout shows a C project with autotools. There is configure.ac, an autogen.sh, an m4/ directory for the autoconf macros, a Makefile.am, a src/ directory, and a test/ directory. INSTALL holds the full dependency list for a source build, and ChangeLog is present alongside the more usual files.

The build from source is the standard apxs route:

sh
./configure --with-apxs=/usr/bin/apxs2   # apxs2 may be named apxs on your platform
make
sudo make install

The comment about apxs2 possibly being named apxs is the kind of note that saves an hour, since the Apache extension tool has a different name on some platforms.

Installing a pre-built binary package is preferred, and on Debian and Ubuntu that is:

sh
apt install libapache2-mod-auth-openidc

Packages for other platforms are listed in the wiki, and release binaries are attached to the GitHub releases.

The quality tooling in the repository is worth noting for a C project of this age. There is a .clang-format and a .clang-tidy, so the code is both formatted and linted by modern tools, and a sonar-project.properties file matching the SonarCloud badges in the README, which show a quality gate status, a coverage measure and a per-component coverage breakdown. A quality gate status badge is a stronger statement than a coverage percentage, because it says there is a threshold that fails the build.

The CI is a GitHub Actions workflow, and the release history is steady. The recent releases are v2.4.20.3 on 2026-09-01, v2.4.20.2 on 2026-08-10 and v2.4.20.1 on 2026-08-09, so a four part version scheme with patches every few weeks. The repository is not archived and the last push was on 2026-10-15, so the module is actively maintained rather than merely still working.

Editorial conclusion

mod_auth_openidc fits an organisation with existing applications, possibly single page apps, that need standards based single sign-on without a rewrite, and that runs Apache in front of them. It is the wrong tool if your application already does its own token handling well, because then you would have two implementations, and the wrong tool if you are not able to run Apache at all. Before deploying, read the complete configuration reference in auth_openidc.conf rather than the minimal example, set OIDCCryptoPassphrase explicitly instead of letting one be generated, and pick a cache backend for the cluster, because the default is per process and will not survive a restart.

Frequently asked questions

What does mod_auth_openidc do in Apache?

It makes the Apache server an OpenID Connect and FAPI 2 Relying Party. It relays user authentication to the OpenID Connect Provider, receives the claims, establishes an authentication session, and passes the identity information on to the protected applications through REMOTE_USER, HTTP headers and environment variables, without those applications needing to implement OpenID Connect themselves.

How do I configure mod_auth_openidc for a provider?

Load the module, set OIDCRedirectURI to a vanity URL inside a protected location that points to no content, set OIDCProviderMetadataURL to the provider's .well-known/openid-configuration endpoint, set OIDCClientID and OIDCClientSecret, register that redirect URI at the provider, and set AuthType openid-connect with Require valid-user on the locations you want to protect.

Why do my sessions disappear when Apache restarts?

OIDCCryptoPassphrase is required to persist sessions across restarts and to share them across a cluster, and when it is omitted a random passphrase is generated at each restart, invalidating existing sessions. The directive accepts a literal passphrase or an exec: form pointing at a command that generates one.

How do I make authorization depend on specific claims in mod_auth_openidc?

The module supports custom fine-grained authorization rules based on Apache's Require primitives, matched against the claims in the id_token and the userinfo endpoint. The wiki page on Authorization covers the details, and there is a separate page for configuring multiple providers.

Official sources

  1. License: Apache-2.0
  2. OpenIDC/mod_auth_openidc on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/openidc-mod-auth-openidc.svg)](https://hysenlabs.com/projects/openidc-mod-auth-openidc)

Was this useful?