makallio85 / cakephp-sso
CakePHP 5 plugin that signs users in through the central Rock Software identity provider (OpenID Connect).
Package info
github.com/makallio85/cakephp-sso
Type:cakephp-plugin
pkg:composer/makallio85/cakephp-sso
Requires
- php: >=8.3
- cakephp/authentication: ^3.2
- cakephp/cakephp: ^5.1
- cakephp/migrations: ^4.0 || ^5.0
- firebase/php-jwt: ^6.10 || ^7.0
Requires (Dev)
- cakephp/cakephp-codesniffer: ^5.0
- phpunit/phpunit: ^11.5 || ^12.0 || ^13.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-10-03 13:39:04 UTC
README
CakePHP 5 plugin that signs users in through the central Rock Software identity
provider (id.rocksoftware.fi, Authentik) with OpenID Connect. Each application keeps
its users table as the anchor for its foreign keys; the plugin creates and refreshes
those rows from the provider, so no application manages people itself.
Design: makallio85/rocksoftware-identity#5.
What it does
| Route | Purpose |
|---|---|
GET /sso/login?redirect=/path |
Starts the authorization code flow with PKCE |
GET /sso/callback |
Redirect URI registered at the provider |
GET|POST /sso/logout |
Signs out here and at the provider |
POST /sso/backchannel-logout |
Back-channel logout URI registered at the provider |
GET|POST /sso/emergency/{token} |
Single-use sign-in from bin/cake sso emergency_login |
- ID and logout tokens are verified against the provider's JWKS with
firebase/php-jwt; only asymmetric algorithms are accepted. Issuer, audience, nonce, state and PKCE are checked by the plugin. - A user row is matched on
external_id, then linked on a verified email address (how existing local accounts move over), else created. Email, name and the active flag are rewritten on every sign-in. - A required provider group (
sso_settings.required_group) gates access. - Back-channel logout moves the configured
sessionsValidFromFieldforward, which ends every session the user had. - The connection lives in
sso_settings; the client secret is encrypted with a key derived fromSecurity.salt.
Authorization stays in the application. The plugin only establishes who the user is.
Installing in an application
-
Composer. Published on Packagist:
composer require makallio85/cakephp-sso:^1.0
Releases are tags on
master(semantic versioning). -
Plugin.
$this->addPlugin(\Sso\SsoPlugin::class);inApplication::bootstrap(). -
Migrations. Run the plugin's before the application's:
bin/cake migrations migrate -p Sso. The application then adds to its users table:Column Type external_idvarchar(64), unique, nullableidentity_source_idFK → identity_source_types.id(local/sso)synced_atdatetime, nullable and makes
passwordnullable, since provider-backed rows have none. -
CSRF. Exempt the back-channel logout, which is a signed server-to-server POST:
$csrf->skipCheckCallback(fn($request) => \Sso\SsoPlugin::isCsrfExempt($request));
-
Configuration (
config/app.php, application shape only — no secrets):'Sso' => [ 'userModel' => 'Users', 'loginUrl' => '/users/login', 'loginRedirect' => '/', 'layout' => 'auth', 'sessionsValidFromField' => 'sessions_valid_from', 'createUsers' => true, ],
-
Events. Listen where the application keeps its own side effects:
Event Data Typical use Sso.beforeUserSaveuser,claims,isNewFill columns the plugin does not know Sso.afterLoginuser,claims,methodLast login, audit log, session freshness Sso.beforeLogoutuserAudit log Sso.backchannelLogoutuserAudit log -
Own second factor. An application with one skips it when
\Sso\Session\SsoSession::isSsoSession($session)is true: the provider already required a second factor. -
Sign-in button. Link to
/sso/loginfrom the login page.
Connecting to the provider
Each application is an OAuth2/OpenID provider plus an application in Authentik, defined
as a blueprint in rocksoftware-identity. Then, in the application container:
bin/cake sso configure \
--issuer https://id.rocksoftware.fi/application/o/<slug>/ \
--client-id <client id> \
--required-group <app>-staff \
--enable
# the client secret is asked for interactively
Emergency sign-in
When the provider is unavailable, someone with a shell in the application container runs:
bin/cake sso emergency_login person@example.com --minutes 15
and opens the printed link. It works once, expires, and is logged.
Development
composer install vendor/bin/phpunit composer cs-check
Tests use SQLite and a fake provider (tests/TestCase/FakeProvider.php) served through
CakePHP's HTTP client mocks, so no live provider is needed.