Skip to content

Suvaidyam/frappe_saml_auth

Repository files navigation

Frappe SAML

Enterprise-grade SAML 2.0 authentication app for Frappe where Frappe acts as the Service Provider (SP) and an external IdP (Azure AD, Keycloak, bank IdP, etc.) handles identity.

This app is designed to be:

  • Reusable across projects
  • Secure by default
  • Safe for bench updates (no Frappe core changes)
  • Docker-friendly

Features

  • SAML endpoints:
    • /saml/login (SP-initiated login)
    • /saml/acs (Assertion Consumer Service)
    • /saml/metadata (dynamic SP metadata)
    • /saml/logout (local logout)
  • Strict OneLogin python-saml validation
  • HTTPS enforcement for ACS
  • Signed assertion/message requirements
  • Replay attack prevention (assertion ID cache)
  • Optional SAML-only mode to block password login
  • Automatic user provisioning and role assignment
  • Safe audit logging (no raw assertions in logs)

Package Layout

frappe_saml/
├── frappe_saml/
│   ├── __init__.py
│   ├── hooks.py
│   ├── saml/
│   │   ├── settings.py
│   │   ├── auth.py
│   │   ├── validation.py
│   │   ├── user_provision.py
│   │   ├── roles.py
│   │   └── audit.py
│   ├── doctype/
│   │   └── saml_settings/
│   │       ├── saml_settings.json
│   │       ├── saml_settings.py
│   │       └── saml_settings.js
├── www/
│   └── saml/
│       ├── login.py
│       ├── acs.py
│       ├── metadata.py
│       └── logout.py

Prerequisites

  • Frappe/ERPNext bench environment
  • Python 3.10+
  • HTTPS-enabled reverse proxy (Nginx/Traefik/Ingress)
  • IdP metadata XML (or XML string source)

Installation

1) Get app code into bench

If your bench apps folder is mounted, clone/copy this app in the bench apps directory.

2) Install dependencies

pip install python3-saml

If your deployment pins requirements per app, add python3-saml to the app requirements file used by your CI/CD image.

3) Install app on site

bench --site <your-site> install-app frappe_saml

4) Restart bench services

bench restart

Configuration

Configuration sources (merged):

  1. site_config.json (primary)
  2. Optional SAML Settings Single DocType

Minimal site_config.json example

{
  "saml": {
    "enabled": true,
    "entity_id": "https://frappe.example.com",
    "acs_url": "https://frappe.example.com/saml/acs",
    "idp_metadata_xml": "<EntityDescriptor ...>...</EntityDescriptor>",
    "nameid_format": "emailAddress",
    "saml_only": true,
    "default_roles": ["Employee"]
  }
}

Field semantics

  • enabled: Enable/disable SAML integration
  • entity_id: SP Entity ID used by the IdP trust config
  • acs_url: Must be HTTPS; IdP posts SAML responses here
  • idp_metadata_xml: Full IdP metadata XML
  • nameid_format: NameID format (e.g., emailAddress)
  • saml_only: Disable password login in Frappe when true
  • default_roles: Roles assigned on login if missing

IdP Setup Guide

Azure AD / Entra ID

  1. Create Enterprise Application.
  2. Configure SAML SSO.
  3. Set:
    • Identifier (Entity ID) = your entity_id
    • Reply URL (ACS) = your acs_url
  4. Add claim mappings:
    • email
    • first_name
    • last_name
  5. Download federation metadata XML and place in idp_metadata_xml.

Keycloak

  1. Create realm/client for SAML.
  2. Set client protocol saml.
  3. Configure:
    • Client ID = your entity_id
    • Valid Redirect URI = your acs_url
  4. Ensure response/assertions are signed.
  5. Export metadata XML and apply to idp_metadata_xml.

User Mapping

SAML Attribute Frappe Field
email User.email
first_name User.first_name
last_name User.last_name

Behavior:

  • Email is unique key
  • Missing users are auto-created as System User
  • Default roles are assigned idempotently

Endpoint Behavior

/saml/login

  • Builds AuthnRequest and redirects to IdP
  • Preserves next path via RelayState

/saml/acs

  • Validates SAML response
  • Enforces signature/issuer/audience/time checks
  • Enforces replay prevention
  • Provisions/maps user and creates Frappe session
  • Redirects to RelayState or /app

/saml/metadata

  • Generates and returns SP metadata XML
  • Useful for IdP onboarding and trust setup

/saml/logout

  • Logs out local Frappe session
  • Redirects to SAML login

Security Controls

Implemented controls:

  • HTTPS required for ACS
  • Strict SAML validation mode
  • Signed assertions/messages enforced
  • Assertion expiry and skew checks
  • Replay attack prevention via cached assertion IDs
  • Optional password-login blocking (saml_only=true)
  • Sanitized audit logging only (no full assertion payloads)

Operational recommendations:

  • Restrict access to site_config.json
  • Rotate IdP signing certs with metadata refresh process
  • Keep server time synchronized (NTP)
  • Enforce TLS 1.2+ at proxy/load balancer

Docker / Deployment Notes

  • Ensure container image includes python3-saml.
  • Mount or inject site_config.json per site securely.
  • Set X-Forwarded-Proto https correctly so app sees HTTPS.
  • Run behind a trusted reverse proxy with TLS termination.

Example (conceptual):

  • app container + worker + scheduler
  • reverse proxy with HTTPS
  • Redis for cache/session (used by replay detection cache)

Verification Checklist

After deployment, validate in staging:

  1. Open /saml/login and confirm redirect to IdP.
  2. Authenticate with IdP and confirm redirect to Desk.
  3. Verify new users are auto-created with mapped names.
  4. Verify default roles are assigned.
  5. Verify /saml/metadata returns valid XML.
  6. Replay same SAML response and confirm rejection.
  7. Set saml_only=true and verify /login password login is blocked.
  8. Inspect logs and confirm no raw SAML assertion content is logged.

Troubleshooting

"SAML authentication is disabled"

  • Ensure saml.enabled is true in site_config.json.

"SAML ACS URL must use HTTPS"

  • Use HTTPS ACS URL and configure proxy headers correctly.

Validation failures at ACS

  • Verify IdP metadata/certificate is current.
  • Confirm Entity ID and ACS URL exactly match IdP config.
  • Confirm response/assertion signing is enabled at IdP.

User not created

  • Ensure SAML includes email (or NameID resolves to email).
  • Confirm user is not disabled.

Bench Commands Reference

# install app
bench --site <site> install-app frappe_saml

# run migrations (if needed)
bench --site <site> migrate

# clear cache
bench --site <site> clear-cache

# restart services
bench restart

Compliance Note

This app is designed to support enterprise SSO compliance requirements, but final compliance posture depends on your deployment controls, IdP policy, key management, logging governance, and operational procedures.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors