-
-
Notifications
You must be signed in to change notification settings - Fork 204
Description
RFC: Self-Service Admin Portal
Phase: 3 — Enterprise SSO & Federation
Priority: P3 — Medium
Estimated Effort: High
Depends on: SAML (#512), SCIM (#513), Organizations (#511)
Problem Statement
Currently, all SSO and directory sync configuration requires either direct API calls or access to the main admin dashboard. Enterprise customers need their IT admins to self-configure SAML connections, SCIM provisioning, and org-level policies without requiring engineering support or access to the platform admin. WorkOS Admin Portal is a key differentiator that enables this self-service model.
Proposed Solution
1. Architecture
Embeddable/hosted portal — a separate React app (similar to web/app/ and web/dashboard/) accessible via time-limited, org-scoped access links.
Portal URL: /portal/:access_token — renders the admin portal app for the organization associated with the token.
2. Portal Access Token
Portal access is granted via time-limited tokens generated through the admin API:
type Mutation {
_generate_portal_link(
organization_id: ID!
expires_in: Int64 # seconds, default 3600, max 86400
return_url: String # URL to redirect after portal session ends
): PortalLink!
}
type PortalLink {
url: String! # e.g., "https://auth.example.com/portal/ptl_abc123..."
expires_at: Int64!
}Schema:
type PortalSession struct {
ID string `json:"id" gorm:"primaryKey;type:char(36)"`
Token string `json:"token" gorm:"type:varchar(256);uniqueIndex"`
OrganizationID string `json:"organization_id" gorm:"type:char(36)"`
CreatedBy string `json:"created_by" gorm:"type:char(36)"`
ReturnURL string `json:"return_url" gorm:"type:text"`
ExpiresAt int64 `json:"expires_at"`
CreatedAt int64 `json:"created_at" gorm:"autoCreateTime"`
}3. Portal Capabilities
The admin portal provides organization IT admins with:
| Section | Features |
|---|---|
| SSO Configuration | Configure SAML connection (upload IdP metadata or manual config), test SSO flow, view SP metadata, enable/disable SSO |
| Directory Sync | Enable SCIM provisioning, generate SCIM bearer token, view sync status, view provisioned users/groups |
| Domain Verification | Add/verify email domains via DNS TXT record, link domains to SSO |
| MFA Policy | Enable/disable MFA requirement for the organization, choose allowed MFA methods |
| Auth Methods | Enable/disable password, magic link, social login for the org |
| Audit Logs | View audit logs scoped to the organization (read-only) |
| Members | View organization members, roles, last login (read-only) |
4. Portal API (Backend)
New package: internal/http_handlers/portal.go
Portal endpoints are scoped by the portal session token — all operations limited to the token's organization:
GET /portal/api/organization → Get org details
GET /portal/api/saml → Get SAML connection config
POST /portal/api/saml → Create/update SAML connection
POST /portal/api/saml/test → Test SAML flow
GET /portal/api/scim → Get SCIM connection status
POST /portal/api/scim → Enable SCIM, generate token
GET /portal/api/domains → List verified domains
POST /portal/api/domains → Add domain for verification
POST /portal/api/domains/:id/verify → Verify domain (check DNS TXT)
GET /portal/api/audit-logs → Org-scoped audit logs
GET /portal/api/members → Org members
PUT /portal/api/settings → Update org auth settings
Middleware: Validate portal session token, extract org context, enforce read/write permissions.
5. White-Label Theming
Portal supports custom branding per organization:
// In Organization.Settings JSON:
type PortalTheme struct {
PrimaryColor string `json:"primary_color"` // hex color
LogoURL string `json:"logo_url"`
FaviconURL string `json:"favicon_url"`
CustomCSS string `json:"custom_css"` // sanitized CSS overrides
}The portal React app reads theme from the org settings and applies it.
6. Domain Verification
IT admins verify domain ownership via DNS TXT record:
1. Admin adds domain "company.com" in portal
2. System generates verification token: "authorizer-verify=abc123def456"
3. Admin adds TXT record to DNS: _authorizer.company.com TXT "authorizer-verify=abc123def456"
4. Admin clicks "Verify" → system performs DNS TXT lookup
5. If record matches → domain verified, linked to org
Verified domains enable:
- Auto-routing users with
@company.comto org SSO - Preventing other orgs from claiming the same domain
Frontend (web/portal/)
New React app at web/portal/:
- Built with the same stack as
web/dashboard/(React + Chakra UI + Vite) - Step-by-step wizards for SAML/SCIM configuration
- Real-time SSO test flow
- Responsive design for IT admin use
Testing Plan
- Integration tests for portal session token generation and validation
- Test portal API endpoints are scoped to correct organization
- Test expired portal session rejection
- Test SAML configuration via portal
- Test domain verification DNS lookup
- E2E tests for portal UI flows