deception technology

Deploying Cloud Deception with Decoy Resources

Deploy cloud-native deception across AWS, Azure, and GCP using decoy (honey) resources whose only purpose is to generate a high-fidelity alert the instant an attacker touches them: canary IAM access keys, permission-less decoy users/roles/service principals, honey object-storage buckets, and decoy secrets in Secrets Manager / Key Vault / Secret Manager. Wires detection through CloudTrail + EventBridge, Azure Sentinel honeytoken watchlists + Defender, and GCP Cloud Audit Logs, so any use of a decoy is routed to the SOC with near-zero false positives. Use when protecting cloud accounts and data stores, when an org has only on-prem honeypots and needs cloud coverage, when seeding fake AWS keys to catch credential theft and code-leak exposure, or when detecting cloud reconnaissance and lateral movement. Keywords: cloud deception, canary token AWS, honey S3 bucket, decoy IAM credentials, CloudTrail alert, GuardDuty, Sentinel honeytoken, decoy secret, honey service account, cloud honeypot, breach detection.

awsazurebreach-detectioncanary-tokencloud-deceptioncloudtrailgcphoneytoken
Install this skill
npx skills add mukul975/Anthropic-Cybersecurity-Skills
Framework mappings

When to Use

  • When cloud accounts (AWS/Azure/GCP) hold crown-jewel data or infrastructure and you need a tripwire that fires the moment an attacker who has gained access starts to operate.
  • When the only deception in place is on-prem honeypots, leaving the cloud control plane uninstrumented.
  • When seeding fake credentials to catch credential theft, accidental code-repo leaks, or secrets exposed in build pipelines.
  • When detecting cloud reconnaissance (enumeration of IAM, storage, or secrets) and lateral movement that legitimate users would never perform.
  • When you want detections that survive into incident response with strong fidelity — a touch on a decoy resource almost always means malicious or unauthorized activity.

This is the cloud counterpart to on-prem honeypot/honeytoken/canary-token deployment skills. For program strategy and how these Activities map to adversary engagement goals, use designing-adversary-engagement-with-mitre-engage.

Prerequisites

  • Cloud admin/IAM permissions to create decoy principals, storage, secrets, and detection wiring, ideally in a dedicated deployment role with least privilege.
  • Cloud audit logging already enabled: AWS CloudTrail (multi-region, with management and relevant data events), Azure Activity log + Microsoft Entra audit/sign-in logs, GCP Cloud Audit Logs (Admin Activity always on; Data Access enabled where needed).
  • A SIEM/alert sink: SNS topic, Microsoft Sentinel workspace, or GCP Pub/Sub + Monitoring, with routing to the SOC.
  • A naming and tagging convention that is plausible to an attacker but unambiguous to defenders internally (e.g., realistic names, plus an internal deception=true tag/label kept out of attacker-visible metadata).
  • Decoy principals must be permission-less (explicit deny-all). The value is the alert, never the access. A decoy that grants real privilege is a liability, not a control.

Workflow

1. Decide what to mimic

Pick decoys that match how your attackers operate: leaked AWS keys (credential theft), an "admin" S3 bucket (data discovery), a prod-db-password secret (secrets harvesting), a privileged-looking service account (cloud lateral movement). Place credential decoys where harvesting tools look: env files, CI variables, code comments, an internal wiki.

2A. AWS — canary access keys on a permission-less user

Create a decoy IAM user with an explicit deny-all policy, then issue an access key to plant:

aws iam create-user --user-name svc-backup-prod --tags Key=deception,Value=true
aws iam put-user-policy --user-name svc-backup-prod \
  --policy-name deny-all \
  --policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Deny","Action":"*","Resource":"*"}]}'
aws iam create-access-key --user-name svc-backup-prod   # plant the returned AccessKeyId/Secret

Any use of this key appears in CloudTrail (even denied calls, which still log AccessDenied). Wire an EventBridge rule on CloudTrail to alert:

aws events put-rule --name decoy-key-used \
  --event-pattern '{"detail":{"userIdentity":{"userName":["svc-backup-prod"]}}}'
aws events put-targets --rule decoy-key-used \
  --targets "Id"="1","Arn"="arn:aws:sns:us-east-1:111111111111:soc-deception-alerts"

2B. AWS — honey S3 bucket

Create a believable bucket, enable object-level data events, and alert on any read/list:

aws s3api create-bucket --bucket acme-prod-db-backups-2026 --region us-east-1
aws s3api put-bucket-tagging --bucket acme-prod-db-backups-2026 \
  --tagging 'TagSet=[{Key=deception,Value=true}]'
# Ensure CloudTrail captures S3 data events for this bucket, then alert on GetObject/ListBucket
aws events put-rule --name decoy-bucket-access \
  --event-pattern '{"detail":{"eventSource":["s3.amazonaws.com"],"requestParameters":{"bucketName":["acme-prod-db-backups-2026"]}}}'

2C. AWS — decoy secret

aws secretsmanager create-secret --name prod/db/master-password \
  --secret-string '{"username":"dbadmin","password":"DECOY-DO-NOT-USE"}' \
  --tags Key=deception,Value=true
# Alert on GetSecretValue for this secret via EventBridge -> SNS

3A. Azure — honeytoken watchlist + decoy service principal

Microsoft Sentinel natively supports honeytokens via a Watchlist of the HoneyTokens template; tagged decoy accounts/secrets raise analytics alerts on use. Create a permission-less decoy app registration / service principal, then add its identifiers to the HoneyTokens watchlist and enable the related analytics rules. Microsoft Defender for Cloud and Entra ID Protection surface anomalous sign-ins to the decoy identity.

3B. Azure — honey storage + Key Vault decoy secret

Create a decoy Storage account and Key Vault, enable diagnostic logging to the Sentinel workspace, store a decoy secret, and write an analytics rule that fires on any data-plane read of the decoy resources.

4A. GCP — decoy service account + honey GCS bucket

Create a service account with no role bindings (permission-less), generate a key to plant, and alert on its use via Cloud Audit Logs:

gcloud iam service-accounts create svc-billing-export \
  --display-name="billing-export"
gcloud iam service-accounts keys create decoy-key.json \
  --iam-account=svc-billing-export@PROJECT.iam.gserviceaccount.com   # plant this key
gsutil mb -b on gs://acme-finance-exports-2026

Create a log-based metric + alerting policy in Cloud Monitoring that triggers on any audit-log entry where the principal is the decoy service account or the resource is the honey bucket.

5. Centralize and de-duplicate

Route all clouds' decoy alerts to one SOC pipeline. Tag each alert as DECEPTION/high-fidelity so it bypasses normal noise filtering and triggers an IR playbook rather than a triage queue.

6. Validate (red-team the decoys)

Have an authorized tester use each decoy (read the bucket, call with the key, fetch the secret) and confirm an alert lands end-to-end within target latency. A decoy you have not tested is assumed broken.

7. Maintain realism and rotate

Refresh decoy names, secrets, and pocket-litter periodically so they age with the real environment. Track every decoy in an inventory so they are never mistaken for real assets during audits or cleanups.

Key Concepts

Concept Definition
Decoy / honey resource A cloud object created solely to be touched by an attacker; no legitimate user has any reason to use it.
Canary access key A planted credential whose use generates an audit-log event; carries deny-all permissions.
High-fidelity alert A near-zero-false-positive signal because legitimate workflows never reference the decoy.
Permission-less principal A decoy IAM user/role/service principal/service account with explicit deny-all or no role bindings.
Data event Cloud audit logging of object/data-plane access (e.g., S3 GetObject), required to detect storage decoys.
Pocket litter Plausible supporting artifacts (fake configs, env files, wiki entries) that make a decoy credible.
Decoy inventory The authoritative internal record distinguishing decoys from real assets.

Tools & Systems

  • AWS — IAM (decoy users/roles), S3 (honey buckets, data events), Secrets Manager / SSM Parameter Store (decoy secrets), CloudTrail, EventBridge, SNS/Lambda, GuardDuty (correlate anomalous use).
  • Azure — Microsoft Entra ID (decoy app registrations / service principals), Storage / Key Vault decoys, Microsoft Sentinel HoneyTokens watchlist and analytics rules, Microsoft Defender for Cloud, Entra ID Protection.
  • GCP — IAM service accounts (decoys), Cloud Storage (honey buckets), Secret Manager (decoy secrets), Cloud Audit Logs, log-based metrics + Cloud Monitoring alerting, Pub/Sub.
  • Open-source / managed honeytoken systems — Canarytokens (https://canarytokens.org offers AWS API key tokens), Thinkst Canary, SpaceSiren / SpaceCrab (self-hosted AWS honey-token frameworks).
  • SIEM/SOAR — to centralize alerts across clouds and drive an IR playbook on any decoy hit.

Common Scenarios

  • Credential-theft / code-leak detection. Plant a canary AWS key in CI variables, an env file, and a private repo. Any external use (even from a leaked public push) fires within minutes.
  • Crown-jewel data store. Stand up a honey "backups" bucket next to the real one; attackers enumerating storage hit the decoy first and reveal themselves.
  • Cloud lateral movement. A permission-less decoy service principal that "looks" privileged catches adversaries assuming roles during pivoting.
  • Secrets harvesting. Decoy entries in Secrets Manager / Key Vault / Secret Manager detect tools scraping the secrets store.
  • Migrating from on-prem-only deception. Mirror the existing on-prem decoy strategy into the cloud control plane so coverage follows workloads.

Output Format

Produce a Cloud Deception Deployment Record using assets/template.md, containing:

  1. Decoy inventory — per decoy: cloud, type, plausible name, real placement location of any planted credential, internal deception tag/label, owner.
  2. Detection wiring — per decoy: audit-log source → rule/pattern → alert sink → IR playbook reference, with the target alert latency.
  3. Least-privilege proof — evidence each decoy principal is deny-all / no-role-binding.
  4. Validation results — date tested, who tested, end-to-end latency observed, pass/fail.
  5. Maintenance plan — rotation cadence and review owner.

Use scripts/process.py to render the deployment record and a per-decoy detection checklist from a decoy-inventory JSON, and to flag decoys missing detection wiring or validation.

Source materials

References and resources

Everything below is rendered for inspection. Script files are read-only and never run.

References 1

standards.md4.1 KB

Cloud Deception — Standards & Reference

Detection foundations (audit logging is mandatory)

Cloud deception only works if a decoy touch is logged. Confirm these before deploying.

AWS

  • CloudTrail — management events plus data events (S3 object-level, Lambda invoke, etc.) for any storage/secret decoys. Multi-region trail recommended.
  • EventBridge — pattern-match CloudTrail events on userIdentity.userName, eventSource, or requestParameters.bucketName and target SNS/Lambda.
  • GuardDuty — correlates anomalous credential/API behavior; useful to enrich a decoy hit.
  • Note: even denied API calls by a deny-all decoy principal are recorded in CloudTrail as AccessDenied, so the alert fires regardless of granted permission.

Azure / Microsoft

  • Azure Activity log + Microsoft Entra ID audit and sign-in logs streamed to a Log Analytics / Microsoft Sentinel workspace.
  • Microsoft Sentinel HoneyTokens — built-in watchlist template; decoy identifiers added to the watchlist drive analytics rules that alert on use.
  • Microsoft Defender for Cloud and Entra ID Protection — surface anomalous access to decoy identities.
  • Enable diagnostic settings on decoy Storage accounts and Key Vaults to capture data-plane reads.

GCP

  • Cloud Audit Logs — Admin Activity logs are always on; enable Data Access logs for the services hosting decoys (Cloud Storage, Secret Manager, IAM).
  • Log-based metrics + Cloud Monitoring alerting policies — trigger on audit entries where protoPayload.authenticationInfo.principalEmail is the decoy service account or the resource is the honey bucket.
  • Pub/Sub sink to forward to a SIEM.

MITRE D3FEND — Deceive tactic mappings

D3FEND technique Cloud decoy realization
Decoy User Credential Canary IAM access key / decoy app secret / decoy SA key
Decoy Network Resource Honey S3 / GCS / Azure Storage bucket
Decoy Object Decoy secret in Secrets Manager / Key Vault / Secret Manager
Decoy Persona Permission-less decoy IAM user / service principal / service account
Decoy Session Token Planted temporary credential / SAS token

MITRE ATT&CK techniques detected

Technique Detected by decoy
T1078 / T1078.004 Valid Accounts (Cloud) Canary key / decoy principal use
T1552 / T1552.001 Unsecured Credentials Decoy secret read; planted credential use
T1580 Cloud Infrastructure Discovery Enumeration touching decoy principals/resources
T1619 Cloud Storage Object Discovery List on honey bucket
T1530 Data from Cloud Storage Object GetObject on honey bucket

NIST CSF 2.0 alignment

CSF 2.0 ID Relevance
DE.CM-01 Networks/environments monitored to find adverse events
DE.CM-06 External service provider (cloud) activity monitored
DE.AE-02 Potentially adverse events analyzed — decoy alert triage
ID.RA-01 Vulnerabilities/exposures identified — informs decoy placement
RS.MA-01 Incident management — decoy hit invokes the IR playbook

Tooling references

  • Canarytokens (AWS API key token): https://canarytokens.org
  • Thinkst Canary: https://canary.tools
  • SpaceSiren (self-hosted AWS honey tokens, serverless): open-source
  • Microsoft Sentinel HoneyTokens watchlist: Microsoft Learn — "Deploy decoys/honeytokens with Sentinel"
  • AWS CloudTrail data events: AWS docs — "Logging data events"
  • GCP Cloud Audit Logs: Google Cloud docs — "Cloud Audit Logs overview"

Operating principles

  • Deny-all decoys only. Decoy principals must carry an explicit deny-all policy (AWS) or no role bindings (GCP) / no privileged roles (Azure). The control's value is the alert, never access.
  • Keep an internal decoy inventory separate from attacker-visible metadata so audits and clean-ups never delete a tripwire by accident, and real assets are never mistaken for decoys.
  • Validate end-to-end (red-team each decoy) and record observed alert latency. Untested decoys are assumed non-functional.
  • Mark deception alerts high-fidelity so they bypass routine noise filtering and go straight to an IR playbook.

Scripts 1

process.py5.0 KB
Display-only source. This catalog never executes bundled scripts.
#!/usr/bin/env python3
"""
Cloud deception deployment validator.

Reads a decoy-inventory JSON, checks each decoy for the controls that make a
cloud decoy trustworthy (detection wiring, deny-all/least-privilege, validation,
internal tagging), renders a Cloud Deception Deployment Record, and exits non-zero
if any decoy is missing a required control.

Usage:
    python process.py --inventory decoys.json --out record.md

decoys.json format:
    {
      "account": "acme-prod (AWS 1111...)",
      "decoys": [
        {
          "name": "svc-backup-prod",
          "cloud": "aws",
          "type": "canary_access_key",
          "placement": "CI variables + private repo .env",
          "deny_all": true,
          "detection": {"source": "CloudTrail", "rule": "decoy-key-used", "sink": "sns:soc-deception-alerts", "playbook": "IR-CLOUD-07"},
          "validated": {"date": "2026-05-20", "by": "redteam", "latency_sec": 90, "passed": true},
          "internal_tag": "deception=true"
        }
      ]
    }
"""
import argparse
import json
import sys
from datetime import date

REQUIRED = ["name", "cloud", "type", "placement"]
VALID_CLOUDS = {"aws", "azure", "gcp"}


def check_decoy(d):
    """Return list of issues for one decoy."""
    issues = []
    for k in REQUIRED:
        if not d.get(k):
            issues.append(f"missing required field '{k}'")
    if d.get("cloud") and d["cloud"].lower() not in VALID_CLOUDS:
        issues.append(f"unknown cloud '{d.get('cloud')}'")

    det = d.get("detection") or {}
    for k in ("source", "rule", "sink"):
        if not det.get(k):
            issues.append(f"detection wiring missing '{k}' (decoy is blind)")
    if not det.get("playbook"):
        issues.append("no IR playbook reference for the alert")

    # Credential/principal decoys must be deny-all / least privilege.
    cred_types = {"canary_access_key", "decoy_principal", "decoy_service_account",
                  "decoy_service_principal", "decoy_iam_user"}
    if d.get("type") in cred_types and not d.get("deny_all"):
        issues.append("credential/principal decoy is not marked deny_all (liability risk)")

    val = d.get("validated") or {}
    if not val.get("passed"):
        issues.append("not validated end-to-end (assume non-functional)")
    if not d.get("internal_tag"):
        issues.append("no internal deception tag/label (audit-cleanup risk)")
    return issues


def render(inv, results):
    lines = [f"# Cloud Deception Deployment Record",
             f"\n_Account: {inv.get('account', 'UNKNOWN')} — generated {date.today().isoformat()}_\n",
             "## 1. Decoy inventory & detection wiring",
             "| Decoy | Cloud | Type | Placement | Detection (source→rule→sink) | Playbook | Validated | Status |",
             "|---|---|---|---|---|---|---|---|"]
    for d, issues in results:
        det = d.get("detection") or {}
        wiring = f"{det.get('source','?')}{det.get('rule','?')}{det.get('sink','?')}"
        val = d.get("validated") or {}
        vstr = f"{val.get('date','-')} ({val.get('latency_sec','?')}s)" if val.get("passed") else "NO"
        status = "OK" if not issues else f"{len(issues)} issue(s)"
        lines.append(f"| {d.get('name','?')} | {d.get('cloud','?')} | {d.get('type','?')} | "
                     f"{d.get('placement','?')} | {wiring} | {det.get('playbook','-')} | {vstr} | {status} |")

    problem = [(d, i) for d, i in results if i]
    if problem:
        lines.append("\n## 2. Issues to remediate before relying on these decoys")
        for d, issues in problem:
            lines.append(f"\n**{d.get('name','?')}** ({d.get('cloud','?')}):")
            for it in issues:
                lines.append(f"- {it}")
    else:
        lines.append("\n## 2. Issues\nNone — all decoys have detection wiring, least privilege, and validation.")

    lines.append("\n## 3. Maintenance")
    lines.append("- Rotation cadence: TBD  ·  Review owner: TBD")
    lines.append("- Keep this record separate from attacker-visible metadata.")
    return "\n".join(lines)


def main():
    p = argparse.ArgumentParser(description="Cloud deception deployment validator")
    p.add_argument("--inventory", required=True, help="Path to decoy-inventory JSON")
    p.add_argument("--out", help="Output markdown path (default: stdout)")
    args = p.parse_args()

    with open(args.inventory) as f:
        inv = json.load(f)

    decoys = inv.get("decoys", [])
    results = [(d, check_decoy(d)) for d in decoys]
    total_issues = sum(len(i) for _, i in results)
    healthy = sum(1 for _, i in results if not i)

    print(f"{len(decoys)} decoy(s): {healthy} healthy, {total_issues} total issue(s).",
          file=sys.stderr)

    out = render(inv, results)
    if args.out:
        with open(args.out, "w") as f:
            f.write(out + "\n")
        print(f"Wrote deployment record -> {args.out}", file=sys.stderr)
    else:
        print(out)

    # Non-zero exit if any decoy has issues, so this can gate a pipeline.
    sys.exit(1 if total_issues else 0)


if __name__ == "__main__":
    main()

Assets 1

template.mdtext/markdown · 2.3 KB
Keep exploring