Summary
Authentication no longer hinges on passwords alone but on tokens, keys, and trust relationships between applications and service accounts. While this shift has enabled seamless integrations and powerful automation, it has also opened the door to a stealthy and dangerous class of attacks: Actor Token Forgery. This blog post explores Actor Token Forgery from an attacker’s point of view, demonstrating how malicious actors exploit legitimate trust chains to impersonate users and applications.
Actor Token Forgery is one of the many techniques adopted by attackers to escalate privileges and move laterally via identity.
This post reconstructs the attack flow, maps it to MITRE ATT&CK, and outlines immediate detection and defense actions.
What are Actor Tokens?
Actor tokens are tokens that are issued by a service called Access Control Service. These tokens allow certain Microsoft services to impersonate users/identities in an Entra directory. Exchange and Sharepoint are two of the most common services using Actor tokens.
Actor tokens lack a lot of security controls and visibility, in particular:
- There are no logs at issuance
- There are no logs of usage, as these tokens in Entra are logged as the impersonated identity
- They cannot be revoked
- Conditional Access policies don’t apply to them
What is Actor Token Forgery?
Actor Token Forgery is a technique where attackers forge OAuth 2.0 access tokens using either a stolen certificate or an injected trusted key. These tokens are indistinguishable from legitimate ones: they’re signed with trusted credentials, issued by Microsoft’s own Security Token Service (STS), and pass all validation checks. With them, attackers can authenticate to Microsoft Graph, Exchange, SharePoint, or any federated app in the tenant, without triggering MFA, without a login event, and without raising any alarms.
This technique is similar in spirit to the infamous Golden SAML attack. But while Golden SAML abuses federated identity infrastructure like ADFS, Actor Token Forgery happens entirely within Microsoft Entra (formerly Azure AD), making it harder to detect and easier to automate.
The Attack Flow
Like many identity-centric attacks, Actor Token Forgery requires an initial foothold. This could come from a compromised global admin account, an exposed CI/CD token, or a misconfigured app registration with excessive permissions.
Once inside, the attacker hunts for service principals or applications with high-privilege permissions such as Directory.Read.All, Mail.Read, or User.Read.All. Using Microsoft Graph, they enumerate applications and check their keyCredentials and appRoles.
- roadtx graphrequest https://graph.microsoft.com/v1.0/servicePrincipals
- roadtx graphrequest https://graph.microsoft.com/v1.0/applications
The next step is critical: the attacker either steals an existing certificate (PFX) from disk or injects a new one via Graph API. Certificate injection requires Application.ReadWrite.All or equivalent permissions, which are often granted to CI/CD pipelines, automation accounts, or overly trusted apps.
Each parameter in the command defines a specific part of the OAuth 2.0 / OpenID Connect token request that ROADtools performs against Azure AD:
-c 93c5e1b2-0fa0-4126-a2d2-9c58f1cd7685— Client (Application) ID The globally unique identifier of the Azure AD application (service principal) that is authenticating. It tells Azure AD which app is requesting the token and links the request to that app’s registration within the tenant.-t endrit.onmicrosoft.com— Tenant Specifies the Azure AD tenant that will issue the token. It’s the logical directory in which the app lives and where authentication takes place. In this example, the tenant domain endrit.onmicrosoft.com corresponds to a particular tenant ID (tid) shown later in the decoded token.-s "msgraph/.default offline_access"— Requested Scopes / Resource Permissionsoffline_accessadds the ability to obtain refresh tokens for long-lived access.--key-pem— Private-Key File (Proof of Possession) – PFX--cert-pem— Public-Key / Certificate File
This allows attackers to:
- Call Microsoft Graph with app-level permissions the app already has. Meaning that they can:
- Add or replace keyCredentials
- Create new service principal
- Assign roles or create privileged accounts
- Use obtained token to call other MS APIs (SharePoint, Exchange,…)
roadtx graphrequest -m POST "https://graph.microsoft.com/v1.0/applications/:98449b3b-bfc5-4459-82cc-f4c1994df7e9addPassword" -d "{\"passwordCredential\":{\"displayName\":\"Backdoor App\"}}
Diving deeper
This figure illustrates a full Actor Token Forgery attack chain executed using ROADtools, a post-exploitation toolkit. The first command shows the generation of an actor token (getactortoken) using a compromised client certificate linked to an app registration (client_id: 93c5e1b2-0fa0-4126-a2d2-9c58f1cd7685) within the Entra tenant. This token impersonates an identity (00000002-0000-0ff1-ce00-000000000000@outlook.office.com) typically used by Microsoft services such as Outlook or Graph API, granting delegated access under this identity. After writing the token to .roadtools_actortoken, the describe command decodes the JWT payload, revealing fields like appid, identityprovider, oid, and tid, confirming it is a signed token for Microsoft Graph with aud and iss aligned to the compromised tenant.
In the next step, getimpersonationtoken is used to forge a composite token impersonating a target user (alice@endrit.onmicrosoft.com) using the previously obtained actor token. The target resource is SharePoint (endrit.sharepoint.com), and the resulting impersonation token is stored in .roadtools_auth. The final describe output reveals the forged token contains an “actortoken” claim, which embeds the original actor token inside the composite, thereby linking the forged token to the service principal that signed it. This type of attack effectively allows lateral movement, access escalation, and cross-service impersonation without MFA or password interaction, bypassing traditional logon detection tools, and representing a serious threat if certificate theft or app registration abuse occurs.
Key points:
- Sharepoint accepted a self-signed, unsigned token (“alg”: “none”), because it came through a trusted hybrid path.
- The “iss” (issuer) is the same one as for the legitimate actor token, and the same for the forged copy after the ROADtools_actor token command.
- The difference is origin: one came from Microsoft’s STS, the other was self-signed by the attacker, yet still trusted by Exchange Online because it’s signed with the valid hybrid certificate’s key.
Assertion key and S2S Authentication Flaws
When the on-prem Exchange server requests an actor token from Microsoft’s Access Control Service, that token is an assertion — a signed JWT stating “Exchange on-prem (actor) is acting on behalf of user X”.
Exchange Online doesn’t talk directly to Entra ID again; instead, it takes that assertion and embeds it verbatim inside a new token — the unsigned bearer token you see being sent to Exchange Online. Because Exchange Online already trusts the on-prem service principal and its certificate (configured as “trusted for delegation”), it doesn’t need to re-validate the signature against Entra ID. It simply unwraps the actor token, verifies the issuer (Exchange Hybrid), and accepts the claims (user identity, roles, scopes).
Thus, the “actor token assertion” and the “unsigned bearer token” contain the same inner data: one is issued by ACS and signed, and the other is just that same blob re-used and forwarded by Exchange Online to prove delegated identity.
The Service-to-Service (S2S) authentication model was built for seamless communication between trusted Microsoft workloads like Exchange and SharePoint but creates a major blind spot.
When a trusted service principal (e.g., an on-prem Exchange hybrid server) requests an actor token from Microsoft’s Access Control Service (ACS), it receives a signed JWT. Exchange Online then embeds that token inside an unsigned bearer token (“alg”: “none”) to skip revalidation with Entra ID, meaning no logs, no Conditional Access, and no revocation. These S2S tokens last up to 24 hours, are non‑revocable, and invisible to standard identity monitoring. Because the bearer token simply reuses the actor token’s contents, compromising a certificate from a TrustedForDelegation service lets attackers impersonate any tenant user, including admins, and access Exchange, SharePoint, and OneDrive entirely outside Entra ID’s visibility.
Hardening Against Actor Token Forgery & S2S Assertion Abuse
-
Audit certificate material in service principals:
a. Query:
ServicePrincipal | where preferredTokenSigningKeyThumbprint != "" or array_length(keyCredentials) > 0b. Flag:
keyCredentials.endDateTime > now() + 365dtrustedForDelegation == truec. Action:- Rotate all credentials ≥ 90 days old
- Enforce short-lived certs via Graph automation:
az ad app credential list --id <appid> az ad app credential reset --id <appid> --append --years 0.25
-
Monitor certificate insertions via Graph API:
a. Telemetry:
AuditLogs | where ActivityDisplayName == "Add keyCredentials"b. Detection logic:
- New certificate on high-privilege app (Graph, Exchange, EWS) without matching
appRoleAssignmentchange
- New certificate on high-privilege app (Graph, Exchange, EWS) without matching
-
Flag or block tokens with
"alg": "none"(unsigned JWTs) -
Correlate mailbox access patterns with Entra logs:
- Rationale: S2S / actor tokens are accepted by Exchange/SharePoint but never logged in Entra ID
- S2S tokens leave no Entra ID log footprint
-
Look for unusual file access scopes in Graph calls (e.g.,
Files.Read.Allby apps) -
Review conditional access bypass paths:
- Important: S2S flows do not trigger Conditional Access
- Mitigation:
- Restrict usage of client-credential flow apps:
az ad app update --id <appid> --set oauth2AllowImplicitFlow=false
- Restrict usage of client-credential flow apps:
Integrity-based detection of forged assertions
In this example, the actor token’s header exposes the thumbprint:
- JWT token thumbprint:
x5t/kid = yEUwmXWL107Cc-7QZ2WSbeOb3sQ
While the legitimate Entra service principal lists a registered certificate with:
- Registered certificate:
customKeyIdentifier = 17A0A7B70A586359E83BCB9BDAA3D3402F29D9DF
Key finding: Because the token thumbprint does not appear in the service principal’s keyCredentials set, the token’s signing certificate is unregistered in Entra—proving it was generated offline with a forged or stolen PFX.
Attacker’s Toolbox
- Exported PFX (cert+key) from Entra or Exchange Hybrid
- ROADtools + ROADtx modules (getactortoken, getimpersonationtoken,…)
- Custom JWT forging tools
- Known AppIDs / Service Principals
- Exchange:
00000002-0000-0ff1-ce00-000000000000 - Graph:
00000003-0000-0000-c000-000000000000 - SharePoint:
00000003-0000-0ff1-ce00-000000000000
- Exchange:
- Graph API post-exploitation
- GET
/users/{id}/drive/root/children(shown below & demo), GET /users, GET /users/{id}
- GET
Demo
This screenshot shows a successful Microsoft Graph call made after ROADtools generated an actor/impersonation token.
API endpoint: GET /users/{id}/drive/root/children
Attack flow:
- Attacker produces a signed actor token (PFX-based)
- Uses it to request a delegated token that can read OneDrive contents
- Makes Graph API call with forged credentials
Technical breakdown:
- Attack type: Actor token forgery / abuse of certificate-backed app credentials
- Authentication proof: Token proves possession of a private key
- Why it works: Accepted by Entra/Exchange/Graph as a valid service-issued assertion
- Result: Graph API returns the victim’s drive items without any interactive login or MFA
Key security implications:
- ❌ No MFA challenge
- ❌ No user interaction required
- ❌ Bypasses Conditional Access policies
- ✅ Appears as legitimate service-to-service authentication
What SlashID detects
SlashID is built to detect and respond to attacks such as Actor Token Forgery. In particular with SlashID you can detect:
- Service accounts with dangerous OAuth 2 scopes
- Anomalous
keyCredentialchanges - Anomalous
appRoleAssignmentchanges - Anomalous service accounts behavior
Conclusion
Actor Token Forgery is a high-impact identity attack that leverages trust relationships and certificate-based signing to bypass normal identity controls. Because the attack abuses legitimate service principals and S2S (service-to-service) flows, it can fail to generate any meaningful records in Entra ID or Conditional Access telemetry—creating a dangerous blind spot for defenders. In practice, an attacker who can obtain or inject a signing certificate into a trusted application or hybrid service principal can impersonate any user in the tenant and access Exchange, SharePoint, OneDrive, and Graph APIs without interactive sign-ins or MFA challenges.
Defenders can significantly reduce this risk by treating certificate material and service principals as first-class security objects: rotate credentials frequently, enforce short certificate lifetimes, monitor and alert on every keyCredentials insertion or modification, and correlate app-level activity with Entra ID and mailbox access logs. Where possible, minimize the number of applications trusted for delegation and restrict app permissions to least privilege. Finally, make integrity checks—like validating token thumbprints against registered keyCredentials—part of routine identity hygiene and automated threat-detection playbooks.
If you maintain hybrid Exchange or any S2S integrations, prioritize the following immediate actions:
- Inventory service principals and their certificates
- Audit recent Add
keyCredentialsevents and newly created high-privilege apps - Implement detection rules that correlate unsigned or unexpected tokens with certificate insertions and privileged Graph activity.
These steps will close the fastest, most obvious attack paths and give your security team the visibility needed to detect and respond to Actor Token Forgery before it becomes a full tenant compromise.
SlashID is built to detect and respond to attacks such as Actor Token Forgery. Get in touch to see how we can help.