Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/sakaiproject/sakai/llms.txt

Use this file to discover all available pages before exploring further.

Security Configuration

Securing your Sakai installation is critical for protecting user data and maintaining system integrity. This guide covers essential security configurations and best practices.

SSL/TLS Configuration

Always use HTTPS in production to encrypt data in transit.

Tomcat SSL Configuration

1

Obtain SSL Certificate

Options:
  • Purchase from certificate authority
  • Use Let’s Encrypt (free)
  • Generate self-signed (testing only)
For Let’s Encrypt:
sudo certbot certonly --standalone -d sakai.example.edu
2

Configure Tomcat Connector

Edit /opt/tomcat9/conf/server.xml:
<Connector port="8443" protocol="HTTP/1.1"
           maxThreads="150" SSLEnabled="true">
    <SSLHostConfig>
        <Certificate
            certificateKeyFile="/etc/letsencrypt/live/sakai.example.edu/privkey.pem"
            certificateFile="/etc/letsencrypt/live/sakai.example.edu/cert.pem"
            certificateChainFile="/etc/letsencrypt/live/sakai.example.edu/chain.pem"
            type="RSA" />
    </SSLHostConfig>
</Connector>
3

Force HTTPS in Sakai

Add to sakai.properties:
# Force HTTPS URLs
force.url.secure=443

# Server URL with HTTPS
serverUrl=https://sakai.example.edu
4

Redirect HTTP to HTTPS

Add redirect connector in server.xml:
<Connector port="8080" protocol="HTTP/1.1"
           redirectPort="8443" />

Reverse Proxy SSL Termination

For production, use a reverse proxy (nginx/Apache) for SSL termination.

Nginx Configuration

server {
    listen 80;
    server_name sakai.example.edu;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name sakai.example.edu;

    ssl_certificate /etc/letsencrypt/live/sakai.example.edu/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/sakai.example.edu/privkey.pem;
    
    # SSL Settings
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;
    
    # Security Headers
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    
    location / {
        proxy_pass http://localhost:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Tomcat RemoteIpValve

Configure Tomcat to recognize forwarded headers:
<Valve className="org.apache.catalina.valves.RemoteIpValve"
       remoteIpHeader="x-forwarded-for"
       protocolHeader="x-forwarded-proto" />
When using a reverse proxy, do NOT set force.url.secure in sakai.properties. Use RemoteIpValve instead.

Authentication Security

Password Policies

Enforce strong password requirements.

Enable Password Policy

# Enable password policy
user.password.policy=true

# Policy provider
user.password.policy.provider.name=org.sakaiproject.user.api.PasswordPolicyProvider

# Entropy requirements (password strength)
user.password.minimum.entropy=16
user.password.medium.entropy=32
user.password.high.entropy=48

# Prevent user info in passwords
user.password.maximum.sequence.length=3

Password Requirements

With policy enabled, passwords must:
  • Meet minimum entropy score
  • Not contain long sequences from username
  • Not be common dictionary words
  • Meet length requirements

Failed Login Protection

# Log failed login attempts
login.log-failed=true

# Enable account lockout after failed attempts
user.login.maxattempts=5
user.login.lockout.minutes=30

Session Security

# Session timeout (minutes)
inactiveInterval=30

# Cookie security
cookieName=SAKAIID
cookieSecure=true
cookieHttpOnly=true

# Cookie domain (for subdomain access)
cookieDomain=.example.edu

reCAPTCHA Protection

Prevent automated attacks on login and registration.
# Enable reCAPTCHA
user.recaptcha.enabled=true
user.recaptcha.public-key=YOUR_RECAPTCHA_SITE_KEY
user.recaptcha.private-key=YOUR_RECAPTCHA_SECRET_KEY
Get keys from Google reCAPTCHA.

Single Sign-On (SSO)

Integrate with institutional authentication systems.

CAS (Central Authentication Service)

1

Enable CAS in Sakai

# Enable container authentication
container.login=true
top.login=false

# CAS server URL
cas.server.url=https://cas.example.edu/cas

# Service URL (your Sakai instance)
cas.service.url=https://sakai.example.edu/portal

# Container logout URL
login.container.logout.url=https://cas.example.edu/cas/logout
2

Configure Tomcat Valve

Add CAS valve to server.xml or context.xml:
<Valve className="org.jasig.cas.client.tomcat.v90.Cas30CasAuthenticator"
       casServerLoginUrl="https://cas.example.edu/cas/login"
       serverName="https://sakai.example.edu" />
3

Enable Guest Login

Allow direct login for guest accounts:
# Enable extra login
xlogin.enabled=true
xlogin.text=Guest Login
xlogin.choice.text=Guest Users

SAML 2.0

Integrate with SAML identity providers.
# SAML entity ID
saml.entityId=https://sakai.example.edu/saml

# Identity Provider metadata
saml.idp.entityId=https://idp.example.edu/saml
saml.idp.metadata.url=https://idp.example.edu/metadata.xml

# Attribute mapping
saml.attribute.userid=urn:oid:0.9.2342.19200300.100.1.1
saml.attribute.email=urn:oid:0.9.2342.19200300.100.1.3
saml.attribute.givenName=urn:oid:2.5.4.42
saml.attribute.surname=urn:oid:2.5.4.4

# Signing and encryption
saml.keystore.path=/path/to/saml-keystore.jks
saml.keystore.password=KEYSTORE_PASSWORD
saml.key.alias=sakai
saml.key.password=KEY_PASSWORD

LDAP/Active Directory

Authenticate against directory services.
# LDAP provider
provider.directory=org.sakaiproject.user.api.UserDirectoryProvider

# LDAP connection
ldap.url=ldaps://ldap.example.edu:636
ldap.basedn=ou=people,dc=example,dc=edu

# Bind credentials for search
ldap.bind.dn=cn=sakai,ou=services,dc=example,dc=edu
ldap.bind.password=LDAP_PASSWORD

# User attributes
ldap.attribute.userid=uid
ldap.attribute.firstname=givenName
ldap.attribute.lastname=sn
ldap.attribute.email=mail

# Search filter
ldap.filter=(objectClass=inetOrgPerson)

# Connection pooling
ldap.pooling=true
ldap.pool.maxsize=20
Use LDAPS (LDAP over SSL) instead of plain LDAP to encrypt directory communications.

Content Security

HTML Content Filtering

Protect against XSS attacks by filtering user-submitted HTML.
# Use high security profile (recommended)
content.cleaner.default.low.security=false

# Error handling for invalid HTML
# Options: none, logged, notify, display
content.cleaner.errors.handling=notify

# Log errors for monitoring
content.cleaner.errors.logged=true

# Force HTML files to download (prevent execution)
content.html.forcedownload=true

Custom Security Policies

Override AntiSamy security policies:
  1. Create custom policy files:
    • ${sakai.home}/antisamy/high-security-policy.xml
    • ${sakai.home}/antisamy/low-security-policy.xml
  2. Base on default policies in:
    • kernel/sakai-kernel-impl/src/main/resources/antisamy/

File Upload Security

# Maximum upload size (MB)
content.upload.max=20

# Upload ceiling (cannot be exceeded)
content.upload.ceiling=100

# Upload temporary directory
content.upload.dir=/tmp/sakai-uploads

# Block dangerous file types
content.upload.blocked.extensions=exe,bat,cmd,com,pif,scr,vbs,js,jar

# Virus scanning integration
viruscan.enabled=true
viruscan.engine=clamav
viruscan.host=localhost
viruscan.port=3310

Access Control

IP-Based Restrictions

Restrict access to administrative functions.
# Web services IP whitelist
webservices.allowlogin=true
webservices.allow=127.0.0.1,10.0.0.0/8,192.168.1.0/24

# Admin workspace IP restrictions
admin.workspace.allowed.ips=10.0.0.0/8

User Type Restrictions

Limit account creation by user type.
# Types allowed for anonymous registration
user.registrationTypes=registered

# Types non-admins can create
user.nonAdminTypes=guest

Email Domain Restrictions

# Blocked email domains for registration
invalidEmailInIdAccountString=@gmail.com,@yahoo.com,@hotmail.com

# Custom error message
user.email.invalid.domain.message=Please use your institutional email address.

# Disallow duplicate emails
user.email.allowduplicates=false

Database Security

Connection Security

# Use SSL for database connection
url@javax.sql.BaseDataSource=jdbc:mariadb://db.example.edu:3306/sakai?useSSL=true&requireSSL=true

# Verify server certificate
url@javax.sql.BaseDataSource=jdbc:mariadb://db.example.edu:3306/sakai?useSSL=true&serverSslCert=/path/to/ca.pem

Database User Permissions

Grant minimal required permissions:
-- Create dedicated Sakai user
CREATE USER 'sakai'@'app-server.example.edu' IDENTIFIED BY 'STRONG_PASSWORD';

-- Grant only necessary privileges
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, INDEX, ALTER 
ON sakai.* TO 'sakai'@'app-server.example.edu';

-- Do NOT grant:
-- DROP, GRANT, FILE, PROCESS, SUPER, etc.

Password Storage

Never store database passwords in plain text. Encrypt Properties:
# Use Tomcat vault or encrypted properties
# Store in security.properties instead of sakai.properties
Environment Variables:
# In setenv.sh
export DB_PASSWORD="your_password"

# In sakai.properties
password@javax.sql.BaseDataSource=${env.DB_PASSWORD}

API Security

Web Services Authentication

# Require authentication for web services
webservices.allowlogin=true

# Session-based authentication
webservices.allow.session=true

# IP restrictions
webservices.allow=127.0.0.1,10.0.0.0/8

# Rate limiting
webservices.ratelimit.enabled=true
webservices.ratelimit.requests=100
webservices.ratelimit.period=60

REST API Security

# Enable REST entity broker
entitybroker.rest.enabled=true

# Require authentication
entitybroker.require.authentication=true

# CORS settings
entitybroker.cors.enabled=true
entitybroker.cors.allowed.origins=https://trusted-site.example.edu

Security Headers

Add security headers to HTTP responses.

Configure Response Headers

# Number of headers to add
response.headers.count=5

# Security headers
response.headers.1=X-Content-Type-Options::nosniff
response.headers.2=X-Frame-Options::SAMEORIGIN
response.headers.3=X-XSS-Protection::1; mode=block
response.headers.4=Strict-Transport-Security::max-age=31536000; includeSubDomains
response.headers.5=Content-Security-Policy::default-src 'self'

Content Security Policy

Define allowed content sources:
response.headers.6=Content-Security-Policy::default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self'
Test CSP thoroughly before deployment as it can break functionality if too restrictive.

Privacy and Data Protection

GDPR Compliance

# Enable privacy controls
privacy.enabled=true

# Allow users to control profile visibility
profile.visibility.user.control=true

# Data retention policies
data.retention.enabled=true
data.retention.period.days=2555  # 7 years

# User data export
user.data.export.enabled=true
# Enable cookie policy warning
portal.cookie.policy.warning.enabled=true
portal.cookie.policy.warning.url=/library/content/cookie_policy.html

Audit Logging

Enable comprehensive audit trails.
# Event logging
events.enabled=true

# Log all user actions
events.log.all=true

# Event table size monitoring
events.size.check=true

# Archive old events
events.archive.enabled=true
events.archive.age.days=365

Monitoring and Alerts

Security Event Monitoring

Monitor critical security events:
# Alert on multiple failed logins
security.alert.failed.logins=5
security.alert.failed.logins.period=300

# Alert email
security.alert.email=security@example.edu

# Monitor privilege escalation
security.monitor.admin.access=true

Log Analysis

Regularly review logs for:
  • Failed login attempts
  • Privilege escalation attempts
  • Unusual API usage
  • Large file uploads
  • Database errors
# Monitor failed logins
grep "Login failed" /opt/tomcat9/logs/catalina.out | tail -100

# Check for suspicious activity
grep -E "(SQL|XSS|script)" /opt/tomcat9/logs/catalina.out

Backup Security

Encrypted Backups

#!/bin/bash
# Encrypted backup script

BACKUP_FILE="sakai-backup-$(date +%Y%m%d).tar.gz"
ENCRYPTED_FILE="${BACKUP_FILE}.gpg"

# Create backup
tar -czf $BACKUP_FILE /var/sakai/content /opt/tomcat9/sakai

# Encrypt with GPG
gpg --symmetric --cipher-algo AES256 $BACKUP_FILE

# Remove unencrypted backup
rm $BACKUP_FILE

# Store encrypted backup securely
mv $ENCRYPTED_FILE /secure/backup/location/

Secure Backup Storage

  • Store backups on separate systems
  • Encrypt backups at rest
  • Limit access to backup files
  • Regular backup restoration tests
  • Offsite backup copies

Security Checklist

1

SSL/TLS

  • SSL certificate installed and valid
  • HTTPS forced for all connections
  • TLS 1.2+ only (no SSL, TLS 1.0/1.1)
  • Strong cipher suites configured
  • HSTS header enabled
2

Authentication

  • Strong password policy enabled
  • Failed login protection configured
  • Session timeout set appropriately
  • SSO integrated (if applicable)
  • reCAPTCHA enabled for public forms
3

Content Security

  • HTML content filtering enabled
  • File upload restrictions configured
  • Virus scanning enabled
  • Content Security Policy defined
  • XSS protection headers set
4

Access Control

  • IP restrictions for admin functions
  • User type restrictions configured
  • Email domain restrictions set
  • Web services authentication required
  • API rate limiting enabled
5

Database Security

  • Database connection encrypted
  • Minimal database user permissions
  • Strong database passwords
  • Database backups encrypted
  • Regular security updates applied
6

Monitoring

  • Audit logging enabled
  • Security event monitoring active
  • Regular log reviews scheduled
  • Incident response plan documented
  • Security contacts configured

Security Best Practices

Regular Updates

  • Apply Sakai security patches promptly
  • Keep Tomcat updated
  • Update Java to latest LTS version
  • Apply OS security updates
  • Update database server regularly

Principle of Least Privilege

  • Grant minimal necessary permissions
  • Limit admin account usage
  • Use separate accounts for different roles
  • Regularly audit permissions
  • Remove unused accounts

Defense in Depth

  • Multiple security layers
  • Firewall protection
  • Intrusion detection/prevention
  • Network segmentation
  • Regular security testing

Incident Response

Prepare for security incidents:
  1. Detection: Monitor logs and alerts
  2. Analysis: Investigate suspected incidents
  3. Containment: Isolate affected systems
  4. Eradication: Remove threats
  5. Recovery: Restore normal operations
  6. Lessons Learned: Document and improve

Next Steps

User Management

Secure user account management

Configuration

Review security-related settings

Database Setup

Secure database configuration

Site Administration

Manage site permissions

Build docs developers (and LLMs) love