Guides
Detection guide

Privilege Escalation Detection: Audit Events to Watch

By Sazabi Team

Last verified on Nov 8, 2026.

Attackers who get a foothold rarely stay at the access they started with. They add a policy to the account they control, create a second access key or add themselves to an admin group, because standing permission outlasts a stolen password. MITRE ATT&CK describes this as account manipulation: any action that preserves or modifies access to a compromised account, such as modifying credentials or permission groups. Insiders and mistakes produce the same events, so the detection works for all three.

Privilege changes are rare compared with most other events, so they are a good place to alert. The trick is knowing which of them were expected.

What the evidence looks like

Every privileged system has an audit trail for these events. AWS records IAM and STS API calls in CloudTrail. GitHub keeps an audit log for organizations. Kubernetes can record API requests with audit logging, and its RBAC rules block users from creating roles or bindings that grant more than they already hold. Your own application should log role grants too: the OWASP Logging Cheat Sheet lists user administration actions, changes to privileges and the use of administrative privileges among events worth logging.

A simplified CloudTrail-style record, as an example:

{
  "eventTime": "2026-11-04T03:12:44Z",
  "eventSource": "iam.amazonaws.com",
  "eventName": "AttachUserPolicy",
  "userIdentity": { "type": "IAMUser", "userName": "build-bot" },
  "sourceIPAddress": "203.0.113.40",
  "requestParameters": { "userName": "contractor-7", "policyArn": "arn:aws:iam::aws:policy/AdministratorAccess" }
}

The AWS API reference describes AttachUserPolicy and AttachRolePolicy as attaching a managed policy, PutUserPolicy as adding or updating an inline policy, CreateAccessKey as creating a new access key for a user, AddUserToGroup as adding a user to a group and UpdateAssumeRolePolicy as changing who can assume a role. All of these change who can do what.

How to detect it step by step

1. Collect the audit logs in one place. Cloud control plane, identity provider, source host, Kubernetes API server and your application's admin actions. Without them there is nothing to query.

2. Maintain a list of privilege-changing event names. Start from the IAM actions above and add the equivalents in each system: org role changes in GitHub, role binding creation in Kubernetes, admin flag updates in your database.

3. Query for them and classify the actor.

SELECT event_time, actor, event_name, source_ip, target, parameters
FROM audit_events
WHERE event_source = 'iam.amazonaws.com'
  AND event_name IN ('AttachUserPolicy','AttachRolePolicy','PutUserPolicy',
                     'CreateAccessKey','AddUserToGroup','UpdateAssumeRolePolicy')
  AND event_time > now() - INTERVAL '1 day'
ORDER BY event_time

4. Keep an allowlist of expected actors. A deployment pipeline that grants a role to a service on every release is expected. A person changing permissions at 3 a.m. is not. Compare the actor and source with the last 30 days of changes by the same actor.

5. Score the change by blast radius. A grant of AdministratorAccess, a new key on a root or break-glass identity, or a role that can assume other roles matters more than adding a read-only policy.

6. Join to change records. If every legitimate grant has a ticket or pull request number in a tag or comment, alert on grants that do not.

Thresholds and pitfalls

Alert on every grant of the broadest roles. The volume is low enough to review manually. For narrower grants, alert on deviation: an actor who has never granted a permission before, a source IP or country not seen for that actor, or a grant outside working hours.

Pitfalls to plan for:

  • Automation. Terraform runs and onboarding scripts create bursts of legitimate changes. Allowlist the identity and the time window, not the event name.
  • Location signals. VPNs, mobile networks and cloud runners make source IP noisy. Treat a new location as a risk factor to combine with others, not as a verdict.
  • Indirect escalation. Changing a trust policy or editing a group an admin belongs to does not look like a direct grant. Include those events in your list.
  • Delay. Some audit logs arrive minutes after the event. Do not close an alert as quiet until the window has passed.
  • Gaps. An attacker with enough access can stop logging. Alert on audit logging being disabled, too.

What to do when it fires

Contact the actor and the owner of the target through a channel that does not rely on the account in question. If nobody can confirm the change, revoke the grant, rotate keys created in the same session and list what the new permission did after it was granted. The same audit trail answers that question.

Then close the loop: add the missing event to your list, allowlist the pipeline that caused a false alarm and tighten who can grant the permission at all. Related reading: authentication anomalies covers sign-ins that precede a privilege grab, access anomalies covers what happens after, and configuration drift covers permissions that change outside review. To pull the audit data in, see the AWS, CloudTrail and GitHub integration pages.

With Sazabi

Sazabi detects this today with no setup: the Sazabi agent automatically sets up sensors for your project and maintains them over time. Privilege Change Alerts: Issues for New Admins, Role Escalations and API Keys covers what it catches.

Frequently Asked Questions

Which events show privilege escalation?

Grants of broad roles, new admin users, new access keys and changes to who can assume a role. In AWS these include AttachUserPolicy, CreateAccessKey and UpdateAssumeRolePolicy.

How do I reduce false positives from automation?

Allowlist the pipeline identity and its normal time window, not the event name. Keep the rule on for everyone else, because the volume of privilege changes is low.

Do I need a SIEM to detect privilege escalation?

No. You need the audit logs in one queryable place, a list of privilege-changing event names and a way to compare the actor with recent history.

What should I do when an unexpected admin grant appears?

Confirm with the actor through a separate channel. If unconfirmed, revoke the grant, rotate keys created in the same session and review actions taken since.

Sources

  1. Account manipulation: actions that preserve or modify access to a compromised account, such as modifying credentials or permission groups (accessed Nov 8, 2026)
  2. IAM and STS API calls are logged with AWS CloudTrail (accessed Nov 8, 2026)
  3. AttachUserPolicy attaches a managed policy to a user (accessed Nov 8, 2026)
  4. AttachRolePolicy attaches a managed policy to a role (accessed Nov 8, 2026)
  5. PutUserPolicy adds or updates an inline policy for a user (accessed Nov 8, 2026)
  6. CreateAccessKey creates a new access key for a user (accessed Nov 8, 2026)
  7. AddUserToGroup adds a user to a group (accessed Nov 8, 2026)
  8. UpdateAssumeRolePolicy updates the policy that grants an entity permission to assume a role (accessed Nov 8, 2026)
  9. GitHub organization audit log can be searched, exported and read through an API (accessed Nov 8, 2026)
  10. Kubernetes auditing records requests to the API server (accessed Nov 8, 2026)
  11. Kubernetes RBAC privilege escalation prevention restricts creation or update of roles and bindings (accessed Nov 8, 2026)
  12. Events to log include user administration actions, privilege changes and use of administrative privileges (accessed Nov 8, 2026)