Craft CMS has no built-in SAML or OpenID Connect sign-in for the control panel. Keyway SSO adds it: it signs people in with your own identity provider, maps the attributes and groups it receives onto Craft users and user groups, and records every attempt on a diagnostics screen inside the control panel.
These pages are written for the person who has the Craft site on one screen and the identity provider's admin console on the other. Everything here is taken from the plugin's own code and from its settings screen, so the field names quoted are the ones you will actually see.
email, username, firstName, lastName,
fullName or field:<handle>; provider groups onto Craft group
handles by exact, prefix or suffix match.| What | Version |
|---|---|
| PHP | 8.2 or newer |
| Craft CMS | 5.0 or newer |
| PHP extensions | dom, mbstring, openssl, zlib |
zlib is not optional and is declared as a requirement, so Composer refuses to
install the plugin without it: the SAML authentication request is DEFLATE-encoded before it is
sent, and the SAML logout messages are encoded and read back the same way.
Not published yet. Keyway SSO is in final testing and is not yet in the Craft Plugin Store or on Packagist, so the commands below do not resolve today. They are here so you can see what installation will look like; this page will be updated when the plugin is listed.
From the project root of your Craft site:
composer require aphexcoding/keyway-ssophp craft plugin/install keyway-ssoThe plugin handle is keyway-sso. Installing it creates two tables: the one behind
the diagnostics screen, and the record of which accounts single sign-on created — without which a
just-in-time account is refused on its second login. Installing through
Settings → Plugins in the control panel runs the same migration.
After any later update, run php craft up. It is not optional
housekeeping: a site that already had the plugin installed gets new tables only that way, and
the one added in schema version 1.1.0 is the one that keeps people signing in.
Then open Settings → Plugins → Keyway SSO and follow the guide for your
provider. Until you choose a protocol there, the login screen looks exactly as it did before the
plugin was installed — Protocol starts at
Disabled (password login only).
The plugin answers on five addresses. Each one exists twice: as an action URL
and as a control-panel alias (sso/start, sso/acs,
sso/callback, sso/metadata, sso/slo).
Give the identity provider the action URL and nothing else. The
control-panel alias contains this site's cpTrigger (the admin part of
the URL), which the site owner can rename at any time, and a renamed address is a configuration
that quietly stops working.
| Address | What it does | Who needs it |
|---|---|---|
<BASE>/actions/keyway-sso/sso/start | Begins a login: issues the single-use login state and the browser-binding cookie, then redirects to your provider. | Nobody. The SSO button on the login screen links to the control-panel alias. |
<BASE>/actions/keyway-sso/sso/acs | SAML assertion consumer service: receives the provider's HTTP-POST assertion. | Your provider (SAML), as the ACS / Single sign-on URL. |
<BASE>/actions/keyway-sso/sso/callback | OIDC redirect URI: receives the authorization code. | Your provider (OIDC), as the redirect URI. |
<BASE>/actions/keyway-sso/sso/metadata | Serves this site's SAML service-provider metadata document. Public and unauthenticated, because several providers fetch it themselves. | Your provider (SAML), optionally — it is also the file behind Download metadata. |
<BASE>/actions/keyway-sso/sso/slo | Receives the provider's SAML LogoutRequest on the HTTP-Redirect binding and ends the matching Craft session. Refuses every message until both the provider's logout URL and an SP private key are set, and until then the metadata document advertises no SingleLogoutService. | Your provider (SAML), only if you opt into Single Logout — which is SAML only and one way (signing out of Craft ends nothing at the provider), and which Okta will not trigger after an ordinary Okta sign-out. |
Do not type these by hand. The settings screen shows the exact addresses this installation answers on, as copy fields (ACS URL this site answers on, Redirect URI this site answers on, Metadata URL, SP single logout URL). For the two you have to repeat in a field of your own — ACS URL and Redirect URI — the screen also compares what you pasted with the address this site really answers on and comments underneath the field. Both protocols compare those values character for character, and a one-character difference fails the login with a message that reads like a certificate problem.
Two things worth knowing before they surprise you. On an installation with Craft's default
omitScriptNameInUrls = false the addresses come out as
<BASE>/index.php?p=actions/keyway-sso/sso/acs; that routes correctly and is
fine for SAML, but some providers refuse a redirect URI carrying a query string, so such a site
needs omitScriptNameInUrls turned on before OpenID Connect can be registered. And
the metadata address answers 404 whenever Protocol is not
SAML 2.0, or SP entity ID or ACS URL is empty or
malformed — deliberately, because a metadata document naming a blank entity ID would configure
your provider against a login that can never validate.
The sixth address is not one you give away: the diagnostics screen is a
control-panel page (<cp>/sso/diagnostics), reachable from the
Open sign-in diagnostics button at the bottom of the settings screen. The plugin
adds no navigation item, so that button is the way in.
Any SAML 2.0 or OpenID Connect provider works the same way — the guides differ only in where each value is found in the provider's console. What differs is how much of it we have run ourselves, so here it is without varnish:
| Provider | Protocols covered by the guide | Verification status |
|---|---|---|
| Keycloak | SAML 2.0 and OpenID Connect | SAML verified end to end on 17 September 2026 against a live Keycloak 26.0 realm and a live Craft install: sign-in, attribute and group mapping, account creation, and IdP-initiated Single Logout — which is SAML only and one-way (IdP → Craft; signing out of Craft ends nothing at the provider), opt-in (it needs the provider's logout URL and an SP private key before it does anything), and will not work with Okta, which does not send such a request after an ordinary Okta sign-out. OpenID Connect has not been run end to end; for it a smoke check reads a real realm's discovery document and JWKS and verifies a real id token's key selection and signature — but not the HTTPS transport and not the full id-token reader. |
| Okta | SAML 2.0 | SAML verified end to end on 17 September 2026 against a live Okta tenant (Integrator Free Plan) and a fresh Craft 5.11 install on default settings: first sign-in created the account just in time with the mapped group, and the second sign-in updated it and reached the control panel. Single Logout will not work with Okta — by Okta's own documentation (read 17 September 2026) Okta will not send a logout request to the application after an ordinary Okta sign-out; that half was not exercised on the live tenant. OIDC with Okta has not been checked. |
| Microsoft Entra ID | OpenID Connect | Guide provided, not yet verified against a live tenant. |
Exactly two settings accept an environment-variable reference — SP private key
(SAML) and Client secret (OpenID Connect). Write them as
$KEYWAY_SP_KEY / $KEYWAY_OIDC_SECRET and put the value in the server's
environment; Craft resolves the reference on read, so the secret stays out of project config and
out of version control. Every other field is stored as typed — writing
$SOMETHING into SP entity ID or ACS URL puts that
literal string into the metadata document and the comparison, and the login fails.
If one of the two supported fields points at a variable that is not set, the plugin fails closed: single sign-on stays off, the settings screen names the missing variable at the top of the page, and the field itself carries an error.
SAML 2.0 and OpenID Connect sign-in for the Craft control panel: attribute and group mapping, just-in-time accounts, an admin password fallback with a guard that switches admin password login back on, with a warning, if your settings would otherwise leave nobody able to sign in, and a diagnostics screen that tells you why a login was refused. The plugin is in final testing and is on its way to the Craft Plugin Store.