integrate-identity-providers
Skill1 starsChanged 5 months agoMITView on GitHub
Use when adding third-party login or identity verification to a backend — social login (Sign in with Google / Apple / Facebook) and national digital identity / KYC (e.g. Singpass) via the OIDC relying-party flow (authorization code + PKCE + state/nonce → token exchange), validating the resulting token (.well-known → JWKS signature + iss/aud/exp, or introspection), centralizing many IdPs behind one identity broker (e.g. Keycloak), mapping an external identity to your user by (provider, subject), and treating verified attributes as KYC-grade. Framework-flexible. The frontend login UI is in secure-a-frontend-app.
In this repository40 other files it gives its agents.
- authoring-project-skillsSkill
- background-jobs-and-cachingSkill
- code-conventionsSkill
- containerize-and-ship-a-serviceSkill
- database-migrationsSkill
- design-an-error-modelSkill
- git-flowSkill
- handle-files-frontendSkill
- import-data-from-csvSkill
- integrate-external-servicesSkill
- integrate-internal-servicesSkill
- keep-service-memory-leanSkill
- operate-ecs-services-safelySkill
- prevent-secret-and-pii-leaksSkill
- release-safetySkill
- render-transactional-emailsSkill
- rules-backendSkill
- rules-code-styleSkill
- rules-debuggingSkill
- rules-gitSkill
- rules-infraSkill
- rules-pr-reviewSkill
- rules-shippingSkill
- rules-workflowSkill
- schedule-effective-dated-changesSkill
- secure-a-frontend-appSkill
- security-auditSkill
- send-slackSkill
- serve-realtime-with-websocketsSkill
- structure-a-backend-serviceSkill
- structure-a-frontend-appSkill
- structure-a-shared-backend-libSkill
- structure-a-shared-ui-libSkill
- tdd-http-firstSkill
- use-feature-flagsSkill
- write-cross-cutting-codeSkill
- write-frontend-codeSkill
- write-frontend-testsSkill
- write-service-codeSkill
- write-unit-testsSkill
The file
We split this skill into the rules it gives an agent
1 rule. About 0 are common, 0 are distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈0
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 95
Every token is signature-verified against JWKS with iss/aud/exp (or introspected).
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Integrate identity providers
Adding external login (Google/Apple/Facebook) and identity verification / KYC (e.g. Singpass)
to a backend, the right way: as an OIDC relying party that delegates auth to the provider and
verifies the result cryptographically. Examples name real public providers; the flow is a standard
so it ports to any language. principle → ▸ Example → ▸ Other stacks. The frontend login UI +
session (NextAuth, route guards) is secure-a-frontend-app; exposing your own API to partners is
integrate-external-services §5. This skill is the backend/server + verification side.
Core principle
Never roll your own identity or trust a client-supplied identity blob. Delegate authentication to an OIDC provider, verify the returned token's signature + claims yourself, then map the external identity to your own user. For a KYC provider (Singpass), the returned attributes are authoritative — store them as verified, don't let the user edit them.
1. The relying-party flow (authorization code + PKCE)
- Redirect the user to the provider's
authorizeendpoint withstate(CSRF) +nonce(replay) + PKCEcode_challenge; keepstate/code_verifierserver-side (or in a signed cookie). On the callback, checkstate, then exchange thecodeat thetokenendpoint for anid_token+access_token. Confidential clients authenticate the exchange with a client secret or a signedclient_assertionJWT (private-key JWT) — never expose the secret to the browser.GET /authorize?response_type=code&client_id=…&redirect_uri=…&scope=openid profile&state=…&nonce=…&code_challenge=…&code_challenge_method=S256 → callback ?code=…&state=… → POST /token { code, code_verifier, client_assertion } → { id_token, access_token } - Then fetch verified attributes (the
userinfoendpoint, or a provider-specific person API) using the access token. The user never hands you their identity — the provider asserts it. ▸ Other stacks: any OIDC/OAuth2 client lib (AppAuth, MSAL, passport-openidconnect,golang.org/x/oauth2). Principle: authorization-code + PKCE, validatestate, exchange server-side, fetch attributes — never implicit/client-asserted identity.
2. Validate the token (what every service does)
- Discover, then verify. Fetch the provider's
/.well-known/openid-configurationonce (cache it) to getjwks_uri+ endpoints; verify theid_token/JWT signature against the JWKS and checkiss,aud,exp, andnonce. For opaque access tokens, introspect at the provider instead. Cache the JWKS (refresh on unknownkid); never skip signature verification.const { jwks_uri, issuer } = await discover(idpBaseUrl); // .well-known, cached const claims = await verifyJwt(idToken, { jwks: jwks_uri, issuer, audience: clientId }); // sig + iss + aud + exp
▸ Other stacks: the same — discovery doc → JWKS → verify signature + standard claims, or token
introspection for opaque tokens. (You already saw the validate side in
integrate-external-services §5.)
3. Centralize many IdPs behind one broker
- Don't make every service implement Google + Apple + Singpass. Front them with one identity broker (e.g. Keycloak) that brokers each upstream IdP and issues your own uniform token; your services then validate just that one issuer (§2). Adding an IdP becomes a broker config change, not a fleet-wide code change. ▸ Other stacks: Auth0/Cognito/Okta/Keycloak as an identity broker; an internal auth service that normalizes providers. Principle: one issuer your services trust, many upstream IdPs behind it.
4. Map an external identity to your user
- Link by a stable
(provider, subject)pair, not by email alone — emails change and can be reused; the provider'ssubis stable. Store which IdP verified the user; on first login, provision the user (and link additional providers to the same account deliberately).const identity = { provider: 'singpass', sub: claims.sub }; // stable key let user = await users.findByIdentity(identity) ?? await users.provisionFrom(identity, claims);
▸ Other stacks: an identities table keyed by (provider, subject) linked to one user. Principle:
stable subject is the key; email is a (mutable) attribute.
5. Identity verification (KYC) vs login
- A national digital identity (Singpass) returns verified attributes (legal name, national id,
DOB). Treat them as authoritative: store a
verifiedflag + the source + a timestamp, don't let the user edit verified fields, and re-verify on the schedule your compliance requires. This is stronger than social login (which only proves "controls this Google account"). Distinguish the two in your model — a "logged in via Google" user is not "identity-verified". ▸ Other stacks: any eID / KYC provider returns asserted attributes; record provenance + verified-at, gate sensitive actions on verification level.
Security checklist
state+nonce+ PKCE on every flow; reject a callback whosestatedoesn't match.- Verify signature +
iss/aud/expon every token; cache JWKS; introspect opaque tokens. - Confidential-client secret/private key in a vault, never in the client or the repo.
- Never log tokens or PII (id numbers) — mask (see
write-service-code§7). Short-lived access tokens + refresh handling; store only what you need.
Vendor recipes (step-by-step)
Step-by-step guides for specific providers live in references/ and load on demand.
references/keycloak.md— Keycloak as token authority + identity broker: discovery, JWKS verify, client-credentials (latency-safe TTL), brokering Google/Apple/Singpass.references/singpass.md— Singpass (NDI OIDC) relying-party: private-key-JWT client assertion, JWE-encrypted ID token (decrypt → verify), hosted JWKS, verified Myinfo (KYC) attributes.- (more per provider — social login, …)
Verification
- Login uses authorization-code + PKCE, validates
state, exchanges server-side — no implicit flow. - Every token is signature-verified against JWKS with
iss/aud/exp(or introspected); JWKS cached. - Many IdPs sit behind one broker/issuer your services validate.
- Users are linked by
(provider, subject), not email; the verifying IdP is recorded. - KYC attributes are stored verified + provenance + timestamp, not user-editable; verification level is distinct from "logged in".
Related
secure-a-frontend-app— the frontend login UI, NextAuth, session, route guards (the client side of this).integrate-external-services§5 (token introspection / partner edge), §2 (resilient HTTP to the IdP).write-cross-cutting-code(the guard that reads the verified identity) ·design-an-error-model·write-service-code§7 (mask PII).
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

