How we built a procedural engine that learns your real cloud environment, generates decoy environments indistinguishable from production, and converts every attacker interaction into signal.
In the myth, Daedalus built the Labyrinth of Knossos so well that he nearly couldn’t escape it himself. The corridors looked real. The paths felt purposeful. And the deeper you went, the harder it became to tell which direction led out.
That’s the design constraint we gave ourselves when building Knossos for Praetorian Guard: generate cloud infrastructure so realistic that an attacker who lands inside it doesn’t realize they’ve already lost. Every API call they make, every role they assume, every secret they pull from Parameter Store, all of it is being recorded, scored, and fed back into the system that built the trap.
The idea isn’t new. Honeypots have existed for decades. But the gap between a traditional honeypot and what a competent attacker expects to find in a real AWS account is enormous. Drop a single canary token in an otherwise empty VPC and you’ve told the attacker two things: you’re running deception, and there’s nothing interesting here. They pivot, and you’ve burned your one shot.
Knossos takes a fundamentally different approach. Rather than scattering individual lures and hoping someone trips one, it generates entire environments — complete with VPCs, subnets, EC2 instances, RDS databases, Lambda functions, S3 buckets, IAM roles, and Secrets Manager entries — all procedurally constructed from a profile of the customer’s actual infrastructure. The result is a decoy account that looks, feels, and behaves like something the organization would have built.
The Problem with Static Deception
Most deception tools fall into one of two categories: they’re either too simple to fool anyone competent, or they’re so labor-intensive to configure that nobody deploys them at scale.
A hand-crafted honeypot can be convincing, but it requires someone who understands both the target environment and the adversary’s perspective to build it. That person needs to create realistic naming conventions, plausible resource relationships, believable IAM policies, and a network topology that makes sense. Then they need to wire up alerting. Then they need to maintain all of it as the real environment evolves. For a single decoy environment, that’s a week of work. For ten, it’s a quarter.
On the other end, automated canary tools generate tokens and credentials that can be scattered across existing infrastructure. These are useful, but they’re point sensors, not environments. An attacker who finds an AWS access key in an S3 bucket and uses it to call sts:GetCallerIdentity triggers an alert. But if the key leads to an empty account with no resources, no history, and no naming conventions, the attacker knows they’ve hit a trap. They stop, they clean up, and they go quiet. The alert fired, but you learned nothing about their tooling, their objectives, or their lateral movement patterns.
What we wanted was something in between: the realism of a hand-crafted environment with the scalability of automation. That meant teaching a system to understand what a real environment looks like — and then generating convincing fakes from that understanding.
The Architect: How Daedalus Learns Your Environment
The core of Knossos is an orchestrator we call Daedalus. Its job is to take a customer’s real cloud infrastructure and reverse-engineer a style profile — a statistical model of how that organization builds and operates in the cloud. Not what they built, but how they build.
The distinction matters. We don’t clone resources. We don’t snapshot configurations. We extract patterns: naming conventions, tag vocabularies, CIDR allocation strategies, IAM policy structures, instance family preferences, region distribution, and even behavioral signals like deployment cadence and API usage patterns.
The Mining Pipeline
When a customer triggers inference, Daedalus kicks off a multi-stage pipeline. The first stage is extraction: a provider-specific component reads the cloud resources that Guard has already discovered through its existing integrations. No additional API calls to the customer’s account are required — the platform already has what it needs.
The extracted resources feed into the Miner, which is where things get interesting. The Miner runs a multi-phase algorithm over every resource name in the environment:
- Delimiter detection — identify structural separators (
-,_,/, camelCase boundaries) - Tokenization — split names into positional segments
- Classification — determine whether each position is a constant, a vocabulary draw, or a sequence counter
- Correlation analysis — detect cross-position dependencies (e.g., when “prod” in position one predicts “api” in position two)
- Confidence scoring — assess how well the inferred pattern fits the observed names
The output is a naming pattern per resource type: a template like {env}-{service}-{component}-{seq:02d} with vocabulary sets and frequency distributions for each variable position. If the organization names their production instances prod-api-web-01 through prod-api-web-12, the miner captures that pattern — including the fact that “prod” always appears in position one, “api” in position two correlates with “web” or “worker” in position three, and the sequence counter is zero-padded to two digits.
The Miner doesn’t just learn names. It learns the grammar of naming — and that grammar is what makes generated resources pass the sniff test.
Beyond naming, the inference pipeline captures tag patterns (required keys, common values), network topology (VPC-to-subnet relationships, peering structures, CIDR allocation preferences), compute profiles (which instance families and sizes are actually in use), security posture (IAM conventions, permission boundary usage, rotation cadence), and toolchain fingerprints (Terraform state patterns, CI/CD artifacts, monitoring stack).
All of this gets merged into a versioned style profile — a data structure that represents everything Daedalus knows about how an organization operates in the cloud. The profile is stored and updated incrementally as new inference runs incorporate fresh data.

Building the Labyrinth: Procedural Decoy Environment Generation
A style profile tells Daedalus what to build. The Generator decides how to assemble it into something an attacker would want to explore.
The generation pipeline doesn’t randomly scatter resources. It constructs environments around attack paths — deliberate sequences of discoverable breadcrumbs that lead an attacker deeper into the deception. Each path has a defined goal (data exfiltration, privilege escalation, compute compromise, lateral movement), a configurable depth, and multiple independent routes to reach the objective.
The engine uses backward-chaining to plan these paths: start from the terminal objective (say, an RDS database with “customer” in the name), then work backwards through the lure catalog to build a plausible chain of discoveries that leads there. A typical path might look like:

Each step in the chain is a lure — a resource that’s intentionally misconfigured in a specific, discoverable way. But the lure doesn’t exist in isolation. It’s embedded in a scaffold of supporting resources (the VPC it lives in, the subnet it’s attached to, the security groups that govern its traffic) and surrounded by camouflage — additional resources that match the ratio distribution of the real environment.
If the customer’s production account has a 3:1 ratio of private subnets to public subnets, the decoy environment maintains that ratio. If they tend to run three security groups per VPC, so does the decoy. The camouflage layer density is controlled by a single scale parameter, so customers can tune the tradeoff between realism and cost.
The Seven Stages
Generation runs through seven discrete stages, each building on the output of the previous one:
| Stage | What It Does |
|---|---|
| Path Planning | Backward-chain from goals to ordered lure sequences |
| Budgeting | Compute resource counts from paths + camouflage ratio |
| Scaffolding | Build base topology — VPCs, subnets, route tables, IAM layers |
| Embedding | Place lures at specific positions in the topology |
| Dressing | Generate names, tags, and properties from the style profile |
| History | Generate synthetic audit log entries for anti-fingerprinting |
| Validation | Run anti-fingerprint validators, score realism |
The history stage deserves a closer look. An environment full of resources with no audit trail is a dead giveaway. So the generator synthesizes historical audit log entries — resource creation events, policy modifications, configuration changes — backdated and distributed across a realistic timeline derived from the style profile’s behavioral data. Timestamps are biased toward the organization’s observed peak hours, with a reduction factor applied for weekends and quiet periods. The result is a creation history that looks like it accumulated organically over weeks or months, not generated in a single pass.
Determinism and Reproducibility
The entire generation pipeline is deterministic. Given the same seed and the same style profile, you get the identical environment every time. This isn’t academic — it matters for auditability. A security team that generated a decoy environment six months ago can reproduce exactly what was deployed, compare it against what the attacker interacted with, and verify that no drift occurred.

From Manifest to Terraform
The generator produces a provider-agnostic representation of every resource, relationship, breadcrumb trail, and isolation policy in the decoy environment. This intermediate representation describes what should exist without committing to how it gets deployed.
Translation to infrastructure-as-code happens in a provider-specific emission layer that converts the internal representation into Terraform HCL, handling reference resolution (a security group that references a VPC ID becomes a proper Terraform resource reference), dependency ordering, and policy rendering for IAM roles and permission boundaries.
The emitter also generates the alerting infrastructure: event rules and API destination callbacks that fire when an attacker touches a lure resource. These events flow back to Guard for triage — more on that in a moment.
Cost estimation runs against live cloud pricing data (with a static fallback table for offline estimation), so customers see projected monthly spend before deploying anything. The resources that form the attack paths — including any compute instances that serve as lure targets — are always present; they’re what makes the deception work. What’s tunable is the camouflage layer: the padding resources that make lures harder to distinguish from the crowd. A single scale parameter controls camouflage density, letting customers dial in the tradeoff between realism and cost.
Defense in Depth: Why We're Not Worried About Friendly Fire
Deploying deliberately misconfigured infrastructure — even fake infrastructure — in a customer’s cloud account raises an obvious question: what if the decoy causes real damage?
Knossos enforces three isolation layers by default:
- Network isolation — the decoy environment lives in a dedicated VPC with deny-all NACLs and no peering connections to production VPCs. Traffic cannot flow between decoy and real infrastructure at the network level.
- Permission boundary — every IAM role in the decoy environment is capped by a permission boundary that prevents any action outside the decoy’s own resources. An attacker who escalates to “admin” within the decoy can’t reach production.
- Service Control Policy — Knossos generates an SCP document with the appropriate resource constraints, to be attached from the management account at the account or OU level. That way the decoy environment is constrained from an upper layer — even if a permission boundary is somehow misconfigured, the SCP contains the blast radius.
The first two layers are baked directly into the generated Terraform. The SCP is emitted as a separate policy document. Knossos generates it. You apply it. To weaken Knossos isolation, you’d have to actively bypass all three isolation layers.
Turning Attackers into Intelligence
Deception without telemetry is just wasted infrastructure. The real value of Knossos isn’t the labyrinth itself — it’s what you learn from watching someone navigate it.
Every lure in a Knossos environment is wired to emit an event when triggered. An attacker calls GetSecretValue on a Secrets Manager entry? Event. They assume an overprivileged role? Event. They list objects in a decoy S3 bucket? Event. These events flow through EventBridge to Guard’s ingestion endpoint, where they’re persisted and correlated with the manifest that generated the environment.
Because the manifest records exactly which resource is a lure, which breadcrumb trail it belongs to, and what position it occupies in the attack path, the telemetry isn’t just “someone accessed a resource.” It’s “an attacker followed the credential_leak → overprivileged_role → accessible_secret path, reached step 3 of 4, and spent 47 minutes between steps 2 and 3.” That level of granularity — which breadcrumbs were followed, in what order, and how long each step took — is the difference between an alert and actual intelligence.
The Feedback Loop
Here’s where it gets interesting. The telemetry system doesn’t just report — it learns.
The telemetry system computes effectiveness scores for each lure type across all deployed environments. It tracks interaction rate (what fraction of deployments saw this lure type get touched), mean dwell time (how long attackers spend at each lure), depth reached (how many breadcrumb steps they follow), and escape rate (how quickly they recognize the deception and bail).
A lure’s effectiveness score is simply InteractionRate Ă— (1 - EscapeRate). High score means the lure attracts attackers and retains them. Low escape rate means they don’t realize they’ve been had.
These scores flow back into the style profile as lure weights. The next time Daedalus generates an environment for that customer, the path planner biases toward lure types that have proven effective and away from those that attackers consistently recognize. Over time, each customer’s deception infrastructure adapts to the actual threat landscape they face.

Validating Realism
Everything described in the Daedalus section — pattern-derived naming, correlated vocabularies, realistic tag sets, structural consistency — exists to solve one problem: making the generated environment pass a competent attacker’s sniff test. But claiming realism and verifying it are different things.
The final generation stage runs a battery of validators against the output: checking that names follow the inferred grammar, that resource distributions match the profile, that the topology has the right structural ratios, and that no obvious tells (sequential IDs, clustered timestamps, implausible policy scoping) survive. The result is a realism score stored alongside the manifest, with individual violations surfaced and explained.
We’re transparent about what the validators catch and what they don’t — no deception system is perfect, and pretending otherwise would be doing a disservice to the customers relying on it.
Where We're Going
The best labyrinth isn’t the one with the most walls. It’s the one where the walls look like corridors.Knossos is available now as part of Praetorian Guard. To learn more about deploying deception infrastructure in your environment, reach out to your Praetorian engagement team or visit praetorian.com.