🛡️ SentinelAISecurity Analyst Portal

SentinelAI — Detection Rules (MVP)

The MVP classifier is 100% deterministic rules + regex — no AI/LLM in the decision path. Everything runs locally in the endpoint agent (agent/app/classifier.py + risk.py) in <5 ms. This document is the authoritative list of what is detected and how a decision is reached.

Phase 2 adds an optional AI verification layer to reduce false positives (see docs/AI.md). It is off by default; the rules below are always the baseline.


1. What is detected

PII

Rule Pattern (plain English) Severity Validation
email_address name@domain.tld 20
phone_number US-style phone numbers 25
us_ssn 123-45-6789 80
credit_card 13–16 digit card numbers 85 Luhn checksum (rejects random digits)

Secrets & credentials (severity 95 — always block-worthy)

Rule Detects
aws_access_key AKIA… access key IDs
aws_secret aws_secret_access_key = … (40-char)
openai_key sk-… API keys
github_token ghp_/gho_/ghu_/ghs_/ghr_…
google_api_key AIza…
google_oauth_secret GOCSPX-…
stripe_secret_key sk_live_… / rk_live_…
slack_token xoxb-/xoxp-/xoxa-/xoxr-/xoxs-…
slack_webhook https://hooks.slack.com/services/…
azure_storage_key AccountKey=… connection strings
npm_token npm_… (36-char)
private_key -----BEGIN … PRIVATE KEY-----
jwt eyJ….….… JSON Web Tokens
bearer Bearer <token>
password_assignment password/passwd/pwd/secret = …

Source code (severity 55)

Fires when ≥2 code signals appear together (reduces false positives on prose): def/class …, function/const/let/var …, import …, from … import …, #include <…>, Java signatures (public static void …), SELECT … FROM …, and operators/markers (=>, ::, console.log(, println!(, System.out.print).

Financial (severity 45, IBAN 70)

  • financial_terms — revenue, EBITDA, salary, compensation, invoice, routing/account number, net income, forecast, P&L, gross margin, …
  • iban — International Bank Account Numbers, validated with the ISO mod-97 checksum.

Contract / legal (severity 45)

contract_language — confidential(ity), NDA, non-disclosure, master service agreement, indemnif…, "hereinafter", termination clause, governing law, "whereas", …


2. How a decision is made (risk.py)

  1. Base score = the single highest-severity finding, plus a volume bump (+3 per additional match, capped at +15).

  2. Destination weight multiplies the score by where the prompt is going:

    Destination Weight Rationale
    ChatGPT / Claude / Gemini ×1.0 consumer, highest exfil risk
    Microsoft Copilot ×0.85
    M365 Copilot ×0.70 enterprise tenant, lower default risk
  3. Bands map the final 0–100 score to an action:

    Score Decision Label
    81–100 block + alert SOC Restricted
    51–80 block Confidential
    26–50 warn (coaching, proceed on ack) Internal
    0–25 allow (log only) Public

Worked example: prompt containing an sk-… key sent to ChatGPT → severity 95, ×1.0, +volume ⇒ 98 → block / Restricted.


3. Known limitations (be upfront with stakeholders)

  • Structured data only. Regex excels at keys/PII/patterns; it cannot catch semantic secrets with no fixed shape — e.g. "our Q3 acquisition target is Acme for $40M." That is the gap the Phase-2 AI layer addresses.
  • No context. A public code sample and proprietary source both trip source_code. The AI layer is designed to suppress exactly these false positives (never to add detections).
  • Static thresholds. Bands and destination weights are hardcoded defaults; per-org policy is an open decision (Clarification #6).
  • Maintenance. Vendor token formats change; patterns need periodic review.

4. Extending

Add a rule in agent/app/classifier.py (a (name, regex) pair in _SECRETS, or a new detector in classify()), pick a severity, and add a test in agent/tests/test_classifier.py. Keep high-false-positive patterns gated behind a checksum (see _luhn_ok, _iban_ok) where possible.