A large share of SaaS automation still runs as a "bot" user account with a password that several people know, a licence nobody reviews and no owner on record once its creator leaves. The alternative on most platforms is an application identity: a service principal in Microsoft Entra ID, a service account in Google Cloud, a GitHub App, or a dedicated API-only integration user in Salesforce. This guide compares the two models on the six properties that decide risk: credential type, MFA and conditional access, ownership and offboarding, audit attribution, licence cost and blast radius. It then gives a threat model and controls for each, decision criteria, a worked scenario and metrics. It is for identity, SaaS administration and platform teams who own automation across Microsoft 365, Google Workspace, GitHub and Salesforce. Platforms are listed alphabetically throughout; order is never a ranking.
Key takeaways
- A bot account is a person-shaped identity doing machine work. It inherits every human control (password, MFA prompts, licence, mailbox, interactive sign-in) whether or not the automation needs it, and those controls either break the job or get switched off for it.
- Mandatory MFA has changed the economics in Microsoft clouds. Microsoft enforces MFA on user identities for Azure portal, CLI, PowerShell, IaC and control plane REST operations, including user accounts used as service accounts, while service principals and managed identities are not affected.
- Application identities are not automatically safer. A service principal with a long-lived secret and tenant-wide Graph permissions, or a Google service account with broad domain-wide delegation, has a larger blast radius than most bot users.
- Attribution is the decisive difference. Platforms log application sign-ins as a separate class with a distinct identifier per integration, while a shared bot account turns every action into "the bot did it", whoever was at the keyboard.
- Keep a user account only where the platform demands one. Some actions are only available to a licensed user or need a user context; in those cases treat the account as a privileged non-human identity with a named owner, a vaulted credential and phishing-resistant or conditional controls.
What each option is
A bot account (also called a service user, robot user, machine user or shared automation account) is an ordinary directory user created for a script, integration or RPA flow. It signs in with a username and password, sometimes with an app password or a stored refresh token, and it appears to the platform exactly as an employee would. GitHub's documentation describes the pattern plainly: user accounts are intended for humans, but you can create accounts to automate activity, and such an account is called a machine user.
A service principal, in the broad sense used here, is an identity that the platform models as software rather than as a person. Microsoft defines the application object as the global template in the home tenant and the service principal as its local representation in a specific tenant, with three service principal types: application, managed identity and legacy. Microsoft groups applications, service principals and managed identities together as workload identities. The equivalents on the other platforms differ in name and mechanics but share the same idea: the identity has no password, no interactive sign-in and a permission model built for APIs.
Platform equivalents
| Platform | User-style automation identity | Application identity | Main scoping control for the application identity |
|---|---|---|---|
| GitHub | Machine user (a personal account used for automation) | GitHub App installed on the organisation | Fine-grained app permissions and the repositories selected at installation |
| Google Workspace and Google Cloud | Workspace user account used by a script | Google Cloud service account, optionally with domain-wide delegation | IAM roles on the service account; the OAuth scopes listed for its client ID under domain-wide delegation |
| Microsoft 365 and Entra ID | Licensed or unlicensed Entra user used as a service account | Application service principal or managed identity | Graph application permissions, Azure RBAC role assignments, Exchange Online RBAC for Applications scopes |
| Salesforce | Standard user with a full licence used for an integration | Integration user on the Salesforce Integration licence with the Minimum Access - API Only Integrations profile, called through an external client app with OAuth 2.0 | Permission sets and permission set groups on the integration user |
Salesforce's integration user is technically a user record, but it is API-only and cannot reach Salesforce data or features through any user interface, so for this comparison it sits on the application side.
Side-by-side comparison
| Property | Bot user account | Service principal or application identity |
|---|---|---|
| Credential type | Password, sometimes with an app password, stored refresh token or TOTP seed shared among the team | Certificate, client secret, private key or federated credential; managed identities and workload identity federation remove the stored secret entirely |
| MFA | Applies, which either blocks unattended jobs or leads to MFA exclusions and shared authenticator seeds | Not applicable; strength comes from credential type and lifetime instead |
| Conditional access | Full user policy set applies, but exclusions for "service accounts" are common | In Entra ID, Conditional Access for workload identities can block single-tenant service principals by location or service principal risk (block is the only grant control) |
| Ownership | Often the creator, recorded nowhere; HR-driven leaver processes never touch it | App registrations, GitHub Apps and service accounts carry owners or a parent project, which can be required and reviewed |
| Offboarding | Survives its creator; password rotation is manual and breaks every consumer at once | Credentials can be rotated per integration; disabling one identity affects one integration |
| Audit attribution | Actions logged under one shared user; cannot tell which person or job acted | Logged as application activity with its own identifier; Entra keeps separate service principal and managed identity sign-in logs |
| Licence cost | Usually consumes a paid user seat | GitHub Apps do not consume a seat; some advanced controls (for example Entra Conditional Access for workload identities) need an add-on licence |
| Blast radius | Everything the user can reach in the UI and API, plus mailbox, files and chat if licensed | Exactly the granted permissions, which can be tenant-wide if granted carelessly or scoped to named mailboxes, repositories or objects |
Bot accounts: threat model, failure modes and controls
Threat model. The attacker's easiest route is the password. Bot accounts are frequently excluded from MFA so that jobs keep running, which makes them the ideal target for password spraying (ATT&CK T1110.003) and for reuse of credentials harvested by infostealers, then abuse as valid cloud accounts (T1078.004). The Snowflake breach showed how far a username and password without MFA can reach when the platform accepts them, and the Microsoft Midnight Blizzard breach began with a password spray against a legacy test tenant account that lacked MFA.
Architecture in words. A script on a server or an RPA runner reads the bot's password from a config file, an environment variable or, at best, a vault; it performs an interactive-style sign-in or a legacy resource owner password flow; the platform issues user tokens; and the job acts with the user's full permission set, including any admin roles someone added "to make it work".
Failure modes.
- Shared password, many consumers: five jobs and three people use the same credential, so nobody rotates it because rotation breaks everything.
- MFA exclusion group: a "service accounts" group excluded from MFA and conditional access becomes the place where attackers and new bots both land.
- Licence-driven data exposure: a licensed bot gets a mailbox, OneDrive or Drive, Teams or Chat, so files and messages accumulate in an account nobody reads.
- Silent breakage under enforcement: Microsoft's mandatory MFA applies to user accounts used for automation; Phase 2 covers Azure CLI, Azure PowerShell, IaC tools and control plane REST create, update and delete operations, starting 1 October 2025 with postponement possible to 1 July 2026, as announced on Microsoft Learn.
Controls if a bot account must remain. Give it a named human owner and a business owner; store its credential in a vault with checkout and rotation; scope it with a dedicated role, never a broad admin role; apply conditional access restricted to the runner's network location instead of an exclusion; remove licences it does not need; block interactive sign-in where the platform allows; and review it on the same cycle as privileged human accounts.
Service principals and application identities: threat model, failure modes and controls
Threat model. Here the attacker targets the credential or the grant. Stolen client secrets and private keys, application access tokens taken from pipelines (T1528, T1550.001), and new credentials added to an existing app for persistence (T1098.001) are the common paths. In the Midnight Blizzard breach the attacker used a legacy test OAuth application with elevated access and granted Exchange Online full_access_as_app, which reads mailboxes with no user signed in.
Architecture in words. The automation authenticates as itself: a certificate or federated token in Entra ID, a key, impersonation or workload identity federation for a Google service account, a JSON Web Token signed with the GitHub App's private key exchanged for a short-lived installation token, or an OAuth 2.0 flow from an external client app to a Salesforce integration user. Tokens carry only the application permissions granted.
Failure modes.
- Orphaned app registrations: the project ended, the owner left, the secret is still valid and the permissions remain. Microsoft's workload identity overview names tracking when an identity is created and when it should be revoked as a core challenge.
- Tenant-wide application permissions:
Mail.Read,Files.Read.Allor Google domain-wide delegation scopes give access to every user's data. Google states that with domain-wide delegation the app can access the data of all your users. - Unscoped grants that defeat scoped ones: Exchange Online RBAC for Applications grants are additive, so an unscoped
Mail.Readin Entra ID still applies even after a scoped assignment is added. The Entra grant has to be removed. - Long-lived secrets in code: a client secret or service account key copied into a repository or CI variable is a password with no MFA by design.
- Groups do not carry policy: Entra Conditional Access policies assigned to a group containing a service principal are not enforced for it; the service principal must be targeted directly.
Controls. Prefer credential-free options (managed identities, workload identity federation, GitHub App installation tokens); use certificates over secrets where a stored credential is unavoidable; scope permissions to resources (Exchange RBAC for Applications management scopes or administrative units, GitHub App repository selection, narrow domain-wide delegation scopes, Salesforce permission sets); require an owner on every registration; and alert on new credentials and new consent grants. See the Service Principals vs Managed Identities guide for the Entra credential order of preference.
How each platform supports the move
GitHub
GitHub Apps are not tied to a user account and do not consume a seat; they use fine-grained permissions instead of broad scopes, short-lived tokens, and they remain installed when the person who installed them leaves. The organisation owner chooses which repositories each installation can access. See the GitHub Apps vs Personal Access Tokens vs OAuth Apps guide and How to audit GitHub outside collaborators and machine users.
Google Workspace and Google Cloud
Google Cloud service accounts authenticate by attachment to a resource, by keys, by impersonation or through workload identity federation. With domain-wide delegation, API calls are authorised as the impersonated user, not as the service account itself. Delegation is granted by a super administrator under Security, Access and data control, API controls, Manage Domain Wide Delegation, by client ID and OAuth scopes; changes can take up to 24 hours, and multi-party approval can require a second super admin. See the Google Workspace Domain-Wide Delegation Security Guide.
Microsoft 365 and Entra ID
Service principals and managed identities are unaffected by mandatory MFA. Microsoft notes that customers who apply Conditional Access to user-based service accounts can reclaim the user licence and add a workload identities licence instead. Conditional Access for workload identities covers single-tenant service principals registered in your tenant, supports location and service principal risk conditions, and can run in report-only mode first. Exchange Online RBAC for Applications limits an app to a management scope or administrative unit and replaces Application Access Policies. See Conditional Access for Workload Identities.
Salesforce
The Salesforce Integration user licence makes the Minimum Access - API Only Integrations profile and the Salesforce API Integration permission set licence available. API-only access through this profile cannot be turned off, and further access is added with permission sets. Salesforce recommends one dedicated integration user per calling system, domain, use case or API resource, and an external client app with an OAuth 2.0 flow for REST APIs. Orgs in supported editions receive a limited number of these licences by default. See How to review Salesforce connected apps and integration users.
Choosing: decision criteria
| Situation | Choose | Why |
|---|---|---|
| Unattended job calling a platform API with application permissions | Application identity | No MFA conflict, attributable, scoped, no seat |
| Job runs on cloud compute or in CI with OIDC | Managed identity or workload identity federation | No stored credential to steal or rotate |
| Job needs one user's data only (one mailbox, one drive) | Application identity scoped to that resource, or delegated access by that user | Avoids a tenant-wide grant |
| Action is only exposed in the UI or only to licensed users (some RPA and legacy admin tasks) | Bot account, hardened | No API or app permission exists; treat as privileged NHI |
| Vendor integration requires a "connected user" | Dedicated API-only or least-privilege user per vendor | One identity per integration preserves attribution and revocation |
| Small organisation with few integrations | Application identities from day one | Cheaper to start right than to migrate later; no add-on licence needed for the basics |
Small versus large organisations. A small team can usually replace its two or three bots in a day, and the main saving is the seat. A large enterprise will find hundreds of user-style service accounts, many feeding RPA platforms and vendor connectors; there the sequence matters more than the end state, so prioritise accounts with admin roles, MFA exclusions or tenant-wide data access.
Decision checklist. Before approving any new automation identity, ask: does an API and application permission exist for this action; can the credential be federated or managed; can the grant be scoped to named resources; who is the named owner and the business owner; how will the identity be disabled when the integration ends; and does anything in the platform require a human licence.
Worked scenario: a reporting bot in Microsoft 365
A finance team runs a nightly script as svc-reports@, a licensed user excluded from MFA, that reads a shared mailbox, writes a spreadsheet to SharePoint and runs an Azure PowerShell command to resize a VM. Three analysts know the password. Under Phase 2 enforcement the PowerShell step starts failing because it is a create, update or delete operation from a user identity.
- Inventory: list every sign-in for the account across interactive and non-interactive logs to find all consumers, including one analyst using it from a laptop.
- Split: create one app registration for the mailbox and SharePoint work and use the VM's existing automation host managed identity for the Azure step.
- Scope: grant
Application Mail.Readthrough Exchange RBAC for Applications with a management scope covering only the shared mailbox, verified withTest-ServicePrincipalAuthorization, and grant a SharePoint site-scoped permission rather than tenant-wide file access. - Credential: use a certificate held in a vault, with owners set on the registration.
- Protect: add a Conditional Access for workload identities policy in report-only mode restricting the service principal to the automation host's named location, then turn it on.
- Retire: block sign-in on
svc-reports@, watch for failures for two weeks, remove its licence and delete it.
Migrating safely
- Discover: find user accounts with non-interactive sign-ins at fixed times, sign-ins from servers, MFA or conditional access exclusions, names like svc, bot or robot, and accounts with no manager attribute.
- Assign owners: give each candidate a named owner before touching it; see How to assign owners to orphaned service accounts.
- Map consumers and permissions: record every job, host and person using the account and the minimum permissions each needs.
- Build the replacement: one application identity per integration, credential-free where possible, scoped to resources.
- Run in parallel: cut over one consumer at a time and keep the bot account enabled but monitored.
- Block, then delete: block sign-in, wait one full business cycle, then remove licences and delete. Re-enabling the user is the rollback.
- Prevent regression: require approval for new accounts that are excluded from MFA or flagged as service accounts, and offer a documented application identity path instead.
Detection and measurement
Monitor both populations. In Entra ID the sign-in logs separate interactive user, non-interactive user, service principal and managed identity sign-ins; blocked workload sign-ins appear on the Conditional Access tab of service principal sign-ins. In Google Workspace, review domain-wide delegation grants and token activity; in GitHub, the organisation audit log for app installations and machine user activity; in Salesforce, login history and event monitoring for integration users. See the Google Workspace Audit Log Detection Guide and Salesforce Event Monitoring Guide.
- Alert on: interactive sign-ins by accounts tagged as bots; new credentials added to existing app registrations; new consent or domain-wide delegation grants; bot sign-ins from new locations.
- Metric 1: number of user accounts used for automation, trending to a small, documented exception list.
- Metric 2: percentage of automation identities with a named owner (target 100%).
- Metric 3: number of accounts in MFA or conditional access exclusion groups.
- Metric 4: percentage of application identities using credential-free or certificate authentication rather than secrets or keys.
- Metric 5: application identities with no sign-in in 90 days.
Common failure patterns
- Migrating the credential, not the privilege: the bot was a Global Administrator, so the new app gets
Directory.ReadWrite.All. See How to find high-privilege Microsoft Graph application permissions. - One app identity for everything: a single "integration" service principal shared by ten jobs recreates the shared bot problem with better logging.
- Forgotten test and legacy identities: the Midnight Blizzard breach combined an unprotected legacy test account with a legacy OAuth app holding elevated access.
- Delegation left after the project: migration tools keep domain-wide delegation long after the migration; Google advises deleting clients you no longer need.
- Stale registrations: owners leave and secrets outlive them; see How to find and remove stale service principals in Entra ID.
Framework mapping
| Framework | Reference | How it applies |
|---|---|---|
| NIST CSF 2.0 | PR.AA-01, PR.AA-05, DE.CM-03 | Manage identities and credentials for services; least privilege; monitor technology usage |
| NIST SP 800-53 Rev. 5 | IA-9, IA-2, IA-5 | Service identification and authentication instead of reusing organisational user authentication; authenticator management |
| NIST SP 800-53 Rev. 5 | AC-2, AC-6, AU-2 | Account management and removal, least privilege, event logging for attribution |
| CIS Controls v8.1 | Safeguard 5.5 | Inventory of service accounts with owner and purpose |
| ISO/IEC 27001:2022 Annex A | A.5.16, A.5.17, A.5.18 | Identity management, authentication information, access rights |
| MITRE ATT&CK | T1110.003, T1078.004, T1098.001, T1528, T1550.001 | Password spraying of bots, cloud account abuse, added app credentials, token theft and reuse |
Practitioner checklist
- Inventory every user account used for automation and tag it, with a named owner and business owner.
- Remove MFA and conditional access exclusions for bots; replace them with location-scoped policies or application identities.
- Create one application identity per integration, never one shared across jobs.
- Use managed identities, workload identity federation or GitHub App installation tokens before certificates, and certificates before secrets or keys.
- Scope grants to resources: Exchange RBAC for Applications, GitHub App repository selection, narrow delegation scopes, Salesforce permission sets.
- Remove unscoped tenant-wide grants after adding scoped ones, because grants are additive.
- Block sign-in, wait a full business cycle, then delete retired bot accounts and reclaim licences.
- Alert on new app credentials, consent grants and interactive sign-ins by bot accounts.
Standards and references
- Microsoft Learn: Application and service principal objects in Microsoft Entra ID
- Microsoft Learn: Mandatory Microsoft Entra multifactor authentication
- Microsoft Learn: Conditional Access for workload identities
- Microsoft Learn: Role Based Access Control for Applications in Exchange Online
- Google Cloud: Service accounts overview
- Google Workspace Admin Help: Control API access with domain-wide delegation
- GitHub Docs: Deciding when to build a GitHub App
- Salesforce Help: Integration user licence and API-only profile
Related NHI Mgmt Group resources: API Keys vs Service Accounts · Entra ID Applications and Consent Guide · GitHub and GitHub Actions Security Guide · Google Workspace Security Guide · Salesforce Security Guide · NHI Offboarding and Decommissioning Guide