Project Lead The Way (PLTW) is a nonprofit that provides STEM curriculum to K-12 schools across the United States. PLTW instructors are a significant source of leads for SolidProfessor's education business. Here is how the pipeline works today:
legacy-app/).
The PLTW login is a custom OAuth 2.0 integration (not SAML), using PLTW's Okta instance
(pltw-ext.okta.com) with a shared client_id/secret for all of SolidProfessor. The legacy backend
(OauthPLTW.php, OauthClientController.php) handles the full flow including
auto-provisioning PLTW users with a 1-year plan. However, this integration was never fully ported
to Platform 2.0 — the Platform 2.0 codebase (platform-frontend + platform-backend)
contains partially implemented dead code. See Page 3 for the full gap analysis.
Platform 2.0 (the Nuxt 2 / Vue 2 frontend) has a modern SAML SSO implementation for enterprise accounts. Here's how it currently works and where the gaps are for PLTW:
SAML is fully supported for company and school accounts only. An admin configures SAML via Account → SAML Configuration → Email Domains in platform-admin. When a user logs in, their email domain is detected, they're routed to their organization's Identity Provider, and upon successful authentication they are auto-provisioned into the company/school account.
Individual accounts support email/password or social login (Google, LinkedIn). There is no SAML support for individual accounts — the platform-admin UI explicitly filters out SAML onboarding strategies for individual account types.
While PLTW OAuth was fully working in the legacy application (legacy-app/
with hardcoded credentials in OauthPLTW.php), the integration was only partially
ported to Platform 2.0. Class files exist in platform-backend
(PltwServiceProvider.php, OAuthProvider.php enum), but the integration
was never fully wired up:
LoginForm.vue's socialMediaButtons array only includes Google, LinkedIn, and SAML.
CSS and logo assets exist in SocialLoginButton.vue but are unreachable.EventServiceProvider.php only registers Cognito; no PLTW handler is wired.config/urls.php has no
urls.pltw.* entries.config/services.php has no
PLTW client_id or client_secret. (The legacy app had these hardcoded in OauthPLTW.php.)| Capability | Platform 2.0 Status |
|---|---|
| SAML SSO for school/company accounts | Supported |
| SAML SSO for individual accounts | Not supported |
| PLTW OAuth login | Dead code — partially implemented, non-functional |
| Individual → EDU account conversion | No tooling exists |
| Lead source tracking (PLTW tag) | Needs Salesforce alignment |
Create a single academic account for PLTW in platform-admin and configure SAML SSO against PLTW's Okta instance. All PLTW instructors would land in this shared "umbrella" account as Learners. When sales converts an instructor, they manually move the user to the instructor's own school EDU account.
No code changes required — this is purely configuration:
PLTW OAuth was fully working in the legacy application but was only partially ported to Platform 2.0
(see Page 3). This option completes that port — wiring up the platform-backend
Socialite driver, adding configuration and credentials, and adding the "Login with PLTW" button to
platform-frontend. Individual accounts are created exactly as the legacy flow works today.
EventServiceProvider.php —
create a PltwExtendSocialite event handler (currently only Cognito is registered).
config/urls.php —
add urls.pltw.authorize, urls.pltw.token, and urls.pltw.userinfo entries.
config/services.php —
wire client_id and client_secret from environment variables.
socialMediaButtons array in LoginForm.vue
to render the "Login with PLTW" button on the Platform 2.0 login page.
platform-backend Socialite driver must be registered,
OAuth endpoints and credentials must be configured, and the platform-frontend button must be added.
Effort is Medium, not minimal.
PltwServiceProvider.php (OAuth provider class),
OAuthProvider.php (enum registration),
EventServiceProvider.php (Socialite driver registration — missing PLTW),
config/urls.php (endpoint URLs — no PLTW entries),
config/services.php (credentials — no PLTW entries),
LoginForm.vue (socialMediaButtons array — no PLTW),
AuthenticationController.php (login flow),
SocialLoginButton.vue (platform-frontend button/CSS for reference).
Extend the platform to allow individual accounts to have SAML configurations. Today, SAML is only available for company and school accounts because the admin UI and backend logic explicitly filter it out for individual account types. This option removes those restrictions and creates a new provisioning path for individual SAML users.
filteredOnboardingStrategies filter
in AccountForm.vue (line ~607-615) that blocks SAML strategies for individual accounts.
AuthenticationController SAML callback to handle
individual accounts — skip the ProvisionUserToCompany step and create an
individual account instead.
SamlEmailValidation rule to not require a Company.
Allow AccountDomain records without a Company association.
ProvisionUserToCompany which auto-assigns the user
to a company/school. For individual SAML, we'd need a new path:
SAML assertion → validate → create individual account → session. This is a
meaningful change to the authentication architecture.
Combine the best of both worlds: keep PLTW OAuth for the initial individual signup (preserving the lead-gen funnel), and when sales converts an instructor to EDU, set up SAML SSO on the school account. Build an "account conversion" tool in platform-admin to streamline the Individual → EDU transition that sales performs today manually.
Same as Option B: complete the PLTW OAuth integration (backend wiring + frontend button).
Build a tool in platform-admin for the sales-to-EDU workflow:
Ensure full visibility for the sales pipeline:
| Criteria | Option A Umbrella Account |
Option B Keep OAuth |
Option C Individual SAML |
Option D Hybrid |
|---|---|---|---|---|
| Engineering Effort | Low | Medium | Med-High | High (phased) |
| Preserves Lead Funnel | Partially | Yes | Yes | Yes |
| Individual Experience | No | Yes | Yes | Yes |
| Conversion Tooling | No | No | No | Yes |
| Code Changes | None | Moderate | Significant | Phased |
| Future-Proof | Limited | Limited | Yes | Yes |
| Time to First Value | Immediate | 2–3 weeks | 4–6 weeks | 2–3 weeks* |
* Option D Phase 1 delivers the same value as Option B in 2–3 weeks. Full value (conversion tool) takes longer.
PltwServiceProvider.php,
OAuthProvider.php,
EventServiceProvider.php (Socialite registration),
config/urls.php (endpoint config),
config/services.php (credentials config),
LoginForm.vue (socialMediaButtons array),
AuthenticationController.php,
AccountSamlConfiguration.php,
SamlEmailValidation.php,
AccountForm.vue:607,
SocialLoginButton.vue