Features Apograph CMS on GitHub

The scripted provider

Identity plugin @apograph/identity-server@apograph/identity-admin

Driving the whole SSO handshake with no identity provider to hand.

Documents 0.5.2 Updated Edit this page Report a problem

On this page

A scripted identity provider: no network, no tenant, no clock skew, the same answer every run.

Shipped, not test scaffolding

It stands on the same footing as the copilot’s scripted backend. It is how the server’s end-to-end suite drives the entire SSO redirect handshake in CI, and how a contributor exercises the sign-in page with no identity provider to hand.

A deployment that registers it gets a working SSO button that signs in whoever the composition root scripted.

It is installed in every generated app, and registered in none

create-apograph-app ships it unconditionally, like the copilot’s. Installing an adapter does nothing on its own — an adapter only matters once the composition root names it, and the template names none.

It really verifies

The temptation with a fake is a stub that always says yes. That would make the conformance kit vacuous on the one adapter that runs in every CI job, so this one does the real shape of the work:

  • authorize scripts a response and signs it;
  • complete re-derives that signature, checks state, checks that the echoed nonce is the one the core stored, and decodes the subject.

Each check raises its own verification error, so the kit’s rejection scenarios exercise distinct code paths rather than one shared throw.

The signature covers code and state, never the nonce

That is what lets a replayed-nonce scenario be told apart from a tampered one: change the nonce and the signature still verifies, so the refusal comes from the nonce check that is actually under test.

It also puts the PKCE challenge in the authorization URL and never the verifier — the conformance kit checks exactly that, so including the challenge is what makes the check meaningful.

Driving it

import { createFakeSsoProvider } from '@apograph/identity-provider-fake';

const idp = createFakeSsoProvider({
    users: [
        { subject: 'idp-ada', email: 'ada@example.com', name: 'Ada' },
        { subject: 'idp-grace', email: 'grace@example.com', emailVerified: false }
    ]
});

idp.signInAs('idp-grace'); // who the NEXT authorize hands back

Scripting an unverified address is how you exercise the rule that gates account linking: a first sign-in may claim an existing account only when the provider asserts the email is verified. See what a sign-in may do.