Alerting & Response
A decoy is touched. Alerting decides how bad that is; Response decides what you do about it. Two pillars, one motion.
Alerting
A decoy fires on behaviour nothing legitimate explains, so alerting is not about finding signal in noise. It is about making sure the signal arrives, that it is believed, and that it says how bad the interaction was.
In this pillar
- Why deception differs — why the usual false-positive problem disappears
- Where the signal comes from — which log records access to each kind of decoy
- Making sure it arrives — four properties the alert pipeline needs
- Deciding severity — decoy fidelity × how far the adversary went
Why deception differs
A conventional detection fires on behaviour that is usually malicious, so most of the engineering goes into suppressing false positives. A decoy fires on behaviour that has no legitimate explanation at all — nobody has a reason to authenticate with a credential that was never issued to a real service.
That changes what can go wrong. The risks are no longer false positives; they are a broken delivery path, an alert nobody believes, and an alert that quietly tells the adversary they have been caught. You are not trying to find signal in noise — the signal is already clean. You are trying to make sure it arrives, that it is believed, and that it carries enough context to act on.
Where the signal comes from
Decoys do not usually emit telemetry themselves. They are observed by the platform they live in, so the design question is always: which log already records access to this object, and is that log switched on?
| Technique class | Signal source | Watch for |
|---|---|---|
| Cloud identity & credential | CloudTrail · Entra sign-in logs · GCP Cloud Audit | Any authentication or API call naming the decoy principal |
| Cloud storage & data | S3 data events · Storage analytics · object access logs | Data-plane events are often off by default — enable per bucket |
| Compute & container | Host agent · VPC flow logs · runtime sensors | Inbound connection, process execution, egress attempt |
| Kubernetes | API server audit log | Audit policy must cover the decoy namespace and verb |
| Endpoint | Sysmon · EDR telemetry · Windows Security log | Registry read, memory access, ticket request for a honey SPN |
| Network | Flow logs · DNS query logs · full packet capture | Any traffic at all to an address that should receive none |
| Application & source code | Application logs · API gateway · callback endpoint | Requests to routes absent from your own client code |
Making sure it arrives
A clean signal is worth nothing if the path carrying it is broken, disbelieved, or readable by the adversary. Four properties the pipeline needs:
1. A channel of its own
Deception alerts should not land in the same queue as routine detections. Their value is that they are near-certain; routing them through a stream where 95% of items are noise destroys that advantage within a week.
2. Continuous proof of life
A decoy that stops reporting looks exactly like a decoy nobody has touched. Trigger one on a schedule and alert if the event does not arrive end-to-end — the canary-of-canaries. Without it you cannot distinguish a quiet network from a broken pipeline.
3. An alert path that does not leak the inventory
If the rule set, SIEM queries or IaC state enumerate every decoy, then an adversary who reaches your tooling gets a complete map of what to avoid. Treat the decoy inventory as sensitive material in its own right.
4. Context attached at fire time
The responder needs the decoy's fidelity, its intended tier, what a real interaction would mean, and what it is not able to tell them. Deciding that during an incident wastes the advantage the decoy just handed you.
Deciding severity
Two variables decide severity: how real the decoy was, and how far the adversary went. A touch on an inert tripwire and a shell on an interactive decoy are not the same event.
| What the adversary did | F1 F2 | F3 | F4 F5 |
|---|---|---|---|
| Seen / enumerated | T0 | T0 | T1 |
| Accessed or read | T1 | T1 | T2 |
| Credential used elsewhere | T3 | T3 | T4 |
| Interactive session established | — | T2 | T3 |
| Destructive action attempted | T4 | T4 | T4 |
A starting point, not a policy. Click any tier to see what it commits you to.
Real-time by platform
The same two-stage pipeline on every platform. Stage 1 runs next to the decoy and forwards only events that name a decoy. Stage 2 runs centrally and decides which actions alert. Then enrich, suppress known scanners, and notify on a channel of its own.
| Platform | Fastest documented signal | Watch out for |
|---|---|---|
| Amazon Web Services | CloudTrail write management events via EventBridge | A forwarding or destination rule left in the default ENABLED state silently drops read-only events such as AssumeRole and GetSecretValue. Both rules need ENABLED_WITH_ALL_CLOUDTRAIL_MANAGEMENT_EVENTS. |
| Microsoft Azure | Activity log | Data-plane reads (getting a secret, reading a blob) are not in the activity log. Without a diagnostic setting on the decoy, the decoy is blind. |
| Google Cloud | Cloud Audit Logs: Admin Activity | Data Access logs are off by default. A decoy secret or bucket read is invisible until DATA_READ is enabled for that service. |
| Kubernetes | API server audit log (self-managed) | List and watch on Secrets return their contents, so the 'ignore enumeration' rule does not apply. Controllers with cluster-wide secret watches will 'read' every decoy. Place decoys where no legitimate controller lists, or suppress only the named controller identities and review them. |
| Windows and Active Directory | Security event 4662 (Audit Directory Service Access) | Normal-mode WEF batches for up to 15 minutes. Decoy events need their own Minimize Latency subscription. |
| Linux | Kernel audit (auditd) | Many distributions ship -a never,task, which silently stops all syscall rules. |
| macOS | Endpoint Security framework (native ES client) | Without Full Disk Access (normally granted by MDM), the ES client gets nothing. |
| Network | Decoy listener's own log (OpenCanary or a native service listener) | Flow logs are summaries, delayed by minutes, and may be sampled. Do not use them as the only source for a T1 or higher decoy. |
| SaaS platforms | Microsoft 365 unified audit log (Office 365 Management Activity API) | The Microsoft 365 unified audit log has no near-real-time path. Use Entra sign-in logs for decoy identities, and treat file and mailbox decoys as slow (T0/T1) signals. |
| Custom applications | In-application decoy hook | Log sampling, DEBUG-level logging and trace sampling can drop the one event that matters. Send decoy events through a path that is never sampled. |
Amazon Web Services
Signal sources
| Source | Default | Latency | |
|---|---|---|---|
| CloudTrail write management events via EventBridge Control-plane changes involving decoys: security group ingress changes, instance starts, policy and role changes, stack operations.
Enable: Event history records management events by default, but EventBridge documents that a CloudTrail trail with logging must exist to deliver CloudTrail events. Create a multi-Region (or organisation) trail. Default-state ENABLED rules match write events. |
partial | Best effort. AWS documents about 5 minutes on average for CloudTrail log delivery, not guaranteed. No published figure for the EventBridge path. Measure it with proof-of-life. | verified |
| CloudTrail read-only management events via EventBridge Most targeted decoy reads: AssumeRole, GetSecretValue, GetParameter, Decrypt, DescribeKey, DescribeTable, Get*Attributes.
Enable: Set rule state ENABLED_WITH_ALL_CLOUDTRAIL_MANAGEMENT_EVENTS (CLI or CloudFormation only) on both the forwarding rule on the default bus and the rule on the destination bus. A default ENABLED rule does not match read-only events. The trail must log read management events. |
off | Same best-effort path as write events. | verified |
| CloudTrail data events Object and item level access: S3 GetObject, DynamoDB GetItem/Query/Scan, Lambda Invoke and other per-service data-plane calls.
Enable: Add advanced event selectors to the trail for the data event types needed. Rules in default ENABLED state match them. Per-event charges apply. Scoping selectors to decoy ARNs limits cost, but then the selectors list the decoys (see AP8). |
off | Best effort, same CloudTrail path. No separate published figure. | verified |
| VPC Flow Logs Network connections to decoy listeners and instances.
Enable: Create a flow log on the decoy subnet or ENI. Set the maximum aggregation interval to 1 minute. Send to CloudWatch Logs for the faster delivery. |
off | Not real-time. Aggregation is 10 minutes by default (1 minute optional; always 1 minute or less on Nitro), then typically about 5 minutes to CloudWatch Logs or about 10 minutes to S3, best effort. | verified |
The pipeline
- Stage 1 (at the decoy): In each decoy account and every enabled Region, put one EventBridge rule on the default bus with state ENABLED_WITH_ALL_CLOUDTRAIL_MANAGEMENT_EVENTS. Its event pattern matches decoy identifiers in detail.requestParameters or detail.resources, generated from the inventory. The target is the central event bus, sent through a role whose only permission is events:PutEvents on that bus ARN. Restrict who can read the rule (events:DescribeRule, events:ListRules), because the pattern is a decoy list.
- Stage 2 (central): In the monitoring account, put rules on the central bus, one per service (source plus an eventName list of targeted actions), also with state ENABLED_WITH_ALL_CLOUDTRAIL_MANAGEMENT_EVENTS so read-only events match. The target is a Lambda function. Configure retries and a dead-letter queue on the target.
- Enrich and suppress: The Lambda function looks up the decoy in the private inventory (kept in the monitoring account), adds technique, tier and path, and extracts userIdentity, sourceIPAddress, userAgent, Region and account. It applies the governed suppression list and removes duplicates. Drill events are confirmed against the drill record, never by a label in the event.
- Notify: SNS topic in the monitoring account feeding a dedicated decoy-alert channel or pager. Function errors and dead-letter-queue depth raise alarms to the same channel.
Proof of life
EventBridge Scheduler in the monitoring account sends a synthetic event to the central bus every few minutes, carrying a per-run value recorded centrally, and expects it in the drill channel. Less often, at random times, a role in the decoy account named like routine automation (<team>-<function>-role) reads a random decoy. A CloudWatch alarm on a 'proof received' metric with missing data treated as breaching fires when either proof misses its window.
Pitfalls
- A forwarding or destination rule left in the default ENABLED state silently drops read-only events such as AssumeRole and GetSecretValue. Both rules need ENABLED_WITH_ALL_CLOUDTRAIL_MANAGEMENT_EVENTS.
- CloudTrail events reach EventBridge only in the Region where they are recorded. Global-service and STS events land in the Region of the endpoint that was used. Deploy stage 1 in every enabled Region.
- Data events (S3 objects, DynamoDB items) are off by default and charged per event. Trails are often set to exclude KMS or read events to save cost, which blinds decoys.
- Delivery is best effort and undocumented for the EventBridge path. Never assume seconds. Measure with proof-of-life.
- Event patterns have a size quota (check the current EventBridge quotas). Large inventories need several stage 1 rules.
- Event history keeps 90 days of management events only. Retain raw decoy events centrally.
- Real proof-of-life touches appear in CloudTrail. Anyone who can read the trail can spot a regular touch pattern, so randomise the timing and the decoy, and restrict trail read access.
Microsoft Azure
Signal sources
| Source | Default | Latency | |
|---|---|---|---|
| Activity log Control-plane operations: create, update, delete and actions on decoy resources, such as role assignments and access-policy changes. It does not typically record reads.
Enable: Collected by default and kept 90 days. Add a diagnostic setting at subscription or management-group level to send it to a central Log Analytics workspace or Event Hub. |
on | Microsoft documents 3 to 20 minutes before activity log entries are available for analysis and alerting. | verified |
| Resource logs (data plane), such as Key Vault AuditEvent and Storage read logs Targeted reads of decoys: SecretGet, KeyDecrypt, KeyGet, blob reads and similar data-plane operations.
Enable: Create a diagnostic setting on each decoy resource (for example category AuditEvent on Key Vault) that sends to the central workspace or Event Hub. Apply the same setting to comparable real resources, or apply it broadly with Azure Policy, so decoys do not stand out. |
off | Microsoft documents resource logs as usually available in 3 to 10 minutes end to end. Key Vault logs are available at most 10 minutes after the operation. | verified |
| Microsoft Entra sign-in and audit logs Sign-ins by decoy users, service principals and app credentials, and directory changes that involve them.
Enable: Shown in the admin center by default. To alert on them, add a diagnostic setting that sends them to the central workspace or Event Hub. Microsoft documents up to three days before logs first appear in a newly routed workspace. |
partial | No per-event figure or SLA. Microsoft documents up to 24 hours before data first appears in a newly configured SIEM or storage account, and up to three days for a newly routed Log Analytics workspace. Steady-state latency is unpublished; measure it with proof-of-life. | verified |
| Virtual network flow logs Network connections to decoy listeners and VMs.
Enable: Enable virtual network flow logs through Network Watcher for the decoy network and read them from the storage account. NSG flow logs can no longer be created and retire on 30 September 2027, so do not build new paths on them. |
off | Not real time. Records are collected at one-minute intervals and appended to an hourly block blob in Azure Storage that is updated every few minutes. | verified |
The pipeline
- Stage 1 (at the decoy): Diagnostic settings scoped to the decoy resources act as the resource filter. Send them to an Event Hub in a security subscription for the fastest stream, or to the central Log Analytics workspace. Send the activity log by diagnostic setting at subscription or management-group scope. Restrict who can read diagnostic settings in decoy subscriptions.
- Stage 2 (central): Option 1: an Azure Function on the Event Hub filters operationName against the targeted-action set (SecretGet, KeyDecrypt and so on). Option 2: a log search alert, or a simple log search alert that evaluates each row, in the central workspace, filtering the same actions, and joining to an inventory watchlist kept in the security subscription.
- Enrich and suppress: The Function, or a Logic App behind the alert, adds inventory context, caller identity (UPN, appId, object ID), callerIpAddress and resource ID, and applies the governed suppression list. Drill events are confirmed against the drill record.
- Notify: Azure Monitor action group to a dedicated decoy-alert channel or pager. Failures of the Function or Logic App alert to the same channel.
Proof of life
A timer-triggered Function with its own managed identity, named like routine automation, reads a random decoy secret at random intervals. The touch is recorded centrally. Microsoft notes that log search alerts are weaker at detecting missing data, so check for absence with a metric alert on a 'proof received' custom metric, or a log query with a window wider than the 3 to 10 minute ingestion delay.
Pitfalls
- Data-plane reads (getting a secret, reading a blob) are not in the activity log. Without a diagnostic setting on the decoy, the decoy is blind.
- Event Grid system events cover some resource changes and Key Vault expiry or new-version events, but not reads. Do not rely on them for decoy access.
- A decoy that is the only resource with a diagnostic setting stands out to anyone who can read monitoring settings.
- Plan for 3 to 20 minutes on the activity log and up to 10 minutes on resource logs. Sub-minute response is not possible from these sources.
- A newly routed Entra log destination can take up to three days to start. Do not deploy decoy identities before it does (OP4).
- Activity log retention is 90 days unless exported.
Google Cloud
Signal sources
| Source | Default | Latency | |
|---|---|---|---|
| Cloud Audit Logs: Admin Activity Writes and configuration changes to decoys: IAM policy changes, creates, deletes.
Enable: Always written. They cannot be disabled or excluded. |
on | Google publishes no latency figure. Measure with proof-of-life. | verified |
| Cloud Audit Logs: Data Access Targeted reads: Secret Manager secret access, Cloud Storage object reads, Kubernetes API reads, and other DATA_READ and ADMIN_READ calls.
Enable: Enable DATA_READ (and ADMIN_READ where needed) in the IAM audit configuration for the services the decoys use, at organisation, folder or project level. Off by default except BigQuery. Volume and cost rise accordingly. |
off | Google publishes no latency figure. Measure with proof-of-life. | verified |
| Cloud Audit Logs: Policy Denied Access attempts against decoys that were denied by security policy. Useful for locked-down decoys.
Enable: Generated by default. Make sure no exclusion filter drops them. |
on | No published figure. | verified |
| VPC Flow Logs Network connections to decoy listeners and VMs.
Enable: Enable on the decoy subnet. Set the secondary sampling rate to 100%: configurations created with the Compute Engine API keep 50% by default, while Network Management API configurations keep 100%. |
off | Aggregation interval defaults to 5 seconds. Google publishes no delivery-latency figure. Sampling can drop a single probe entirely. | verified |
The pipeline
- Stage 1 (at the decoy): A sink on the decoy project, or a non-intercepting aggregated sink on the folder or organisation, whose inclusion filter matches decoy resource names (protoPayload.resourceName) generated from the inventory. It routes to a Pub/Sub topic in a security project. Restrict logging.sinks.get on decoy projects, because the filter is a decoy list.
- Stage 2 (central): A Cloud Run function in the security project subscribes to the topic and matches protoPayload.methodName against the targeted-action set for each service. Log-based alerting policies also work, but they apply a notification rate limit and are better suited to low-volume paging than to per-event processing.
- Enrich and suppress: The function adds inventory context, principalEmail, callerIp, user agent and resource name, applies the governed suppression list, and removes duplicates. Google documents duplicate audit-log delivery for some sources. Drill events are confirmed against the drill record.
- Notify: The function sends to a dedicated decoy-alert channel. Alternatively, Cloud Monitoring notification channels via an alerting policy. Function errors and Pub/Sub backlog (oldest unacked message age) alert to the same channel.
Proof of life
Cloud Scheduler publishes a synthetic message to the topic regularly. Less often, a scheduled job running as a dedicated service account, named like routine automation, reads a random decoy. A Cloud Monitoring alert on absence of a 'proof received' metric (a log-based metric on the function's output) fires when a window is missed.
Pitfalls
- Data Access logs are off by default. A decoy secret or bucket read is invisible until DATA_READ is enabled for that service.
- Google publishes no audit-log delivery latency. Treat it as minutes until measured.
- Sinks cannot route entries retroactively, and Cloud Storage sinks are processed hourly. Use Pub/Sub for alerting.
- The default VPC Flow Logs sampling (50% on Compute Engine API configurations) can miss a single connection.
- Eventarc audit-log triggers are subject to the same audit-log delay, and a newly created trigger takes up to about two minutes to become active.
- Log-based alert notification rate limits mean repeated touches may be merged. Keep the raw events in the function path.
Kubernetes
Signal sources
| Source | Default | Latency | |
|---|---|---|---|
| API server audit log (self-managed) Every API request on decoy objects: get, list or watch on decoy Secrets, ConfigMaps and service-account tokens, exec into decoy pods, RBAC use.
Enable: Start kube-apiserver with --audit-policy-file plus a backend (--audit-log-path or --audit-webhook-config-file). With no policy file, nothing is logged. Log decoy objects at Metadata level (rules can match resourceNames) so secret values never enter the log. |
off | Log backend: written locally as requests complete. Webhook backend in the default batch mode: up to 30 seconds (--audit-webhook-batch-max-wait default). Events are dropped if the 10000-event buffer overflows. | verified |
| Managed control-plane audit logs (EKS, AKS, GKE) The same API audit events on managed clusters.
Enable: EKS: enable the audit log type, which is off by default, to send to CloudWatch Logs. AKS: add a diagnostic setting with category kube-audit, which is off by default. kube-audit-admin excludes get and list and is blind to decoy reads. GKE: writes go to Admin Activity (always on), while get and list go to Data Access logs. Confirm Data Access logging is enabled for the cluster's project and test with a read. |
partial | EKS: within a few minutes, best effort. AKS: Azure resource-log path, usually 3 to 10 minutes. GKE: no published figure. | verified |
| Node runtime sensors (Falco, Tetragon) Reads of decoy files or mounted decoy tokens inside containers and on nodes, which the API audit log never sees.
Enable: Deploy the sensor as a DaemonSet with rules on decoy paths. Forward its output to the central collector. |
off | No vendor latency figure. Falco emits an alert when a rule matches and can send it to a file, syslog, a program, HTTP(S) or gRPC; Tetragon exports JSON logs or gRPC. Do not rely on tailing stdout: Falco documents output buffering that can delay container-log tailing by more than 15 minutes. Use HTTP or gRPC output into the central collector (for Falco, through Falcosidekick). | verified |
The pipeline
- Stage 1 (at the decoy): An audit policy rule that selects decoy objects by namespace, resource and resourceNames, at Metadata level, sent through the webhook backend (self-managed) or the managed provider's log path. The policy sits on the control plane, out of tenants' reach. Node sensors use rules matched to decoy paths.
- Stage 2 (central): A central collector, such as the Falco k8s audit plugin or the cloud function used for that provider, matches verbs and subresources (get, list, watch, create on pods/exec, token requests) against the action set and drops known controller identities on the governed suppression list.
- Enrich and suppress: Add the inventory entry, user.username, groups, sourceIPs, userAgent, the impersonation fields, and the pod or node identity (from node sensors). Drill events are confirmed against the drill record.
- Notify: A dedicated decoy-alert channel through the central processor. Webhook backend errors, dropped-event counters and sensor DaemonSet health alert to the same channel.
Proof of life
A CronJob running as a dedicated service account, named like routine automation, performs get on a random decoy object at random times. The run is recorded centrally. The central processor alerts when an expected proof does not arrive within the backend's latency window.
Pitfalls
- List and watch on Secrets return their contents, so the 'ignore enumeration' rule does not apply. Controllers with cluster-wide secret watches will 'read' every decoy. Place decoys where no legitimate controller lists, or suppress only the named controller identities and review them.
- Auditing is off unless a policy file is set, and an empty rules list is invalid. Managed providers ship with control-plane audit logging off (EKS, AKS).
- On AKS, kube-audit-admin omits get and list. Use kube-audit.
- Logging Secrets at Request or RequestResponse level writes secret values, real and decoy, into the log. Use Metadata.
- Admission webhooks do not see read requests, so they cannot detect decoy reads.
- The webhook batch buffer drops events when it overflows. Alert on the drop metrics.
- GKE does not log some system requests (level None). Do not model decoys on those identities or paths.
Windows and Active Directory
Signal sources
| Source | Default | Latency | |
|---|---|---|---|
| Security event 4662 (Audit Directory Service Access) Reads of, or operations on, decoy directory objects (accounts, groups, GPOs, attributes).
Enable: Enable the Audit Directory Service Access subcategory on domain controllers, and put a SACL on each decoy object for the accesses to watch (for example Read Property on chosen attributes). Without a matching SACL, 4662 is not generated. |
off | Written locally on the DC that served the request. End-to-end delay depends on forwarding (see Windows Event Forwarding). | verified |
| Kerberos events 4768, 4769, 4771 (Audit Kerberos Authentication Service and Service Ticket Operations) Ticket requests for decoy accounts and service principal names (for example roasting attempts) and pre-authentication failures.
Enable: Enable both Kerberos subcategories (Success and Failure) on every DC. Microsoft's table shows no Windows default for them. Check the effective policy with auditpol /get /category:*, because domain policy may differ. |
off | Written locally on the issuing DC. End-to-end delay depends on forwarding. | verified |
| Logon events 4624 and 4625 (Audit Logon) Use of decoy credentials to log on to member servers and workstations.
Enable: On by default for Success and Failure (Windows 10 1809 and later, and Windows Server per Microsoft's table). Confirm with auditpol. |
on | Written locally on the target host. End-to-end delay depends on forwarding. | verified |
| File and share access 4663 and 5145 (Audit File System, Audit Detailed File Share) Reads of decoy files and shares on Windows hosts.
Enable: Enable the subcategory and put a SACL on the decoy file or share. |
off | Written locally. End-to-end delay depends on forwarding. | verified |
| Windows Event Forwarding (WEF/WEC) Transport of the events above from DCs and hosts to a collector.
Enable: Configure a source-initiated subscription. Add NETWORK SERVICE to Event Log Readers on sources so the Security log can be forwarded. Use a dedicated subscription for decoy events set to Minimize Latency, or Custom with a low DeliveryMaxLatency. |
off | Normal mode: pull, batches of 5, 15-minute batch time-out. Minimize Latency: push, 30-second batch time-out. Minimize Bandwidth: 6 hours. | verified |
The pipeline
- Stage 1 (at the decoy): The SACL on the decoy object, file or share is the resource filter for 4662 and 4663. For Kerberos and logon events, the subscription's XPath query selects only events whose EventData names a decoy account or SPN, generated from the inventory. Use a dedicated Minimize Latency subscription.
- Stage 2 (central): On the collector or central platform, match on event ID plus access mask, operation or ticket options (for example 4769 for a decoy SPN, 4662 with Read Property or Control Access on a decoy object) and drop governed suppressions.
- Enrich and suppress: Add the inventory entry, SubjectUserName and SID, logon ID, client address, ticket encryption type and the DC or host name, and correlate with a 4624 by logon ID where present. Drill events are confirmed against the drill record.
- Notify: A dedicated decoy-alert channel from the central platform. Monitor subscription runtime status. A source going inactive alerts to the same channel.
Proof of life
A scheduled task on a management host, running as a dedicated account named like a routine service, requests a service ticket for a random decoy SPN or reads a decoy attribute at random times, and the run is recorded centrally. The central platform alerts when an expected 4769 or 4662 does not arrive within the subscription's latency window.
Pitfalls
- Normal-mode WEF batches for up to 15 minutes. Decoy events need their own Minimize Latency subscription.
- 4662 and Kerberos events are logged only on the DC that served the request. Forward from every DC, including read-only DCs.
- A SACL can be removed silently by an administrator. Reconciliation (OP6) must check SACLs, not only that the object exists.
- Directory sync tools, backup and inventory tools read many attributes. Scope SACLs to specific attributes and access types.
- Busy DC Security logs wrap. Make sure events are forwarded before they are overwritten.
- Do not rely on the default-domain-policy audit state. Confirm the effective policy on each DC with auditpol.
Linux
Signal sources
| Source | Default | Latency | |
|---|---|---|---|
| Kernel audit (auditd) Reads, writes and executes on decoy files, keys and credential stores, with uid, auid, process and syscall.
Enable: Install auditd. Add a syscall rule such as -a always,exit -F path=<decoy-path> -F perm=r -k <neutral-key> (the -w form is deprecated). Remove any default -a never,task rule, which disables syscall auditing on many distributions. Consider -e 2 to lock the configuration until reboot. |
off | Events are recorded locally and auditd multiplexes them to plugins in real time. End-to-end delay is set by the plugin or shipper (for example audisp-remote, whose max_time_per_record setting allows at most 5 seconds by default to deliver each record). | verified |
| sshd authentication logs (journald or the auth log) Use of decoy accounts or decoy SSH keys.
Enable: Logged by default on standard installs. Forward to the central collector. |
on | Written locally as the event happens (OpenSSH defaults: SyslogFacility AUTH, LogLevel INFO; some distributions use AUTHPRIV). Forwarding delay depends on the shipper. | verified |
| eBPF runtime sensors (Falco, Tetragon) File opens, process execution and network connections involving decoys, with container context.
Enable: Install the sensor and add rules for decoy paths. |
off | No vendor latency figure. Falco emits an alert when a rule matches (file, syslog, program, HTTP(S) or gRPC output); Tetragon writes JSON to /var/log/tetragon/tetragon.log by default or exports over gRPC. Avoid stdout tailing, which Falco documents can lag by more than 15 minutes because of buffering. | verified |
The pipeline
- Stage 1 (at the decoy): An audit rule (or sensor rule) scoped to the decoy paths is the resource filter. Use a key name that looks routine, because keys appear in logs. Forward matches off the host immediately with an audispd plugin or syslog shipper.
- Stage 2 (central): The central collector matches syscall and permission (read, open, exec) and drops governed suppressions for named backup, indexing or scanning processes, matched by executable path and user together.
- Enrich and suppress: Add the inventory entry, host, auid (the original login user), uid, exe, comm, parent process, terminal and source address of the session. Drill events are confirmed against the drill record.
- Notify: A dedicated decoy-alert channel from the central collector. A host that stops sending, an auditd stop, or an audit CONFIG_CHANGE event alerts to the same channel.
Proof of life
A systemd timer or cron job running as a dedicated service user, named like routine automation, reads a random decoy file at random times, and the run is recorded centrally. The central collector alerts when the matching audit record does not arrive.
Pitfalls
- Many distributions ship
-a never,task, which silently stops all syscall rules. - A root attacker can stop auditd or delete rules. Forward immediately, lock with -e 2, and alert on CONFIG_CHANGE and on host silence.
- Indexers (updatedb or locate), antivirus, backup agents and configuration management read files routinely. Suppress by exact executable plus user, never by path alone.
- Audit backlog limits (-b) and rate limits (-r) drop events under load.
- Methods based on atime fail on noatime or relatime mounts. Use syscall auditing instead.
- Paths inside containers differ from host paths. Write rules for the mount namespace the sensor sees.
Sources: [1]
macOS
Signal sources
| Source | Default | Latency | |
|---|---|---|---|
| Endpoint Security framework (native ES client) File open, exec, authentication and other events touching decoy files or credentials.
Enable: Deploy a client that runs as root, is signed with the Endpoint Security entitlement (requested from Apple) and is approved for Full Disk Access, which MDM can pre-approve with a privacy preferences payload on supervised Macs. Subscribe to NOTIFY events (for example open) and filter to decoy paths. For testing, the built-in eslogger tool (macOS 13 and later) is already entitled but is not meant for production use. |
off | NOTIFY events are asynchronous and always delivered; the operation proceeds without waiting for the client. Apple publishes no latency figure. | verified |
| eslogger (macOS 13 and later) The same Endpoint Security NOTIFY events, as JSON on stdout or to the unified log.
Enable: Run as root, with Full Disk Access granted to the responsible process. Ships with the OS and is already entitled. Apple says it is not intended for applications and its output can change in updates, so use it for prototyping and validation, not as the production fleet sensor. |
off | Streams as events occur. No figure published. | verified |
| Unified log sshd and authorisation events that involve decoy accounts.
Enable: Collect with a predicate-scoped log stream or an agent. Private fields may be redacted. |
on | Local and immediate. Not verified. | unverified |
The pipeline
- Stage 1 (at the decoy): An ES client subscribed to open and exec, with path filtering (muting everything except the decoy paths) so only decoy touches leave the host. Forward immediately to the central collector.
- Stage 2 (central): The central collector matches the event type and process. Drop governed suppressions for named system processes (Spotlight indexing, backup, endpoint protection) by code-signing identity, not by process name.
- Enrich and suppress: Add the inventory entry, host, user, process path, signing identity, team ID, parent process and audit token. Drill events are confirmed against the drill record.
- Notify: A dedicated decoy-alert channel from the central collector. Client exit, revoked Full Disk Access or host silence alerts to the same channel.
Proof of life
A launchd job running as a dedicated account opens a random decoy file at random times, and the run is recorded centrally. The central collector alerts when the open event does not arrive.
Pitfalls
- Without Full Disk Access (normally granted by MDM), the ES client gets nothing.
- eslogger is not a supported production sensor and its output format can change between updates.
- Spotlight, Time Machine, iCloud sync and endpoint protection open files constantly. Match suppressions on signing identity.
- Open events are very high volume. Filter at the source.
- The legacy BSM audit subsystem is deprecated. Do not build new decoy detection on it (not verified against Apple documentation in this run).
Network
Signal sources
| Source | Default | Latency | |
|---|---|---|---|
| Decoy listener's own log (OpenCanary or a native service listener) Connections, login attempts, submitted credentials and commands against decoy services on unused addresses or ports.
Enable: Logging is part of deploying the listener. Configure a syslog or webhook handler to the central collector, not only a local file. |
on | The listener logs each connection or attempt as it happens and passes it to the configured handler. OpenCanary ships webhook, Slack and Teams handlers besides file and syslog; delay is set by the handler and the receiver. | verified |
| Cloud flow logs (AWS VPC, Google Cloud VPC, Azure virtual network) Connections to decoy addresses and ports, including rejected ones.
Enable: Enable on the decoy subnet or interface, with the shortest aggregation interval and full sampling. |
off | Minutes, not real-time. AWS: 1 or 10 minute aggregation plus about 5 to 10 minutes delivery, best effort. Google Cloud: 50% sampling by default on Compute Engine API configurations. | verified |
| Network sensors (Zeek, Suricata) on a tap or span Protocol-level activity toward decoy addresses and names, including DNS lookups of decoy hostnames.
Enable: Deploy on a segment that sees decoy traffic, with rules or scripts matching decoy addresses and names. |
off | No vendor latency figure. Suricata EVE output can go to a file, syslog, a unix socket or Redis, and its default buffer-size of 0 means no buffering. Zeek log writers may buffer output (Log::set_buf, Log::flush); stream with a JSON writer or a Kafka writer plugin rather than waiting for log rotation. | verified |
| Router and firewall flow export (NetFlow, IPFIX) and deny logs Connections to decoy addresses across segments.
Enable: Enable flow export or rule logging on the decoy address. Shorten the active and inactive flow time-outs. |
off | Bounded by the flow cache time-outs. Cisco Flexible NetFlow defaults are 1800 seconds active and 15 seconds inactive: a short probe of the decoy exports about 15 seconds after it goes idle, but a long-lived session can wait up to 30 minutes. Shorten the active time-out on decoy segments. | verified |
The pipeline
- Stage 1 (at the decoy): The decoy listener is its own resource filter: it only exists to be touched. For flow or sensor sources, filter on the decoy addresses, ports and hostnames from the inventory, at the sensor or collector.
- Stage 2 (central): The central collector classifies by action (connection only, authentication attempt, credential submitted, command run) and drops governed suppressions for named scanners, matched by source address and schedule together.
- Enrich and suppress: Add the inventory entry, source address and asset-inventory lookup of the source host and its owner, destination service, credentials attempted (kept in the restricted alert store only) and NAT translation where available. Drill events are confirmed against the drill record.
- Notify: A dedicated decoy-alert channel. Listener health (no heartbeat) alerts to the same channel.
Proof of life
A scheduled job on a management host connects to a random decoy listener at random times, from an address recorded centrally. The central collector alerts when the connection event does not arrive.
Pitfalls
- Flow logs are summaries, delayed by minutes, and may be sampled. Do not use them as the only source for a T1 or higher decoy.
- Vulnerability scanners and asset discovery will touch every internal decoy. Suppress them by source and schedule together, and review the entries. A compromised scanner host is a real attacker.
- Internet-facing listeners see constant background scanning. Route them to analysis, not paging.
- NAT and proxies hide the real source. Collect translation logs.
- Banners, versions and port sets that do not match real hosts in the segment make listeners easy to fingerprint.
SaaS platforms
Signal sources
| Source | Default | Latency | |
|---|---|---|---|
| Microsoft 365 unified audit log (Office 365 Management Activity API) Access to decoy files, mailboxes, sites and Teams content.
Enable: On by default for enterprise organisations. Verify with Get-AdminAuditLogConfig in Exchange Online PowerShell. Retention depends on licence (180 days standard). |
on | No near-real-time path. Microsoft gives no guarantee: typically 60 to 90 minutes for core services, longer for others. | verified |
| Microsoft Entra sign-in logs Sign-ins with decoy accounts or decoy app credentials. Usually the fastest decoy signal in a Microsoft 365 tenant.
Enable: Shown in the admin center by default. Route through diagnostic settings to an Event Hub or workspace for alerting. |
partial | No per-event figure or SLA. Microsoft documents up to 24 hours before data first appears in a newly configured SIEM or storage account, and up to three days for a newly routed Log Analytics workspace. Measure steady-state latency with proof-of-life. | verified |
| Google Workspace audit and investigation logs (Reports API) Access to decoy Drive files, logins and SAML sign-ins with decoy accounts, admin actions, OAuth token grants.
Enable: Recorded by default. Retention is 6 months and cannot be changed. Poll the Reports API, or use its push channels (not verified here), filtered to decoy document IDs and accounts. |
on | Admin, Drive, login and SAML events: near real time (a couple of minutes). Account events: tens of minutes. OAuth token events: a couple of hours or more. | verified |
| Other SaaS audit logs and streaming Access to decoy objects (repositories, records, tickets, keys) in other SaaS platforms.
Enable: Check the vendor's documentation for audit availability by plan, streaming support and documented lag. Many offer only polling APIs. |
partial | Varies widely; record the documented figure per vendor. Examples: Microsoft 365 unified audit log, typically 60 to 90 minutes for core services with no guarantee (Management Activity API notifications typically within an hour); Google Workspace admin log events, near real time (a couple of minutes), other log types vary; Okta log streaming to EventBridge or Splunk Cloud, near real time with no guaranteed maximum; GitHub audit log streaming, Enterprise Cloud only (standalone organisations cannot stream). | verified |
The pipeline
- Stage 1 (at the decoy): Usually not possible on the SaaS side. Collapse it into the central query: poll or stream the audit API and filter on decoy object IDs and accounts from the inventory. Where the platform offers per-object alerts or streaming filters, scope them to decoys.
- Stage 2 (central): The central processor matches the activity types that count as access (view, download, sign-in, token grant) and drops governed suppressions such as DLP and indexing service identities.
- Enrich and suppress: Add the inventory entry, actor, IP address, user agent or client app, and object ID. Drill events are confirmed against the drill record.
- Notify: A dedicated decoy-alert channel. Polling failures and API errors alert to the same channel.
Proof of life
A scheduled job using a dedicated account opens a random decoy object at random times, and the run is recorded centrally. Set the absence window to the source's documented lag (for example more than 90 minutes for the Microsoft 365 unified audit log).
Pitfalls
- The Microsoft 365 unified audit log has no near-real-time path. Use Entra sign-in logs for decoy identities, and treat file and mailbox decoys as slow (T0/T1) signals.
- Google Workspace OAuth token events lag by hours, while Drive and login events lag by minutes. Choose the decoy type to suit the latency needed.
- Email link scanners, previews, DLP and search indexing open decoy documents and links. Check the actor before alerting.
- Audit retention and availability depend on licence and plan.
- Polling APIs have rate limits and pagination, and can miss events if a poll fails. Track your position in the log and alert on gaps.
Custom applications
Signal sources
| Source | Default | Latency | |
|---|---|---|---|
| In-application decoy hook Use of decoy API keys, decoy accounts, decoy records or fields, and requests to decoy endpoints or parameters.
Enable: Add a check at the point of use (authentication, data access layer, router) that recognises decoy identifiers and emits a structured security event straight to the central path. Store decoy identifiers as hashes in configuration so that reading the code does not reveal the inventory. |
off | As fast as the emit path you build. Send synchronously or through a non-sampled queue. Not verified. | unverified |
| Web server, proxy and load balancer access logs Requests to decoy paths and hosts.
Enable: Enable access logging on the front end. Managed load balancer access logs are often off by default and delivered in batches. |
partial | Managed load balancers deliver in batches. AWS Application Load Balancer access logs are disabled by default and published every 5 minutes per node (Classic Load Balancer: 5 or 60 minutes, default 60). Azure Application Gateway access logs are collected every 60 seconds once enabled in diagnostic settings. Google Cloud external Application Load Balancer logging is off by default on new backend services. Self-hosted web server logs are written per request. | verified |
| Database audit logs Queries that touch decoy tables, rows or columns.
Enable: Enable the engine's audit feature scoped to the decoy objects. PostgreSQL: load pgAudit through shared_preload_libraries and use object audit logging (pgaudit.role, then grant that role SELECT on the decoy tables); pgaudit.log defaults to none. SQL Server: create a server audit plus a database audit specification for the decoy objects. Ship the engine log to the central collector. |
off | Depends on the engine and on how its log is shipped; no general figure. | verified |
The pipeline
- Stage 1 (at the decoy): The hook itself is the resource filter: it only fires when a decoy identifier is used. For access logs, filter on decoy paths and hosts at the shipper.
- Stage 2 (central): The central processor classifies by action (authentication with a decoy key, read of a decoy record, request to a decoy route) and drops governed suppressions (named health checks or crawlers, by identity and source).
- Enrich and suppress: Add the inventory entry, authenticated principal, session, source address, user agent, request ID and trace ID. Drill events are confirmed against the drill record.
- Notify: A dedicated decoy-alert channel. Failure to emit raises an internal error metric that alerts to the same channel.
Proof of life
A scheduled synthetic client uses a random decoy identifier at random times from an identity recorded centrally. The central processor alerts when the event does not arrive within the budget.
Pitfalls
- Log sampling, DEBUG-level logging and trace sampling can drop the one event that matters. Send decoy events through a path that is never sampled.
- Asynchronous loggers and batch shippers add minutes of delay. Use a direct emit path for T1 and higher.
- A decoy that responds differently from a real object (timing, error text, status code) gives itself away.
- Crawlers and security scanners hit advertised decoy paths. Decide in advance which sources count.
- Decoy identifiers in plaintext in source code or configuration expose the inventory to anyone with repository access.
Sources: [1]
Alerting principles
The rules behind every pipeline above, and the guidelines that hold whichever alerting platform you use.
DOAR's own private research and deployment experience, written as platform-neutral rules. Not drawn from published sources. Rules marked derived follow from the others.
Stage 1 runs where the decoy lives and forwards only events that reference a decoy identifier. Stage 2 runs centrally and decides, by service and action type, which of those events are alertable. Adding a decoy changes only stage 1.
Why: Filtering by resource at the source means almost nothing leaves the decoy boundary unless a decoy is touched, which keeps cost, noise and data exposure low. Filtering by action centrally keeps the central rules small and stable as decoys are added.
Not for: Decoys that are their own sensor (a listener, an in-application hook), where stage 1 is the decoy's own log. SaaS platforms that only allow central queries, where both stages collapse into one central query.
Alert on actions that need the decoy's specific identifier: reading its content, assuming it, decrypting with it, describing that one resource, invoking it. Do not alert on bulk list or describe-all calls that return every resource of a type, which automation and inventory tools make all the time.
Why: Bulk enumeration is constant background activity and would bury real signals. A call that names the decoy means someone found it and is acting on it.
Not for: Platforms where a list returns contents (Kubernetes list or watch on secrets returns secret data), host files (any read is access), network listeners (any connection is the signal) and SaaS documents (opening is access).
A decoy has no legitimate user, so every event that passes both stages is treated as a true positive and routed as high-confidence. Achieve this by design (internal-only placement, targeted actions), plus a small, governed suppression list. Do not achieve it by tuning thresholds.
Why: The value of deception is high-confidence alerts. Thresholds and scoring bring back the noise deception is meant to avoid, and train responders to ignore decoy alerts.
Not for: Internet-facing honeypots, where background scanning is expected. Route those to analysis (T0/T1), not paging.
Move events with the platform's simplest native event routing (rule, bus, function, notification). Add streaming or queueing systems only when volume requires it.
Why: Simple native routing is cheap, easy to observe and has few parts to fail silently. Decoy event volumes are tiny by design.
Not for: Platforms with no native push path (some SaaS audit logs), where scheduled polling is the honest option.
Run one central processor that adds inventory context to each matched event (which decoy, technique, tier, path), applies the governed suppression list, removes duplicates, and sends the alert. Keep the raw event in the alert.
Why: Responders need context the moment the alert fires. One central point makes suppression auditable and keeps it out of the attacker's reach.
Not for: No decoy class is exempt.
On a schedule, send a labelled synthetic event through the alert path. Less often, make a real touch on a randomly chosen decoy. Raise an alert when the expected proof does not arrive within the latency budget.
Why: A pipeline that has stopped looks exactly like a quiet day. Only proof that is checked for absence turns silent failure into an alert.
Not for: No decoy class is exempt. On sources with hour-scale lag, set the absence window to match.
Stage 1 must run in every scope where an event for the decoy can be recorded: every enabled region, every domain controller, every cluster control plane, every tenant.
Why: Many platforms record an event only in the region or node that served the request. Missing one scope is a silent gap that attackers can cross by accident or on purpose.
Not for: Decoys that exist in one place by construction (a single listener, one host file).
Treat stage 1 filters, log selectors, diagnostic settings and audit rules that name decoys as part of the inventory: restrict who can read them. Do not let decoys stand out by having logging their real neighbours lack. Turn on the same logging for similar real resources, or apply it broadly by policy.
Why: A forwarding rule or data-event selector that lists every decoy identifier is a complete decoy list for anyone who can read monitoring settings. A store that is the only one with access logging stands out.
Not for: Settings that live only in the monitoring boundary or on the control plane where tenants cannot read them.
Decide that an event is a drill centrally, by checking the proof-of-life identity, schedule and a per-run value against the private drill record. Never treat an event as a drill because of content the event carries.
Why: If an attacker learns the drill label or the drill identity's pattern, they could make real access look like a drill and get it silenced.
Not for: No decoy class is exempt.
Generic platform guidelines
Send decoy alerts to their own channel or paging route, separate from general security noise, owned by a named on-call role, and treated as high-confidence. Send pipeline failures (dead-letter queues, function errors, disabled rules, silent sources) to the same channel.
Why: Decoy alerts are rare and high-value. Mixed into a noisy queue they get triaged late or ignored, and a broken pipeline that alerts nowhere stays broken.
The decoy environment's only link to the alerting platform is permission to send events to one destination. It cannot read rules, the suppression list, the inventory, alert history or the drill schedule, and it cannot change processing or notification.
Why: An attacker who controls the decoy environment must not be able to learn what is watched, mute alerts or tune them away.
Treat the inventory, stage 1 filters, log selectors, the covert marker value, the suppression list and the drill schedule as sensitive. Restrict read access to security operators. Keep them out of shared repositories, tickets, chat and public documentation. Do not let monitoring settings make a decoy look different from its real neighbours.
Why: Whoever holds the inventory can avoid every decoy. Most leaks come from monitoring configuration and casual sharing, not from the decoys themselves.
Every alert carries: the decoy (inventory reference), technique ID and tier, actor identity, source address, client or user agent, time, scope (region, host, tenant), the action, the raw event, and a link to the response steps. If enrichment fails or times out, send the raw alert anyway and mark it unenriched.
Why: Responders act on the first alert. Making them look up context costs minutes when an attacker is active, and enrichment that blocks sending turns an enrichment bug into a missed attack.
Each suppression is as narrow as possible (identity plus decoy plus action, never a decoy alone), has an owner, a reason and an expiry date, and is reviewed regularly. Changes are recorded and themselves raise a notification. Fix the noisy source in preference to suppressing it.
Why: The suppression list is the easiest way to blind deception, whether by an attacker or by convenience. Broad or permanent entries quietly turn decoys off.
Set an end-to-end target from touch to notification for each tier, using each signal source's documented delay. Measure the real figure on every proof-of-life run and alert when it is exceeded. Do not promise fast containment (T2 Contain & Collect, T4 Immediate Evict) on sources that lag by tens of minutes or hours. Choose a faster signal or a lower tier.
Why: Detection that arrives after the attacker has finished is evidence, not defence. Unmeasured latency hides slow drift until a real incident shows it up.
Every drill or proof-of-life event is labelled as a drill in the alert and routed so responders cannot mistake it for an attack. The label is decided centrally by matching identity, time window and a per-run value against the private drill record, never by trusting content in the event. Unmatched events that look like drills alert as real. Announce live simulations in advance and record who ran them and when.
Why: Responders must be able to tell an exercise from a compromise, and an attacker must not be able to make real access look like a drill.
For every signal path, expect proof-of-life within a set window and alert when it is missing. Use the platform's absence-capable alerting (metrics with missing data treated as breaching) rather than a log query that only looks for presence.
Why: A stopped pipeline produces no alerts, which looks exactly like no attacks.
Copy every raw decoy event that passes stage 1 into retention in the monitoring boundary, separate from the decoy environment's own logs, kept for at least the incident-investigation period.
Why: Platform audit logs in the decoy environment can be short-lived or tampered with. The independent copy is the evidence when they are gone.
Use the platform's native routing and notification services, with retries and dead-letter handling on every hop. Add streaming or queueing systems only when volume requires it.
Why: Decoy event volume is tiny. Every extra component is another way to fail silently.
Response
Once a decoy fires, malice is no longer in question. The decision is how far to go and how much to learn before acting — five tiers, T0 to T4, trading intelligence against risk, chosen in advance rather than by whoever is on shift.
In this pillar
- The tiers — T0 Silent Log through T4 Immediate Evict
- Escalation in practice — what each tier means for real techniques
- Automation & defaults — what is safe to automate, and where to start
The tiers
Every response tier trades intelligence against risk. Evict immediately and you are safe but blind: you learn nothing about who they are, how they got in, or what else they hold. Watch longer and you learn their objectives and tooling — while an adversary with real access remains inside your estate. The tier model exists so that this decision is made in advance, deliberately, rather than by whoever happens to be on shift.
| T0 | Silent Log
Log to SIEM · Enrich with threat context · Baseline analytics · No human notification |
|---|---|
| T1 | Alert & Observe
SOC alert · Session recording · Correlate signals · 24h monitoring window |
| T2 | Contain & Collect
Isolate compromised identity · Restrict (don't revoke yet) · Capture session metadata · Notify IR team · Preserve forensic evidence |
| T3 | Active Engage
Feed disinformation · Extend deception environment · Deploy additional breadcrumbs · Record full TTP session · Coordinate with threat intel |
| T4 | Immediate Evict
Kill ALL sessions · Revoke ALL credentials · IP ban across all accounts · Snapshot for forensics · Trigger IR plan · Notify legal/compliance |
T0 Silent Log
The interaction is recorded and enriched, and nobody is woken up. Appropriate for low-value signals that matter in aggregate — broad scanning, opportunistic enumeration — where a page per event would train your SOC to ignore the channel.
Actions
- Log to SIEM
- Enrich with threat context
- Baseline analytics
- No human notification
T0 for a real technique
| T1078 Valid Accounts |
Not recommended — valid account abuse warrants human attention |
| T1552.005 Cloud Instance Metadata API |
IMDS probe on honey instance |
| T1496 Resource Hijacking |
CPU spike on honey instance |
When the matrix points here
- Seen / enumerated — decoy F1 F2
- Seen / enumerated — decoy F3
T1 Alert & Observe
A human is told, and the session is watched. The decoy keeps running. This is the default for most first interactions: the alert is high-fidelity, but a single touch rarely justifies disrupting the business.
Actions
- SOC alert
- Session recording
- Correlate signals
- 24h monitoring window
T1 for a real technique
| T1078 Valid Accounts |
Single failed auth attempt against honey account |
| T1552.005 Cloud Instance Metadata API |
IMDS credential request |
| T1496 Resource Hijacking |
Crypto binary detected on honey |
When the matrix points here
- Seen / enumerated — decoy F4 F5
- Accessed or read — decoy F1 F2
- Accessed or read — decoy F3
T2 Contain & Collect
Access is narrowed rather than cut. Restricting instead of revoking keeps the adversary present and observable while limiting what they can reach — and avoids telling them they have been spotted. Evidence preservation starts here.
Actions
- Isolate compromised identity
- Restrict (don't revoke yet)
- Capture session metadata
- Notify IR team
- Preserve forensic evidence
T2 for a real technique
| T1078 Valid Accounts |
Successful auth to honey account from unknown source |
| T1552.005 Cloud Instance Metadata API |
IMDS creds extracted and used |
| T1496 Resource Hijacking |
Active mining on honey compute |
When the matrix points here
- Accessed or read — decoy F4 F5
- Interactive session established — decoy F3
T3 Active Engage
You engage deliberately: feed disinformation, extend the deception environment, keep them busy and recorded. This requires an operator and a plan, and it is the tier most likely to need legal and executive sign-off before it is ever used.
Actions
- Feed disinformation
- Extend deception environment
- Deploy additional breadcrumbs
- Record full TTP session
- Coordinate with threat intel
T3 for a real technique
| T1078 Valid Accounts |
Sustained access with enumeration — track TTPs |
| T1552.005 Cloud Instance Metadata API |
Track SSRF chain and origin |
| T1496 Resource Hijacking |
Monitor mining pool — capture infrastructure |
When the matrix points here
- Credential used elsewhere — decoy F1 F2
- Credential used elsewhere — decoy F3
- Interactive session established — decoy F4 F5
T4 Immediate Evict
Everything stops. Sessions killed, credentials revoked, access blocked, forensic snapshots taken, incident response invoked. Reserved for confirmed destructive intent or an adversary close enough to real assets that observation is no longer defensible.
Actions
- Kill ALL sessions
- Revoke ALL credentials
- IP ban across all accounts
- Snapshot for forensics
- Trigger IR plan
- Notify legal/compliance
T4 for a real technique
| T1078 Valid Accounts |
Honey account used for destructive actions |
| T1552.005 Cloud Instance Metadata API |
IMDS creds used for data access |
| T1496 Resource Hijacking |
Mining spreading to real compute |
When the matrix points here
- Credential used elsewhere — decoy F4 F5
- Destructive action attempted — decoy F1 F2
- Destructive action attempted — decoy F3
- Destructive action attempted — decoy F4 F5
Escalation in practice
The severity matrix gives a starting tier for any decoy. The framework also carries escalation criteria per individual ATT&CK mapping — what specifically counts as a T2 rather than a T3 for that technique:
| T0 | Not recommended — valid account abuse warrants human attention |
|---|---|
| T1 | Single failed auth attempt against honey account |
| T2 | Successful auth to honey account from unknown source |
| T3 | Sustained access with enumeration — track TTPs |
| T4 | Honey account used for destructive actions |
| T0 | IMDS probe on honey instance |
|---|---|
| T1 | IMDS credential request |
| T2 | IMDS creds extracted and used |
| T3 | Track SSRF chain and origin |
| T4 | IMDS creds used for data access |
| T0 | CPU spike on honey instance |
|---|---|
| T1 | Crypto binary detected on honey |
| T2 | Active mining on honey compute |
| T3 | Monitor mining pool — capture infrastructure |
| T4 | Mining spreading to real compute |
Every mapped row (225) has escalation criteria, visible per technique in the ATT&CK matrix. They are operational judgment against the tier definitions above, not evidence claims.
Automation & defaults
T0 and T1 should be fully automated — they are logging and notification, and delay costs you nothing but adds risk. The boundary sits between T1 and T2: everything from T2 upward changes the state of production systems, and an automated action triggered by a misconfigured decoy becomes your outage rather than the adversary's.
The exception is a narrow class of T4 trigger: a honey credential used at all is, by construction, unambiguous. Automating revocation for that specific signal is defensible. Automating eviction on any decoy interaction is not.
Test the full chain against a deliberately triggered decoy, in production, on a schedule. An automated response path that has never fired is an assumption, not a control — and the failure mode is discovering it is broken during a real intrusion.
Choosing a default
| If your organisation… | Default |
|---|---|
| Has no dedicated IR function, or cannot tolerate dwell time | T1 escalating straight to T4 |
| Has a staffed SOC and wants attribution and tooling intelligence | T1 → T2 on second interaction |
| Runs threat intelligence and can dedicate an operator | T2 → T3 with pre-approved rules of engagement |
| Operates safety-critical or regulated systems | T4 on any interaction near production |