Skip to content

SSO/SAML Integration for Knowledge Service #165

@rucka

Description

@rucka

Story Statement

As an enterprise admin
I want SSO/SAML integration for the knowledge service
So that users can authenticate using our corporate identity system without managing separate credentials

Where: Knowledge service — authentication layer + admin SSO configuration UI

Epic Context

Parent Epic: Platform Hardening & Enterprise Readiness #68
Status: Refined
Priority: P0 (Must-Have)

Status Workflow

  • Refined: Story is detailed, estimated, and ready for development
  • In Progress: Story is actively being developed
  • Done: Story delivered and accepted

Acceptance Criteria

Functional Requirements

  1. Given an enterprise admin has configured SSO for org "acme" with Okta SAML
    When a user navigates to the web dashboard login page
    Then they see a "Sign in with SSO" button alongside the API key login; clicking it redirects to Okta IdP login page

  2. Given a user completes Okta SAML authentication successfully
    When the IdP sends the SAML assertion to the service's ACS endpoint
    Then the service validates the assertion, creates or updates the user via JIT provisioning (email, name, org membership from assertion), creates a session, and redirects to dashboard

  3. Given an enterprise admin configures SSO
    When they access the SSO settings page
    Then they can: upload IdP metadata XML (or provide IdP SSO URL + certificate), configure attribute mapping (email → user.email, role → user.role), download SP metadata XML, test the SSO connection

  4. Given SSO is configured for org "acme"
    When an SSO-authenticated user's IdP session expires or they are removed from the IdP
    Then their next request to the service triggers re-authentication; if IdP rejects, session is invalidated and user is logged out

  5. Given OIDC is configured instead of SAML
    When a user clicks "Sign in with SSO"
    Then the service uses OIDC Authorization Code flow, validates the ID token, and applies the same JIT provisioning logic

  6. Given SSO is NOT configured for an org
    When users access the org
    Then API key authentication remains the only method (SSO is opt-in per org)

Business Rules

  • SSO is opt-in per organization (API key auth always available as fallback)
  • Protocols: SAML 2.0 (SP-initiated) + OIDC Authorization Code flow
  • JIT provisioning: user created on first SSO login with attributes from IdP assertion
  • Attribute mapping: configurable (IdP attribute → service field: email, name, role)
  • Default role for JIT-provisioned users: "member" (admin must promote manually)
  • Session duration: 8 hours (configurable per org)
  • SSO applies to web dashboard only — CLI continues to use API keys
  • SP metadata: auto-generated and downloadable for IdP configuration

Edge Cases and Error Handling

  • Invalid SAML assertion (expired, wrong audience, bad signature): Redirect to error page "SSO authentication failed: [specific reason]"
  • IdP unreachable: Fall back to API key login with message "SSO provider unreachable. Use API key to log in."
  • Attribute mapping mismatch (required field missing from assertion): Redirect to error page "SSO configuration error: email attribute not found in assertion"
  • User exists from API key but now using SSO: Link accounts by email; merge access
  • Multiple IdPs per org: Not supported in v1 — one IdP per org

Definition of Done Checklist

Development Completion

  • All 6 acceptance criteria implemented and verified
  • SAML 2.0 SP implementation (ACS endpoint, metadata, assertion validation)
  • OIDC RP implementation (authorization code flow, token validation)
  • SSO configuration admin UI (IdP metadata, attribute mapping, SP metadata download, connection test)
  • JIT user provisioning from IdP assertions
  • Session management (creation, expiration, invalidation)
  • Unit tests for assertion validation, attribute mapping, JIT provisioning
  • Integration tests with mock IdP (SAML + OIDC)

Quality Assurance

  • Tested with Okta (SAML) and Google Workspace (OIDC) dev instances
  • Invalid/expired assertions correctly rejected
  • Session invalidation on IdP logout works
  • Fallback to API key when SSO unreachable

Deployment and Release

  • SSO configuration documentation for enterprise admins
  • SP metadata endpoint documented
  • Supported IdPs listed in documentation

Story Sizing and Sprint Readiness

Refined Story Points

Final Story Points: XL(12)
Confidence Level: Low
Sizing Justification: Two protocols (SAML + OIDC), IdP configuration UI, JIT provisioning, session management, attribute mapping. Most complex story across all three epics. Enterprise IdPs have many edge cases.

Sprint Capacity Validation

Sprint Fit Assessment: Does NOT fit in single sprint
Total Effort Assessment: Requires splitting

Story Splitting Recommendations

  1. SSO/SAML Integration for Knowledge Service #165-A: SAML SP + SSO config admin page + JIT provisioning (XL(8))
  2. SSO/SAML Integration for Knowledge Service #165-B: OIDC RP + session management + connection testing (L(5))

Dependencies and Coordination

Story Dependencies

Prerequisite Stories: Epic #66 #151 (Auth foundation), #153 (Web Interface — SSO login page)
Dependent Stories: None

External Dependencies

Infrastructure Requirements: IdP test instances (Okta dev, Google Workspace)
Third-party Integrations: SAML library (passport-saml or saml2-js), OIDC library (openid-client)

Validation and Testing Strategy

Acceptance Testing Approach

Testing Methods: Integration tests with mock IdP (samlify or keycloak test container); unit tests for assertion validation, attribute mapping; manual testing with Okta dev account
Test Data Requirements: SAML assertions (valid, expired, wrong audience), OIDC tokens (valid, expired)
Environment Requirements: Mock IdP container (Keycloak), Okta dev account

Notes

Refinement Insights: Split into two stories is strongly recommended. SAML first (most enterprise demand), OIDC second. Consider Keycloak test container for automated testing.

Technical Analysis

Implementation Approach

Technical Strategy: SAML: use @node-saml/passport-saml for SP implementation. OIDC: use openid-client for RP. Both share JIT provisioning logic. Session: express-session with PostgreSQL store. SSO config stored in org settings (IdP metadata, attribute mapping).
Key Components: SAML SP middleware, OIDC RP middleware, JIT provisioner, session manager, SSO config admin API + UI
Data Flow: SSO login → redirect to IdP → IdP authenticates → callback with assertion/token → validate → JIT provision → create session → redirect to dashboard

Technical Requirements

  • SAML: ACS endpoint at /auth/saml/callback, SP metadata at /auth/saml/metadata
  • OIDC: callback at /auth/oidc/callback, redirect to IdP authorization endpoint
  • DB: sso_configs(org_id UUID FK UNIQUE, protocol ENUM('saml','oidc'), idp_metadata TEXT, attribute_mapping JSONB, enabled BOOLEAN, created_at TIMESTAMPTZ)
  • DB: users(id UUID PK, org_id UUID FK, email VARCHAR UNIQUE(org_id), name VARCHAR, role ENUM('admin','member'), source ENUM('api_key','sso'), idp_subject VARCHAR, created_at TIMESTAMPTZ, last_login_at TIMESTAMPTZ)
  • Session: express-session with connect-pg-simple for PostgreSQL session store (8h max age)

Technical Risks and Mitigation

Risk Impact Probability Mitigation Strategy
SAML assertion edge cases across IdPs High Medium Test with 3+ IdPs; use well-maintained library; comprehensive assertion validation
Session management complexity (SSO + API key coexistence) Medium Medium Clear separation: SSO sessions for web, API keys for API/CLI
IdP clock skew causes assertion validation failures Medium Low Allow configurable clock skew tolerance (default 5 min)

Spike Requirements

Required Spikes: Set up Keycloak test container for automated SAML/OIDC testing in CI

Metadata

Metadata

Assignees

No one assigned

    Labels

    user storyWork item representing a user story

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions