Microsoft Digital Defense Report 2026: Agents Are an Identity Problem

·9 min read·Evergreen Tools Team

Microsoft published the 2026 edition of its Digital Defense Report on October 1, and the blog post summarising it, written by CVP and Deputy CISO Terrell Cox, is worth reading for one reason: the list of things it says security teams now have to examine about AI. Agent identity, appropriate access, authentication between agents, attribution, and the ability to revoke access. If you build with agents, that list is your backlog. It is also, notably, a list of familiar security problems wearing new labels.

A padlock and encryption concept

Agent identity comes before agent capability

AI in the threat landscape, described without drama

The report's finding on offensive use is specific rather than apocalyptic: threat actors are incorporating AI into reconnaissance, social engineering, malware and exploit development, and post-compromise activity, and much of that use remains focused on particular parts of existing attack workflows. AI gives attackers greater speed, scale, and the ability to tailor activity more efficiently, with social engineering becoming more targeted and technical work compressing. The underlying methods remain familiar. People, identities, exposed systems and trusted access still feature prominently in what Microsoft observes. That is a useful calibration: the threat changed shape and retooled, and it did not replace the fundamentals you were already supposed to be doing.

# Every agent needs an owner, a purpose and an expiry. Most have none.
import json

AGENT = {
    'name': 'invoice-reconciler',
    'owner_team': 'finance-platform',
    'purpose': 'match supplier invoices against purchase orders',
    'identity_type': 'workload-identity',
    'credential_ttl_minutes': 60,
    'scopes': ['erp.read', 'erp.write:reconciliation-notes'],
    'may_call_agents': ['notification-agent'],
    'human_approval_required_for': ['erp.write:payments'],
}

REQUIRED = ['owner_team', 'purpose', 'credential_ttl_minutes', 'scopes']

def validate(agent):
    missing = [k for k in REQUIRED if not agent.get(k)]
    long_lived = agent.get('credential_ttl_minutes', 0) > 1440
    return {'missing': missing, 'long_lived_credential': long_lived,
            'status': 'reject' if missing or long_lived else 'accept'}

print(json.dumps(validate(AGENT), indent=2))

# An agent with no owner is an anonymous insider with a job title.

Agents are an identity problem

This is the part that should reshape roadmaps. The report says agents can interact with enterprise data, applications, APIs and tools with different levels of access and autonomy depending on how they are designed and deployed, and those connections are both what make agents useful and what security teams need to understand. It then names the questions: agent identity, appropriate access, authentication between agents, attribution, and the ability to revoke access. Every one of those is a solved problem in service-to-service architecture, which is good news. The awkward novelty is that agents act with delegated human intent and change behaviour based on text, so the same primitive has to hold under a fuzzier set of inputs.

# Least privilege is easier to review as a diff than as a policy PDF.
GRANTED = {
    'erp.read', 'erp.write:reconciliation-notes', 'crm.read',
    'mail.send:internal', 'files.read:/shared/finance',
}
REQUESTED_BY_TASK = {
    'match_invoice':    {'erp.read'},
    'write_note':       {'erp.write:reconciliation-notes'},
    'notify_purchasing': {'mail.send:internal'},
}

def unused_grants(granted, requested):
    needed = set().union(*requested.values())
    return sorted(granted - needed)

print('unused grants:', unused_grants(GRANTED, REQUESTED_BY_TASK))

# Anything an agent can do and nothing asks it to do is a permission
# waiting for a prompt injection to find.
A network of connected nodes

A single log line is noise; correlation across sources is the signal

The five properties the report calls out

Alongside identity, the report examines security considerations specific to AI: prompt injection, memory, models and data, agent behaviour, and the integrity of software and services around AI systems. Read as a design checklist, each one maps onto something you can test. Prompt injection is an input-validation problem with no perfect parser. Memory is a persistence problem that turns a transient injection into a durable one. Models and data is a supply-chain problem. Agent behaviour is an observability problem, and a hard one, because the specification of correct behaviour is often written in prose. Integrity of surrounding software is the ordinary dependency problem, which is where most real incidents still land.

# Agent-to-agent calls deserve the same checks as service-to-service calls.
def verify_agent_token(claims, caller, callee):
    checks = {
        'issuer_trusted': claims.get('iss') in {'auth.internal'},
        'audience_is_callee': claims.get('aud') == callee,
        'subject_is_caller': claims.get('sub') == caller,
        'not_expired': claims.get('exp', 0) > 0,
        'is_agent_identity': claims.get('actor_type') == 'agent',
        'human_on_behalf_of': bool(claims.get('act')),
    }
    failures = [k for k, ok in checks.items() if not ok]
    return {'allow': not failures, 'deny_reasons': failures}

TOKEN = {'iss': 'auth.internal', 'aud': 'notification-agent', 'sub': 'invoice-reconciler',
         'exp': 1, 'actor_type': 'agent', 'act': {'sub': 'user:1043'}}

print(verify_agent_token(TOKEN, 'invoice-reconciler', 'notification-agent'))

# The act claim is the one people forget: which human asked for this?

Vulnerability discovery cuts both ways

The report is careful to present AI-assisted code analysis as a doubled-edged development rather than a defence win. Advances in applying AI to code analysis make it possible to examine software and identify weaknesses more effectively, creating opportunities to find vulnerabilities earlier and strengthen software before weaknesses are exploited. The same advances give threat actors more capable tools for vulnerability discovery and exploit development. Microsoft's framing, that both sides continue to advance, is the honest one. The practical consequence for a small team is that time-to-patch becomes a competitive variable: if discovery gets cheaper for everyone, the half-life of an unpatched dependency shortens.

# Revocation is a rehearsal, not a diagram. Time it.
import subprocess, time

REVOCATION_DRILL = [
    ('disable workload identity', 'az ad sp update --id $AGENT_SP --set accountEnabled=false'),
    ('rotate the agent secret',   'vault kv put secret/agent key=-'),
    ('block the agent egress',    'firewall-cli deny --tag agent-invoice-reconciler'),
    ('invalidate cached tokens',  'auth-cli revoke --subject $AGENT_SP'),
    ('confirm in the audit log',  'siem query --actor $AGENT_SP --since 5m'),
]

def drill(dry_run=True):
    timings = []
    for label, cmd in REVOCATION_DRILL:
        start = time.time()
        if not dry_run:
            subprocess.run(cmd, shell=True, check=False)
        timings.append((label, round(time.time() - start, 3)))
    return timings

print(drill(dry_run=True))

# If the answer to how long it takes is unknown, the honest answer is not short.
A close-up of a circuit board

Every permission an agent holds should map to a task on a list

Correlation is the defence that scales

The report's least glamorous section is the one most teams should act on. Security teams work with information from endpoints, identities, cloud environments, applications, email, networks and threat intelligence, and signals become more useful when they can be considered together, because threat activity spanning several systems may leave a pattern that no single source shows. The same principle extends across organisations through trusted intelligence sharing. On automation, the report draws a line worth remembering: connecting known information and running established techniques can increasingly be automated, while finding an undocumented attack path still benefits from experienced operators. Automate the first, staff the second.

# Correlate across sources, because single-source alerts miss the pattern.
EVENTS = [
    {'ts': '03:02', 'source': 'identity', 'actor': 'invoice-reconciler', 'event': 'token_issued'},
    {'ts': '03:04', 'source': 'network',  'actor': 'invoice-reconciler', 'event': 'egress_denied'},
    {'ts': '03:06', 'source': 'erp',      'actor': 'invoice-reconciler', 'event': 'bulk_read', 'rows': 41250},
    {'ts': '03:07', 'source': 'email',    'actor': 'invoice-reconciler', 'event': 'external_send'},
]

def correlate(events, actor):
    by_actor = [e for e in events if e['actor'] == actor]
    sources = {e['source'] for e in by_actor}
    signals = []
    if {'identity', 'network'} <= sources: signals.append('new identity with denied egress')
    if any(e.get('rows', 0) > 10000 for e in by_actor): signals.append('bulk read')
    if any(e['event'] == 'external_send' for e in by_actor): signals.append('outbound to external')
    return {'actor': actor, 'sources': sorted(sources), 'signals': signals}

print(correlate(EVENTS, 'invoice-reconciler'))

# One source is a log line. Four sources is an incident.

The checklist that follows

Give every agent an owner, a written purpose, and credentials measured in hours rather than months. Map its granted permissions to the tasks it actually performs, and revoke the ones nothing requests, because an unused permission is a prompt injection's reward. Authenticate agent-to-agent calls the way you authenticate service-to-service calls, and record which human the action was on behalf of. Rehearse revocation and time it; an untimed revocation plan is a diagram, not a control. Then correlate signals across identity, network, application and email, so that a new identity with denied egress, a bulk read and an outbound message stop being three log lines and become one incident.

📌 Frequently Asked Questions

What is the Microsoft Digital Defense Report?

It is Microsoft's annual report drawing on what its security and threat intelligence teams observe, published in October 2026 for this edition. It covers the broader threat landscape, cybercrime, resilience, and how technologies, identities, systems and people relate in an increasingly interconnected environment.

What does it say about AI and attackers?

That threat actors are incorporating AI into reconnaissance, social engineering, malware and exploit development, and post-compromise activity, with much of the use focused on specific parts of existing workflows. AI gives them greater speed, scale and tailoring ability, while the underlying methods and the reliance on identities and trusted access remain familiar.

Why call agent security an identity problem?

Because the report frames it that way: agent identity, appropriate access, authentication between agents, attribution and the ability to revoke access. Each agent needs a distinct identity, a scoped set of permissions, verifiable calls to other agents, and a way to be shut down quickly.

Which AI-specific risks does it list?

Prompt injection, memory, models and data, agent behaviour, and the integrity of the software and services around AI systems, alongside the surrounding identity and authorisation concerns.

What should a builder do first?

Inventory agent identities and their owners, cut credential lifetimes, remove unused permissions, add authentication and attribution to agent-to-agent calls, rehearse revocation with a stopwatch, and correlate security signals across identity, network, application and email sources.