Skip to content

Security & Privacy

Learner messages and resolved profile variables are transmitted to the LLM provider you have configured. As the site administrator, you are responsible for informing your learners about this data processing and complying with the privacy laws applicable in your jurisdiction. SlideMind is a tool — the legal responsibility for its use rests with you.

In practice:

  • Choose your LLM provider carefully. Review the provider’s data processing agreement, data retention policies, and hosting jurisdiction. Some providers offer HIPAA-compliant or EU-hosted options.
  • Inform your learners. Your site’s privacy policy must disclose that messages and profile data are sent to a third-party AI provider for processing.
  • Comply with applicable laws. Depending on your jurisdiction, this may include GDPR (EU), Loi 25 (Quebec), CCPA (California), PIPEDA (Canada), or other regulations.
  • Limit data exposure. Only enable profile variables that are necessary for the learning experience. Avoid injecting sensitive personal data into prompts unless required.

API keys never leave your server and are never exposed to the learner’s browser.

E-learning module (browser)
│ POST /wp-json/slidemind/v2/chat
│ Body: { configId, messages, variables }
│ (no API key in the request)
WordPress server
├─ Validates the configuration (must be published)
├─ Checks CORS origin whitelist
├─ Checks rate limit (per IP, per slide)
├─ Decrypts the stored API key (AES-256)
├─ Builds the LLM request with the decrypted key
├─ Calls the external LLM provider
└─ Returns only the message + usage stats
E-learning module (browser)
└─ Displays the response

The learner’s browser never sees the API key. It sends conversation messages and receives the AI response. All authentication with the LLM provider happens server-side.

ProviderAuth methodEndpoint
OpenRouterBearer tokenapi.openrouter.ai
OpenAIBearer tokenapi.openai.com
Anthropicx-api-key headerapi.anthropic.com
MistralBearer tokenapi.mistral.ai
Google (Gemini)Bearer tokengenerativelanguage.googleapis.com

In all cases, the key is sent server-side only.


All API keys and license keys are encrypted at rest using AES-256-CBC with a random initialization vector (IV).

  1. A random 16-byte IV is generated for each encryption operation.
  2. The key is encrypted using openssl_encrypt() with AES-256-CBC.
  3. The IV is prepended to the ciphertext and the result is Base64-encoded for storage.
  4. On decryption, the IV is extracted and the key is decrypted server-side.

Each operation produces different ciphertext, even for the same key, because the IV is always random.

The encryption key is resolved in this order:

PrioritySourceSecurity level
1 (recommended)SM_ENCRYPTION_KEY constant in wp-config.phpHighest — key is outside the database
2sm_encryption_key option in the databaseModerate — key is in the same database as the encrypted data
3Auto-generated on first useModerate — same as above, but automatic
Section titled “Setting up SM_ENCRYPTION_KEY (recommended)”

Add this line to your wp-config.php, before the /* That's all, stop editing! */ line:

define( 'SM_ENCRYPTION_KEY', 'your-32-character-random-string' );

Use a strong, random 32-character string. You can generate one with a password manager or an online generator.

Important: If you change or remove the encryption key after storing API keys, all previously encrypted keys become permanently unreadable. You will need to re-enter every API key (global and per-course) and your license key. Back up your wp-config.php before making changes.

If SM_ENCRYPTION_KEY is not defined in wp-config.php, SlideMind displays a dismissible admin notice recommending that you add it. The plugin works without it (using the database fallback), but defining the constant provides better security.

  • Global API keys for each provider (stored in wp_options)
  • Per-course API key overrides (stored as post meta)
  • License keys

SlideMind stores the following data on your WordPress server:

Every API call is logged with metadata only — message content is never stored:

DataPurpose
Configuration IDWhich slide was used
Token countsPrompt + completion tokens
Estimated costIn USD, for billing tracking
Response timeIn milliseconds
Model usede.g., gpt-4, claude-3.5-sonnet
StatusSuccess or error (with error message)
IP addressFor rate limiting and analytics (stored in full, not anonymized)
User IDWordPress user ID (0 if unauthenticated)
TimestampWhen the request was made

Retention: Logs are automatically purged after the configured retention period (default: 90 days, configurable from 7 to 365 days in Settings > Advanced). A daily cron job handles cleanup.

GDPR note: Full IP addresses are personally identifiable information under GDPR. If your privacy policy requires IP anonymization, consider using a reverse proxy or server-level configuration to truncate IPs before they reach WordPress. SlideMind stores IPs as received by WordPress.

Variables stored between sessions for personalization:

DataPurpose
WordPress user IDLinks memory to an authenticated user (0 for anonymous)
Session IDUUID v4 identifying an anonymous browser session (empty for authenticated users)
Scopeglobal, course, or module
Variable name and valueThe actual stored data
TimestampsCreated and last updated

Retention:

  • Authenticated learners: Configurable in Settings > Advanced (keep forever, or auto-purge after 30/90/180/365 days of inactivity).
  • Anonymous sessions: Configurable TTL (default 24 hours, range 1-168 hours). Expired sessions are automatically purged by a daily cron job. The session ID is stored in the browser’s localStorage — clearing browser data ends the session.
  • Learner messages (conversation content) are not stored in the database by default
  • AI responses are not stored in the database by default
  • Profile variables resolved at runtime are not stored — they are read from existing WordPress user meta

Note: If Persistent memory is enabled on a slide, learner input and/or AI responses can be saved as memory variables. For example, an administrator might configure a slide to capture the learner’s answer (e.g., their profession) and store it as a memory variable for reuse in other slides. The captured content then becomes part of the learner’s memory data and follows the retention and privacy rules described above. See Learner Memory for details.

When a learner interacts with the widget, the following is sent to the configured LLM provider:

  • The system prompt (configured by the administrator)
  • The conversation messages (learner input + AI responses in the current session)
  • Resolved profile variables (if configured — e.g., learner name, role)
  • Resolved memory variables (if configured — injected into the system prompt)

The LLM provider processes this data according to their own privacy policy and terms of service.


SlideMind hooks into WordPress’s built-in privacy tools for data protection compliance.

SlideMind adds a suggested paragraph to your WordPress Privacy Policy page (Settings > Privacy). This text explains that AI-assisted interactions occur and that learner data may be sent to a third-party provider. Review and integrate this text into your published privacy policy.

SlideMind registers a data exporter with WordPress’s Tools > Export Personal Data tool. When you process an export request for a user, their learner memory variables are included in the export.

Exported data includes:

  • All memory variables (global, course, and module scope)
  • Variable names and values
  • Last updated timestamps

SlideMind registers a data eraser with WordPress’s Tools > Erase Personal Data tool. When you process an erasure request, all learner memory for that user is permanently deleted.

When a WordPress user is deleted, all their learner memory records are automatically purged.

Administrators can also manage learner data directly from SlideMind > Memory > Learner Data:

ActionDescription
ViewSee all stored variables for a learner
EditModify variable values inline
ExportDownload a learner’s data as JSON
PurgeDelete all data for a learner (with confirmation)

SlideMind includes an optional consent overlay for the chat widget. When enabled, learners must acknowledge that their messages are processed by an AI before they can interact.

To enable: Go to SlideMind > Settings > Advanced and check Widget consent banner.

Behavior:

  • The consent banner appears on the first widget load.
  • Once accepted, consent is stored in the learner’s browser (localStorage).
  • The banner does not reappear on subsequent visits.

When to disable: If your site already manages consent globally (e.g., via a cookie consent plugin or a site-wide privacy banner), you can disable the widget-level consent to avoid duplicate prompts.


SlideMind applies per-IP, per-slide rate limiting to prevent abuse and control costs.

SettingDefaultRange
Rate limit60 requests/minute0 (disabled) to 1,000

Configured in Settings > Advanced > Chat rate limit.

The rate limit is enforced per IP address and per slide configuration. If a learner exceeds the limit, they receive an HTTP 429 (Too Many Requests) response and must wait before trying again. The counter resets every 60 seconds.

EndpointLimitScope
Memory (/memory/*)60 req/minPer IP
Whoami (/whoami)30 req/minPer IP
Sandbox (/sandbox)Same as chatPer IP + per user (admin only)

The memory, whoami, and sandbox limits are fixed and not configurable.


CORS controls which external domains can call the SlideMind API. E-learning modules are typically hosted on a different domain than your WordPress site, so CORS configuration is required.

For full configuration details, see Administration — CORS Management.

Summary:

  • By default, only your site’s own domain is allowed.
  • Add LMS and SCORM hosting domains in Settings > Advanced > Allowed Domains (CORS).
  • A 24-hour test mode temporarily allows all origins for local development.

The chat, memory, and whoami endpoints are publicly accessible (no authentication required) because they are called from e-learning modules where learners may not have WordPress accounts. Security relies on:

  • Configuration validation (the requested slide must be published)
  • CORS origin whitelist
  • Rate limiting
  • Input sanitization and validation

The sandbox endpoint requires the manage_sm_configurations capability (administrators and editors).

PageRequired capability
Settingsmanage_sm_settings (administrators only)
Courses, Modules, Slidesmanage_sm_configurations (administrators and editors)
Sandbox, Analytics, Memorymanage_sm_configurations

All admin forms are protected with WordPress nonces (sm_admin_nonce) against CSRF attacks.


SlideMind validates these requirements on activation:

RequirementMinimumPurpose
PHP8.0+Language features and security
WordPress6.0+REST API and privacy tools
OpenSSL extensionRequiredAES-256 encryption

If OpenSSL is not available, the plugin cannot encrypt API keys and will not activate. OpenSSL status is displayed in Settings > Advanced > System Information.


Recommended practices:

  • Define SM_ENCRYPTION_KEY in wp-config.php
  • Configure CORS allowed origins (don’t leave it empty in production)
  • Set a reasonable rate limit (default 60/min is a good starting point)
  • Set log retention to the minimum period you need
  • Set learner memory retention if required by your privacy policy
  • Set anonymous session TTL to the minimum needed (default: 24 hours)
  • Enable the widget consent banner or ensure site-wide consent management
  • Review your privacy policy and add the SlideMind disclosure
  • Limit profile variables to only what is necessary for the learning experience
  • Review your LLM provider’s data processing terms