TILLSHIELD · OVERVIEW

See the attack. Act on it.

TillShield is the security layer of TillDev. It reads the security telemetry your TillPulse SDKs already collect — device-integrity failures, TLS-pinning breaks, Android overlay abuse, web and desktop tamper signals — scores each one, and puts it in front of a rule. When a rule’s trigger is crossed it takes one action automatically: raise an incident, quarantine the session, revoke the user’s TillAuth sessions, or fire an alert. No new pipeline to stand up — it runs in the workspace you already have.

The mental model

Three moving parts, in order:

  1. Signals come in — security events reported by the SDKs, each with a type, a severity, and a confidence score. Some carry a cross-customer threat-intel match.
  2. Rules watch those signals. A rule’s trigger is a set of security types plus thresholds; when they’re met, the rule takes exactly one action.
  3. Incidents are the human side. Actions that raise an incident create a triage record — status, severity, assignee, and an append-only timeline — that your team works to resolution.

TillShield is reactive: it responds to signals after they’re reported. An inline, request-time enforcement layer is on the roadmap (see below) but is not part of the product today.

How detection works

TillShield doesn’t collect anything itself. It consumes the security events your TillPulse SDKs emit and normalizes them into a small set of security types:

  • device_integrity — a rooted Android or jailbroken iOS device reported by the mobile SDK. A compromised trust boundary.
  • tls_pinning_failure — a pinned connection whose certificate didn’t match. Often a man-in-the-middle in progress.
  • overlay_abuse — a foreign window drawn over your Android app: the classic tap-jacking / credential-capture vector.
  • tamper — web and desktop runtimes report their own tamper indicators through the same channel.
  • threat_intel_match — a signal whose indicator matched the shared cross-customer feed. See the privacy model.

Severity and confidence

Every signal lands with two numbers you write rules against. Severity is how serious the detection is (low critical). Confidence is how sure the SDK is that the detection is real, from 0 to 1. Keeping the two separate is deliberate: a low-confidence critical and a high-confidence low are very different situations, and you get to decide how each is handled.

Writing rules

A rule is a trigger and an action. The trigger selects which signals count and how many, over what window, before the rule fires:

{
  name: "integrity-lockdown",
  when: {
    types: ["device_integrity", "tls_pinning_failure"],
    minSeverity: "high",       // low | medium | high | critical
    minConfidence: 0.8,        // 0..1
    threshold: { count: 3, within: "10m" },
  },
  then: { action: "revoke_sessions" },
  testMode: false,             // dry-run: log, don't act
  cooldown: "30m",
}

The trigger

  • types — one or more security types the rule watches.
  • minSeverity — ignore anything below this severity.
  • minConfidence — ignore anything the SDK isn’t sure enough about.
  • threshold — a count of matching signals within a time window. One-offs don’t have to fire the rule; a burst does.

The action

A rule takes exactly one of four actions when it fires:

  • raise_incident — open a triage record with the triggering events attached.
  • quarantine_session — cut off the offending session, leaving the rest of the account intact.
  • revoke_sessions — end every auth session for the user; TillShield asks TillAuth to do it.
  • alert — notify the channel you already route TillPulse alerts to.

Test-mode and cooldowns

Turn on testMode to run a rule as a dry-run: it evaluates the trigger and logs what it would have done, without doing it. Use it to tune thresholds against real traffic before a rule can revoke anyone’s session. A per-rule cooldown then caps how often the action can repeat, so a single persistent attacker can’t make the rule fire a hundred times a minute.

Incident triage

A raise_incident action creates a record your team works — not another alert to acknowledge and forget. Every incident has a status, a severity, an assignee, and a timeline.

Status

Incidents move through four states, in order:

open → investigating → contained → resolved
  • open — freshly raised, unowned.
  • investigating — someone is on it.
  • contained — the threat is stopped; cleanup remains.
  • resolved — closed out, with the record intact.

The timeline

The timeline is append-only. Notes your team adds, every status change, and every action a rule took automatically are one ordered history — nothing is edited away after the fact. Assign an incident to a teammate and it shows up on their plate; the severity and the triggering events stay attached from open to resolved. Every one of these changes is also written to the shared TillDev audit log.

Threat intelligence & the privacy model

When a malicious package, certificate, or binary is seen attacking one TillDev customer, its indicator is shared across every org — so a threat that has hit someone else can surface for you before it reaches your users. The value is obvious; the trick is doing it without leaking anyone’s data.

The model is deliberately narrow:

  • sha256 indicators only. What’s shared is a one-way hash of the offending artifact — a fingerprint you can match against. There is no reversible payload and no raw identifier.
  • Anonymous. No org name travels with an indicator. You learn that a fingerprint is hostile; you never learn who it attacked first.
  • Opt-out. Contribution is on by default and can be disabled per workspace. Even if you don’t contribute, you still consume the shared feed.
  • Just another signal. A match arrives as a threat_intel_match with its own severity and confidence, so the same rules and actions apply — you can revoke sessions on a known-bad binary the same way you would on repeated integrity failures.

Enabling SDK security capture

TillShield only sees what your SDK sends. Device-integrity, pinning, and overlay checks live in the TillPulse mobile SDKs and are enabled in your SDK configuration — turn on the checks you want and the events flow into TillShield automatically. Conceptually:

import { init } from '@tillpulse/react-native'

init({
  dsn: process.env.TILLPULSE_DSN,
  // Security capture feeds TillShield. Enable the checks you need.
  security: {
    deviceIntegrity: true,   // root / jailbreak
    tlsPinning: true,        // pinning-failure reporting
    overlayDetection: true,  // Android overlay abuse
  },
})

The exact option names and platform coverage live in the SDK reference — React Native and Flutter. Once security events are arriving, you write rules against them from the TillShield section of your workspace; no rule fires until you create one.

On the roadmap

These are coming, not shipping. TillShield is reactive today; it does not sit in the request path. We’ll say so plainly here until each lands.

  • Inline WAF / edge decisioning — a request-time worker that blocks or challenges traffic on the hot path, turning a detection into a decision before the request is served. In design.
  • Server-side SDKs @tilldev/shield-node and @tilldev/shield-cloudflare, to enforce rules at your own edge and origin. Not published yet.

TillShield is part of TillDev — one workspace, one login, one audit log. See the workspace overview, or the docs for its siblings: TillPulse (the telemetry it reads) and TillAuth (the sessions it acts on). Prefer the pitch? See the product page.