MITRE ATLAS (Adversarial Threat Landscape for Artificial-Intelligence Systems) is a public knowledge base of how adversaries attack systems that contain AI, organised the way MITRE ATT&CK organises attacks on ordinary IT: tactics for the attacker's goals, techniques for how they achieve them, mitigations, and case studies of real incidents and red-team exercises. For a team shipping a chatbot, a retrieval pipeline or a tool-using agent, it supplies a shared vocabulary: a finding tagged AML.T0051.001 means the same thing to your red team, your detection engineers and an auditor.
Most introductions stop at the matrix picture. This one goes further: how the current release is structured, how to read its machine-readable data correctly, which techniques matter for LLM applications, how to turn a case study into a test scenario, and how to measure detection and mitigation coverage without fooling yourself. Figures quoted here were counted from the ATLAS 2026.09 data release, published in September 2026. ATLAS ships monthly content releases, so expect the numbers to have moved by the time you read this.
What ATLAS is and is not
ATLAS describes adversary behaviour. It does not rank risks, and it does not tell you how to govern an AI programme. The OWASP Top 10 for LLM Applications ranks the most common application weaknesses and is good for prioritising; the NIST AI Risk Management Framework describes governance and risk processes. ATLAS sits beside them as the catalogue you tag attacks, tests and detections with.
The 2026.09 release contains 16 tactics, 120 techniques with 88 sub-techniques under them, 40 mitigations and 73 case studies, of which 50 are labelled exercises and 23 incidents. Every technique carries a maturity label: Feasible (shown in research or proof of concept), Demonstrated (shown to work against a realistic target) or Realized (seen used by real adversaries). Across techniques and sub-techniques the split is 101 Realized, 83 Demonstrated and 24 Feasible. Techniques also list platforms, so you can filter, for example, to the ones tagged for generative or agentic AI.
The 16 tactics in matrix order
Fourteen tactics share their names with ATT&CK; two exist only in ATLAS. AML.TA0000 AI Model Access covers how an attacker gets to the model at all, from a public inference API to a copy of the weights. AML.TA0001 AI Attack Adaptation covers preparing an AI-specific attack, such as crafting adversarial data, building a proxy model or iterating on a prompt until it works; earlier releases used a staging name for this tactic, so old reports may not match current names even when the ID does. The matrix order, taken from the data file, is:
| # | ID | Tactic | LLM-application example |
|---|---|---|---|
| 1 | AML.TA0002 | Reconnaissance | Finding which public portals feed an agent |
| 2 | AML.TA0003 | Resource Development | Building payloads, accounts, poisoned documents |
| 3 | AML.TA0001 | AI Attack Adaptation | Crafting and testing an injection prompt |
| 4 | AML.TA0004 | Initial Access | Supply chain compromise, prompt via public app |
| 5 | AML.TA0000 | AI Model Access | Using the product's inference API |
| 6 | AML.TA0005 | Execution | Prompt injection, direct or indirect |
| 7 | AML.TA0006 | Persistence | RAG poisoning, agent memory poisoning |
| 8 | AML.TA0012 | Privilege Escalation | Agent tool invocation, jailbreak |
| 9 | AML.TA0007 | Defense Evasion | Jailbreak, prompt obfuscation |
| 10 | AML.TA0013 | Credential Access | Secrets reachable by tools or context |
| 11 | AML.TA0008 | Discovery | Probing the system prompt or tool list |
| 12 | AML.TA0015 | Lateral Movement | Using one agent's tools to reach another system |
| 13 | AML.TA0009 | Collection | Gathering data through agent tools |
| 14 | AML.TA0014 | Command and Control | Steering an agent via planted instructions |
| 15 | AML.TA0010 | Exfiltration | Leaking data through tool calls or rendered output |
| 16 | AML.TA0011 | Impact | Denial of service, cost harvesting, external harms |
Techniques that matter for LLM applications
A handful of techniques account for most LLM application findings. The tactic column shows the tactics each technique achieves in the 2026.09 data; several techniques serve more than one goal.
| ID | Technique | Tactic(s) | Maturity |
|---|---|---|---|
| AML.T0051 (.000 / .001 / .002) | LLM Prompt Injection: Direct, Indirect, Triggered | Execution | Realized |
| AML.T0054 | LLM Jailbreak | Defense Evasion, Privilege Escalation | Realized |
| AML.T0053 | AI Agent Tool Invocation | Execution, Privilege Escalation, Lateral Movement | Demonstrated |
| AML.T0086 | Exfiltration via AI Agent Tool Invocation | Exfiltration | Realized |
| AML.T0070 | RAG Poisoning | Persistence | Demonstrated |
| AML.T0080 | AI Agent Context Poisoning | Persistence | Realized |
| AML.T0056 | Extract LLM System Prompt | Exfiltration | Feasible |
| AML.T0057 | LLM Data Leakage | Exfiltration | Demonstrated |
| AML.T0068 | LLM Prompt Obfuscation | Defense Evasion | Realized |
| AML.T0010 | AI Supply Chain Compromise | Initial Access | Realized |
| AML.T0034 | Cost Harvesting | Impact | Feasible |
The maturity column is a useful sanity check on your own threat model. If your top risk is rated Feasible in ATLAS and you are ignoring something rated Realized, you should be able to explain why.
The data model behind the matrix
ATLAS is published as YAML in the mitre-atlas/atlas-data repository on GitHub, and the website is generated from the same data. Two version numbers matter: the content version, such as 2026.09, and the format version, currently 6.0.0, under dist/v6/. Older layouts live under dist/legacy/. There is a trap in the file names: dist/v6/ATLAS-latest.yaml is not the data. It is an 18-byte file whose content is the name of the current release file. A loader that fetches it and parses the result gets a string, not a matrix. Resolve the pointer once, then pin the versioned file.
In format 6 the top level has tactics, techniques, mitigations and case-studies, each a mapping keyed by ID, plus a relationships mapping keyed by source ID. The links between objects live only in that relationships block, in five types:
achieves: technique to tactic. A technique has no tactic field of its own.specializes: sub-technique to parent technique.mitigates: mitigation to technique.employs: case study to technique, with the tactic used, astep-idand aleads-tolist that turns a case study into a directed graph of steps.sequences: the matrix to its tactics, which gives the column order.
A loader that only reads the technique objects will find no tactic or mitigation information at all, and will conclude, wrongly, that the data is incomplete.
A pinned loader in Python
The loader below pins a release, builds the indexes you need, and validates tags. It requires PyYAML.
import collections, pathlib, urllib.request
import yaml
BASE = "https://raw.githubusercontent.com/mitre-atlas/atlas-data/main/dist/v6/"
PINNED = "ATLAS-2026.09.yaml" # pin; ATLAS-latest.yaml only names the current file
def fetch(dest="atlas.yaml"):
path = pathlib.Path(dest)
if not path.exists():
urllib.request.urlretrieve(BASE + PINNED, path)
return path
class Atlas:
def __init__(self, path):
d = yaml.safe_load(pathlib.Path(path).read_text(encoding="utf-8"))
self.version = d["collection"]["version"]
self.tactics, self.techniques = d["tactics"], d["techniques"]
self.mitigations, self.cases = d["mitigations"], d["case-studies"]
rel = d["relationships"]
def targets(src, kind):
return [x["target"] for x in rel.get(src, {}).get(kind, [])]
self.order = targets("ATLAS-matrix", "sequences")
self.tactics_of = {t: targets(t, "achieves") for t in self.techniques}
self.parent = {t: next(iter(targets(t, "specializes")), None) for t in self.techniques}
self.mitigated_by = collections.defaultdict(list)
for m in self.mitigations:
for t in targets(m, "mitigates"):
self.mitigated_by[t].append(m)
self.steps = {cs: rel.get(cs, {}).get("employs", []) for cs in self.cases}
def check(self, tag):
if tag not in self.techniques:
raise KeyError(f"{tag} is not a technique in ATLAS {self.version}")
return self.techniques[tag]["name"]
def suggested_mitigations(self, tag):
# a sub-technique inherits the parent's mitigations
ids = set(self.mitigated_by[tag]) | set(self.mitigated_by.get(self.parent.get(tag), []))
return sorted(ids)Run check in CI over every technique ID in your threat model, red-team findings and detection rules. It catches typos and, more importantly, IDs that were renamed or deprecated between releases, which is the moment to re-review the finding rather than silently carrying an old tag forward.
Worked example: a case study as an attack chain
Case studies are the most underused part of ATLAS. Take AML.CS0039, "Living Off AI: Prompt Injection via Jira Service Management", an exercise in which researchers targeted an organisation whose support engineers used an AI assistant connected to Jira through an MCP server. The data records eight steps:
- Reconnaissance on the MCP integration (
AML.T0003) and a search for exposed service portals (AML.T0095). - Crafting a prompt that asks for the details of all other tickets to be posted as a reply (
AML.T0065, AI Attack Adaptation). - Submitting it as a new ticket on the public portal (
AML.T0093, Initial Access). - A support engineer asks the assistant to handle the ticket, which executes the planted instructions (
AML.T0051.001, indirect prompt injection). - The instructions cause MCP tool calls with the engineer's access (
AML.T0053, Privilege Escalation), which collect other tickets (AML.T0085.001, Collection) and post them back to the attacker's ticket (AML.T0086, Exfiltration).
Ordering the employs entries by following leads-to from the step nobody points at gives this chain directly. Each step is a test case: can an external user submit content that reaches the agent, does the agent obey instructions in that content, can it call tools with more access than the submitter has, and can it write data back to a place the attacker can read? For your own architecture, replace the Jira portal with whatever untrusted input reaches your agent, and keep the chain.
The mitigations ATLAS links to AML.T0086 include AML.M0030 Restrict AI Agent Tool Invocation on Untrusted Data, AML.M0028 AI Agent Tools Permissions Configuration, AML.M0029 Human In-the-Loop for AI Agent Actions and AML.M0024 AI Telemetry Logging. Notice what is not on that list: a better system prompt. The structural controls break the chain; the prompt only makes the attacker work harder.
Coverage maps without self-deception
The practical use of ATLAS inside a team is a coverage map: for each technique in scope, which controls prevent it, which detections would see it, and which tests prove both. Keep that map as data next to your threat model and compute the gaps.
SCOPE = { # technique -> what we have; keep in the repo with the threat model
"AML.T0051.001": {"controls": ["AML.M0030"], "detections": ["tool_call_after_untrusted_doc"], "tests": ["rt-114"]},
"AML.T0053": {"controls": ["AML.M0028", "AML.M0029"], "detections": [], "tests": ["rt-115"]},
"AML.T0086": {"controls": ["AML.M0028"], "detections": ["egress_to_new_domain"], "tests": []},
"AML.T0070": {"controls": [], "detections": [], "tests": []},
}
atlas = Atlas(fetch())
for tag, have in SCOPE.items():
name = atlas.check(tag)
missing = [m for m in atlas.suggested_mitigations(tag) if m not in have["controls"]]
gaps = [k for k in ("controls", "detections", "tests") if not have[k]]
print(f"{tag} {name}: gaps={gaps or 'none'} unconsidered={missing}")The output is a to-do list, not a score. An unconsidered mitigation is a prompt to decide, and record, whether it applies; many will not. Resist turning the map into a percentage of the matrix covered: an agent product with no access to model weights should not be penalised for lacking controls against weight theft, and a high percentage invites people to tag shallow detections to make the number move.
Folding ATLAS into everyday security work
Fold ATLAS into work you already do rather than running it as a separate exercise.
- Threat modelling. Draw the data flow first, then walk the tactics in matrix order for each untrusted input and each tool, and record candidate techniques with the reasoning.
- Red teaming. Tag every finding with the most specific technique, sub-technique where one exists, and plan exercises from case-study chains that resemble your architecture.
- Detection engineering. Tag rules with techniques and review the map quarterly; agent tool calls and outbound requests after untrusted content are the most valuable telemetry for LLM applications.
- Incident response. Tag incidents with the same IDs, so post-incident reviews can ask which step of the chain should have been stopped.
- Release upgrades. When you move to a new ATLAS release, diff technique IDs, names and relationships, and re-review anything in your scope that changed.
Failure modes
Mistakes that make ATLAS adoption look busy without improving security:
- Matrix colouring. Shading cells green because a document mentions them. A cell is covered only when a test proves the control or detection works.
- Tagging only parents.
AML.T0051alone hides whether the injection was direct or arrived through retrieved content, and those need different defences. - Unpinned data. Loading whatever is current means a monthly release can silently change names and links under your reports.
- Treating ATLAS as complete. It catalogues observed and researched behaviour. Your system can have weaknesses nobody has written up yet; threat modelling still starts from your architecture.
- No severity. ATLAS tells you what an attack is, not how bad it is for you. Pair each tagged technique with impact and likelihood in your own risk register.
Related reading
For the wider ecosystem ATLAS sits in, read the AI security labs and knowledge-base ecosystem. Pair it with the OWASP Top 10 for LLM applications for prioritisation and the NIST AI Risk Management Framework for governance. To apply it, see threat modelling LLM applications, red teaming LLM systems and data poisoning.
What to do next
- Download a pinned ATLAS release, load it with the code above, and print the tactics in matrix order.
- Draw your application's data flow and list every untrusted input that can reach a model or agent.
- Walk the 16 tactics for each input and record candidate techniques at sub-technique level.
- Pick the two case studies closest to your architecture and turn their step chains into red-team test cases.
- Build the coverage map for your in-scope techniques and review the gaps and unconsidered mitigations.
- Add the ID check to CI for findings and detection rules, and schedule a review for each ATLAS release.