Skip to content
Skillv1.0.0

mindtickle-security-basics

Security Basics for MindTickle. Trigger: "mindtickle security basics".

by jeremylongshore(0) 0 installs
Free
Sign in to install

Free account. Installing gives you the manifest plus copy-paste snippets.

See reviews

About

Imported from jeremylongshore/tons-of-skills-marketplace (plugins/saas-packs/mindtickle-pack/skills/mindtickle-security-basics/SKILL.md). Install upstream with npx skills add jeremylongshore/tons-of-skills-marketplace --skill mindtickle-security-basics. Copyright stays with the author (MIT).

MindTickle Security Basics

Overview

MindTickle integrations process employee PII through SCIM provisioning (names, emails, job titles, manager chains) and HR-sensitive data like course completion scores, certification status, and coaching assessments. The API uses bearer token authentication combined with a Company-Id header for multi-tenant isolation — omitting or spoofing this header can leak data across tenants. Webhook payloads carrying training completion events must be HMAC-verified to prevent injection of fraudulent compliance records.

Prerequisites

  • Secrets manager (AWS SSM, GCP Secret Manager, or Vault) for API tokens
  • HTTPS enforced on all SCIM and webhook endpoints
  • Company-Id validated against an allowlist of known tenant identifiers
  • .env files in .gitignore — never committed to version control
  • Data retention policy for employee training records (GDPR/SOC2)

API Key Management

// MindTickle requires both bearer token and company ID for multi-tenant isolation
const MT_API_TOKEN = process.env.MINDTICKLE_API_KEY;
const MT_COMPANY_ID = process.env.MINDTICKLE_COMPANY_ID;

function validateMindTickleConfig(): void {
  if (!MT_API_TOKEN) throw new Error('Missing MINDTICKLE_API_KEY');
  if (!MT_COMPANY_ID) throw new Error('Missing MINDTICKLE_COMPANY_ID');
}

function mindtickleHeaders(): Record<string, string> {
  return {
    Authorization: `Bearer ${MT_API_TOKEN}`,
    'Company-Id': MT_COMPANY_ID!,
    'Content-Type': 'application/json',
  };
}
// Call validateMindTickleConfig() at startup — both values are required for every request

Webhook Signature Verification

import crypto from 'node:crypto';

const MT_WEBHOOK_SECRET = process.env.MINDTICKLE_WEBHOOK_SECRET!;

function verifyMindTickleWebhook(payload: string, signature: string, timestamp: string): boolean {
  // Reject stale webhooks (>5 min) to prevent replay attacks
  const age = Date.now() - parseInt(timestamp, 10) * 1000;
  if (age > 300_000) return false;

  const signedPayload = `${timestamp}.${payload}`;
  const expected = crypto
    .createHmac('sha256', MT_WEBHOOK_SECRET)
    .update(signedPayload, 'utf8')
    .digest('hex');
  return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}

app.post('/webhooks/mindtickle', (req, res) => {
  const sig = req.headers['x-mindtickle-signature'] as string;
  const ts = req.headers['x-mindtickle-timestamp'] as string;
  if (!sig || !ts || !verifyMindTickleWebhook(JSON.stringify(req.body), sig, ts)) {
    return res.status(401).json({ error: 'Invalid signature or stale timestamp' });
  }
  // Process verified training completion event
});

Input Validation

// Validate SCIM user payloads — employee PII requires strict schema enforcement
interface ScimUser {
  userName: string;
  name: { givenName: string; familyName: string };
  emails: { value: string; primary: boolean }[];
}

function validateScimUser(user: unknown): user is ScimUser {
  const u = user as Record<string, unknown>;
  if (typeof u.userName !== 'string' || u.userName.length > 254) return false;
  const emails = u.emails as { value: string }[] | undefined;
  if (!emails?.every(e => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e.value))) return false;
  return true;
}

Data Protection

function redactEmployeeData(record: Record<string, unknown>): Record<string, unknown> {
  const piiFields = ['email', 'userName', 'phone', 'manager_email', 'employee_id'];
  const hrFields = ['score', 'certification_status', 'coaching_notes'];
  const redacted = { ...record };
  for (const field of [...piiFields, ...hrFields]) {
    if (redacted[field]) redacted[field] = '[REDACTED]';
  }
  return redacted;
}
// Redact before logging — course scores and coaching data are HR-confidential

Access Control

// Enforce tenant isolation — Company-Id must match the authenticated context
const ALLOWED_COMPANY_IDS = new Set(process.env.MT_ALLOWED_COMPANIES?.split(',') ?? []);

function assertTenantAccess(companyId: string): void {
  if (!ALLOWED_COMPANY_IDS.has(companyId)) {
    throw new Error(`Unauthorized tenant: ${companyId}`);
  }
}

function assertScimWriteAccess(operation: string, hasScimScope: boolean): void {
  const writeOps = ['createUser', 'updateUser', 'deactivateUser'];
  if (writeOps.includes(operation) && !hasScimScope) {
    throw new Error(`SCIM write operation "${operation}" requires scim:write scope`);
  }
}

Security Checklist

  • Bearer token and Company-Id stored in secrets manager
  • Company-Id validated against tenant allowlist on every request
  • Webhook HMAC-SHA256 verified with timestamp replay protection
  • SCIM payloads validated against strict schema before processing
  • Employee PII (email, name, phone) redacted in all logs
  • Course scores and coaching data classified as HR-confidential
  • SCIM write operations gated behind explicit scope checks
  • Data retention policy enforced for training completion records
  • Token rotation scheduled quarterly with zero-downtime swap

Error Handling

Vulnerability Risk Mitigation
Missing Company-Id header Cross-tenant data leakage Reject requests without validated Company-Id
Unverified webhooks Fraudulent training completion records HMAC-SHA256 + timestamp validation on every webhook
SCIM PII in logs Employee data breach (GDPR/SOC2) Redact all PII fields before logging
Stale webhook replay Duplicate or backdated compliance events Reject webhooks older than 5 minutes
Over-permissioned SCIM token Unauthorized user provisioning Enforce scim:write scope check for mutations

Resources

Next Steps

See mindtickle-prod-checklist.

Use it

Copy one of these into your project. Installing also returns the manifest and these snippets.

yaml
targets:
  - https://api.opensmartroute.ai/api/v1/registry/jeremylongshore-tons-of-skills-marketplace-mindtickle-se-3f736c/manifest   # or paste the manifest below

Manifest

An Open Capability Manifest: the router reads it to know what this does, what it costs and when to pick it.

jeremylongshore-tons-of-skills-marketplace-mindtickle-se-3f736c.ocm.jsonjson
{
  "ocm": "1",
  "id": "jeremylongshore-tons-of-skills-marketplace-mindtickle-se-3f736c",
  "kind": "skill",
  "name": "mindtickle-security-basics",
  "description": "Security Basics for MindTickle. Trigger: \"mindtickle security basics\".",
  "publisher": "jeremylongshore",
  "version": "1.0.0",
  "capabilities": {
    "domains": [
      "general"
    ],
    "tags": [
      "skill-md",
      "saas",
      "mindtickle",
      "sales",
      "skills-sh"
    ],
    "languages": [
      "en"
    ]
  },
  "quality_prior": 0.6,
  "examples": [
    "Security Basics for MindTickle. Trigger: \"mindtickle security basics\"."
  ],
  "primary": false,
  "metadata": {
    "source": {
      "provider": "skills.sh",
      "repository": "https://github.com/jeremylongshore/tons-of-skills-marketplace",
      "path": "plugins/saas-packs/mindtickle-pack/skills/mindtickle-security-basics/SKILL.md",
      "ref": "HEAD",
      "url": "https://github.com/jeremylongshore/tons-of-skills-marketplace/blob/HEAD/plugins/saas-packs/mindtickle-pack/skills/mindtickle-security-basics/SKILL.md",
      "key": "jeremylongshore/tons-of-skills-marketplace/plugins/saas-packs/mindtickle-pack/skills/mindtickle-security-basics/SKILL.md"
    },
    "compatibility": "Designed for Claude Code",
    "allowed_tools": [
      "Read,",
      "Write,",
      "Edit"
    ],
    "license": "MIT"
  },
  "instructions": "# MindTickle Security Basics\n\n## Overview\n\nMindTickle integrations process employee PII through SCIM provisioning (names, emails, job titles, manager chains) and HR-sensitive data like course completion scores, certification status, and coaching assessments. The API uses bearer token authentication combined with a `Company-Id` header for multi-tenant isolation — omitting or spoofing this header can leak data across tenants. Webhook payloads carrying training completion events must be HMAC-verified to prevent injection of fraudulent compliance records.\n\n## Prerequisites\n\n- Secrets manager (AWS ",
  "cost": {
    "context_tokens": 1486
  }
}

Fetch it by URL: GET /api/v1/registry/jeremylongshore-tons-of-skills-marketplace-mindtickle-se-3f736c/manifest?version=1.0.0

Reviews

Star ratings from people who tried it. One review per account; edit yours any time.

No reviews yet. Install it, try it, and be the first to rate it.