Skip to main content

Sovereign FerrisKey IAM (OIDC SSO)

Centralizing authentication across an organization is convenient: one login opens every service. But that single gateway also becomes the most sensitive point of your information system. Every login, every identity, every group transits through it. Handing it to Okta, Auth0 or Entra ID means placing that identity directory on infrastructure subject to US law.

Bunker runs FerrisKey instead, an open-source identity and access management (IAM) server written in Rust and released under the Apache-2.0 licence, hosted in Europe. Your identities stay on the continent, and the service stays re-internalizable: both the software and the data can move back onto your own infrastructure.

Access: a FerrisKey server dedicated to your project, for example managed-yourslug-ferriskey-yourproject.apps.france-nuage.fr.

What an IAM does​

An IAM (Identity and Access Management) is the central directory that answers two questions for all your applications: who are you? (authentication) and what are you allowed to do? (authorization). Instead of each piece of software managing its own accounts and passwords, they all delegate that responsibility to FerrisKey.

Concretely, FerrisKey provides:

  • OIDC single sign-on (SSO): the user logs in once, then reaches every connected service without re-entering credentials.
  • Multi-organization realms: each organization (or entity, or client) gets its own isolated space, with its users, groups and rules.
  • Identity brokering: FerrisKey can delegate authentication to another identity provider, which enables the federation described below.
  • A self-service admin UI: create a realm, declare an application (OIDC client), manage users and roles, without filing a ticket.

OIDC-compatible with Keycloak​

FerrisKey exposes the same OpenID Connect URLs as Keycloak. The discovery document sits at the standard location:

https://managed-yourslug-ferriskey-yourproject.apps.france-nuage.fr/realms/<your-realm>/.well-known/openid-configuration

and the endpoints follow the same /realms/<your-realm>/... convention (authorization, token, userinfo, JWKS). The practical upshot: an application already configured for Keycloak connects to FerrisKey by simply changing the issuer URL. Any standard OIDC client library (on the application side) works without adaptation.

Hub-and-spoke federation​

The managed service is built on a hub-and-spoke federation. Bunker runs a central FerrisKey (the hub) that brokers authentication to a FerrisKey dedicated to your organization (the spoke). Each organization keeps its own realm, users and rules.

The benefit: your applications only talk to your FerrisKey, and that space is yours. At any time you can export its configuration and users to re-internalize it on your own infrastructure.

Protecting a site behind the zero-trust edge​

Managed services are exposed behind the Bunker zero-trust edge, built on the open-source Pangolin software. Each customer company has its own organization on it, and that organization relies on the company's IAM.

One organization, its company's IAM​

Once your company's IAM is declared (FerrisKey over OIDC, one realm per company, for example https://auth.your-domain.com/realms/your-company), the edge uses it as your organization's identity provider. Your users have no local account on the edge, and there is nothing to configure in the Pangolin interface.

One annotation on the Ingress​

A site becomes protected when its Ingress carries the zero-trust.france-nuage.fr/sso: "true" annotation:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-application
annotations:
zero-trust.france-nuage.fr/sso: "true"

A visitor who is not logged in is then redirected straight to the IAM of the organization that owns the site, with no intermediate login screen.

A site without the annotation keeps its behaviour: if it is public, it stays public. And the automation only ever protects: it never opens a site that is already protected.

Exempting an API's paths​

The login wall only works for a browser. A script, an agent or an uptime probe calling your API with a key cannot sign in through it. If your application authenticates those routes itself, declare them on the same Ingress with the zero-trust.france-nuage.fr/sso-bypass-paths annotation. The edge then lets them through without a session, and the rest of the site still requires a login.

metadata:
annotations:
zero-trust.france-nuage.fr/sso: "true"
zero-trust.france-nuage.fr/sso-bypass-paths: "/api/*"
  • Patterns: a comma-separated list. A * segment matches zero, one or more segments, so /api/* matches /api and everything below it, but not /apix. A * inside a segment matches any characters within that segment.
  • Limits: at most 10 patterns per site (the Ingresses of one site add up) and at most 200 characters per pattern. Between the /, only A-Z a-z 0-9 . _ ~ * - are allowed. The . and .. segments are rejected, and so is a pattern made only of *, since /* would exempt the whole site.
  • Normalization: the edge decodes and resolves the path before comparing it. It therefore treats /api/../admin as /admin, which is not exempted. This normalization does not replace your application's own access control.
  • Invalid annotation: the site stays in its previous state, and other sites are not affected.
  • Ordering: exemptions are applied before protection, so that putting a site behind SSO does not cut off its exempted paths.
  • Without sso: the annotation is ignored. Removing sso freezes the site as it is, exemptions included.

The edge serves an exempted path as is. Your application has to reject a request without a valid key, so only exempt routes it authenticates itself.

Do not lock your IAM's own host​

An IAM cannot sit behind its own login wall

Putting sso on the FerrisKey host itself, without exempting its login path, shuts everyone out.

The edge sends a visitor who is not logged in to the organization's IAM. If the protected site is that IAM, the redirect leads to a page that is itself protected: reaching the login page would require being logged in already. Nobody gets in any more, not your users, not your applications, not your administrators, since the FerrisKey console sits behind the same protection.

The other mistakes described above can be undone. This one cannot: logging in again does nothing, and removing sso does not reopen the host, since the automation never opens a site that is already protected. The only way out left is to complete the exemption on the Ingress, and only if your own access to the cluster does not itself go through this IAM.

You have two options.

1. Do not annotate your IAM's host. This is the default, and the right choice in most cases. FerrisKey already authenticates its users itself. Putting it behind a protection that depends on it adds nothing.

2. Put it behind the edge anyway, with its login path exempted. FerrisKey serves that path from two components: the API, which carries the OIDC issuer (/realms/<your-realm>/…), and the web application, which shows the login page under /realms/<your-realm>/authentication/… and loads its resources from the root. For FerrisKey 0.9.0, the full path fits in these ten patterns:

PatternComponentPurpose
/realms/<your-realm>/protocol/openid-connect/*APIauthorization, tokens, public signing keys, logout
/realms/<your-realm>/.well-known/*APIOIDC discovery read by your applications
/realms/<your-realm>/login-settingsAPIsettings shown on the login page
/realms/<your-realm>/login-actions/*APIpassword, one-time code, passkey, reset
/realms/<your-realm>/portal/activeAPIlogin page theme
/configAPIpublic configuration read by the web application
/realms/<your-realm>/authentication/*web applicationlogin, verification and callback pages
/assets/*web applicationscripts and stylesheets
/config.jsonweb applicationAPI address
/logo_ferriskey.pngweb applicationlogin page logo

Replace <your-realm> with the name of your realm. If your API is published under a prefix (the FerrisKey Helm chart serves it under /api by default), add that prefix to the API patterns. This list comes from the routes of FerrisKey 0.9.0: go over it again at every version upgrade, because a missing route gives a half-served login page, which is as good as none.

metadata:
annotations:
zero-trust.france-nuage.fr/sso: "true"
zero-trust.france-nuage.fr/sso-bypass-paths: >-
/realms/your-realm/protocol/openid-connect/*,/realms/your-realm/.well-known/*,/realms/your-realm/login-settings,/realms/your-realm/login-actions/*,/realms/your-realm/portal/active,/config,/realms/your-realm/authentication/*,/assets/*,/config.json,/logo_ferriskey.png

Three rules, and here they are not matters of convenience:

  • Count before you annotate. This path alone takes up the 10 patterns allowed per site. If the API and the web application share a host, the whole list counts against that one site, and there is no room left for any other path, for instance /realms/<your-realm>/broker/* if you federate an external identity provider. An eleventh pattern makes the annotation invalid, and the host stays in its previous state. Better to know it before than to find out from the rejection.
  • Exemption first, protection second. Check the list before you set sso, then set both annotations in the same change, never sso alone first. For an IAM, this order decides whether a mistake can be fixed or locks you out.
  • Test from an address with no special access. Open a private browsing window, on a network that benefits from no access exception, and go through a full login. Also check that one of your applications still gets its tokens. A test run from an already open session, or from a network allowed by default, passes for the wrong reasons and proves nothing.

The warning given for APIs holds here too: the edge serves an exempted path as is, so it is up to FerrisKey to reject what must be rejected. For an IAM, that is exactly its job, and it is what makes this exemption acceptable.

Who gets in​

Anyone with an account in your company's realm is added automatically to your organization, and to that one only, with the member role, on their first login. There is nothing for you to do. No user is created or invited on the edge, and whether a site is protected is decided by its Ingress annotation alone.

The edge therefore lets in any account of the realm. If your realm also holds accounts of customers or partners, only annotate an application that checks permissions itself, for instance by requiring an IAM role, as Paperclip does. Creating and removing the realm's accounts, like your application's access policy, remains your responsibility.

To give someone access, create their account in the IAM of their company, never in another company's.

Comparison​

CriterionBunker (managed FerrisKey)Okta / Auth0 / Entra ID (SaaS)Self-hosting
Identity directory hostingIn EuropeIn the USUp to you
Law governing the identitiesEU lawSubject to US lawUp to you
ProtocolOpenID Connect (Keycloak-compatible)Proprietary + standardsUp to you
ReversibilityOpen source (Apache-2.0), re-internalizableProprietary SaaSTotal
CostMonthly plan, users includedOften per active userOn you
Updates & availabilityManagedManagedOn you

Getting started​

  1. Receive your realm: Bunker provisions a dedicated realm on your FerrisKey server.
  2. Declare your applications: in the admin UI, create one OIDC client per application to connect (redirect URI, client type).
  3. Configure each application: point the application's OIDC configuration at your realm's discovery URL (above). Most frameworks only ask for the issuer URL, the client id and its secret.
  4. Create your users and groups, or connect an existing identity provider through brokering.

The First login tutorial walks through bringing up a first service on Bunker, and the Authentication page describes the IAM's role in the platform.

Use cases​

  • Unify access to your managed services: one login for your OIDC-connected tools (Grafana, Metabase, and any compatible software).
  • Partition several entities: one subsidiary, client or team per realm, isolated from one another.
  • Take back a directory subject to US law: migrate from Okta, Auth0 or Entra ID to an IAM hosted in Europe.

Current limitations​

FerrisKey is a young project, and the managed offer is deliberately transparent about its scope. At this stage:

  • OIDC only: FerrisKey supports OpenID Connect. SAML and LDAP are not supported. An application that can only authenticate via SAML, or a service that queries an LDAP directory directly, cannot go through FerrisKey yet.
  • Logout is per service: back-channel single logout is not yet propagated to all connected applications. In practice, logging out happens service by service today; a session open on another application may stay active until it expires.

These items are on the roadmap. If your need depends on them, flag it before you start: we'll tell you where support stands and scope the rollout with you.

Reversibility​

Everything is open source. You could run FerrisKey yourself: that is exactly what an Apache-2.0 licence allows. Bunker operates it for you (updates, availability, backups) without locking you in. Your realm configuration and your users export cleanly, and you keep the right to bring everything back onto your own hardware whenever you decide. You are not swapping a US lock-in for a European one.

References​


Okta is a trademark of Okta, Inc. Auth0 is a trademark of Okta, Inc. Microsoft Entra ID is a trademark of Microsoft Corporation. Keycloak is a trademark of Red Hat, Inc. Rust is a trademark of the Rust Foundation. Bunker is neither affiliated with nor endorsed by these companies; these names are used descriptively, to refer to the technologies deployed or compared.