Most SaaS-to-SaaS integrations get access in one of two ways, an OAuth app that holds tokens or a dedicated integration service account whose password or API token sits in the other system, and teams rarely choose deliberately between them. The choice decides who the integration acts as, how much it can reach, how its credential can be revoked and what you see in the logs when it is misused. This guide compares the two models for connecting SaaS platforms to each other and to internal systems, explains the delegated and app-only variants of OAuth, gives a decision table and a migration path, and lists what to monitor. It is for SaaS administrators, integration owners, IAM and security teams. Example platforms are listed alphabetically. For the wider SaaS picture see the SaaS Security Guide.
Key takeaways
- The real question is who the token represents. An OAuth app can act as a signed-in person, as itself (app-only), or as a dedicated integration user; each has a different blast radius.
- OAuth apps give you scopes, consent and revocation. Access is granted per scope, recorded as a grant you can review, and revoked without changing anyone's password.
- Integration service accounts are clear but credential-heavy. A dedicated account gives a stable owner and audit trail, but a password or API token stored in another vendor's system is a secret you must rotate yourself.
- Never use a person's account for an integration. When that person leaves or changes role, the integration breaks or, worse, keeps their access.
- Long-lived refresh tokens are the shared weak spot. Recent Salesforce integration incidents involved OAuth tokens that stayed valid for years; set expiry, IP restrictions and per-integration monitoring whichever model you pick.
What each one actually is
OAuth app (connected app, app registration, marketplace app): a registered client in the target platform. An administrator or user grants it scopes, and the platform issues an access token and usually a refresh token. Three variants matter:
- Installation-based apps: some platforms scope the app to selected resources at install time. GitHub describes GitHub Apps as having targeted permissions, being installed on chosen repositories, and using installation access tokens that currently expire after one hour, while OAuth app tokens are long-lived by default. GitHub states that GitHub Apps are generally preferred over OAuth apps.
- App-only (application permissions): the app acts as itself with no user present. Google Workspace domain-wide delegation is one form: Google states that with it the app has access to the data belonging to all of your users. Microsoft notes that with application permissions the application is able to access any data the permission is associated with, and that these permissions generally need administrator consent.
- Delegated (on behalf of a user): the app acts as the person who authorised it. Microsoft's identity platform states that with delegated permissions the application is not able to access anything the signed-in user could not access. Access ends, or should end, when that user loses access.
Integration service account: a dedicated, non-human account created in the target platform for one integration. The integration authenticates as that account with a password, an API token, a certificate or by authorising an OAuth app as that user. Salesforce, for example, offers a Salesforce Integration user licence and a Minimum Access - API Only Integrations profile that restricts the user to API access with no user interface.
The two models overlap: a well-run integration often uses an OAuth app authorised by a dedicated integration user, which combines scoped tokens with an account you can own and restrict. The models to avoid are a personal account used as an integration and a shared admin account whose password is pasted into a vendor's settings page. See the API Keys vs Service Accounts guide for the credential side of this choice.
Side-by-side comparison
| Dimension | OAuth app (delegated) | OAuth app (app-only or installation) | Integration service account |
|---|---|---|---|
| Acts as | The authorising user | The app itself | A dedicated non-human user |
| Permission boundary | Granted scopes, capped by the user's own access | Granted application permissions or installation scope | Roles, profiles and permission sets on the account |
| Credential held by the integration | Access and refresh tokens | Client secret, certificate or private key, and short-lived tokens | Password, API token or certificate, sometimes plus OAuth tokens |
| Consent and approval | User or admin consent per scope | Admin consent | Admin creates the account and assigns roles |
| Revocation | Revoke the grant or tokens; disabling the user also cuts access | Remove the app, delete the secret or uninstall | Disable the account or rotate its credential |
| Effect of staff changes | Breaks or keeps access when the authorising user leaves | Unaffected | Unaffected, if ownership is recorded |
| Audit trail | Actions appear as the user, with the app as client | Actions appear as the app | Actions appear as the integration account |
| Licence | Uses the user's licence | Usually none | Often a seat or integration licence |
| Main risk | Inherits a person's broad access; consent phishing | Tenant-wide data access if scopes are broad | Long-lived static secret stored outside your control |
Risks of each model
OAuth apps
- Token custody at the vendor: the refresh token lives in the integration vendor's environment. In the Salesloft Drift breach, OAuth tokens for a chatbot integration were taken from the vendor's cloud environment and used to bulk-export data from customers' Salesforce instances. The Gainsight Salesforce breach involved 285 tokens that were two to eight years old.
- Broad scopes: full-access or offline scopes requested by default and approved without review.
- User-consented sprawl: users approving apps that nobody inventories. Salesforce's default connected app setting is "All users may self-authorize". See the Consent Phishing and Illicit OAuth Grants Guide.
- Persistence: attackers add credentials to existing app registrations (ATT&CK T1098.001 Additional Cloud Credentials) or reuse stolen tokens (T1528 Steal Application Access Token, T1550.001 Application Access Token).
Integration service accounts
Microsoft's guidance is direct on one point: it recommends not using a Microsoft Entra user account as a service account, and using a managed identity or service principal instead.
- Static secret in a third party: a password or API token configured in another platform is rarely rotated, because rotation means touching both sides.
- Over-privileged roles: the account is given an admin profile "to make it work" and keeps it. Salesforce notes that its API Integration permission set licence carries many permissions similar to the System Administrator profile, so what you assign on top matters.
- Interactive use: people sign in with the integration account, which hides who did what and can bypass MFA policies. See How to detect interactive logons by service accounts.
- Orphaned accounts: the integration is retired but the account and credential remain. The How to assign owners to orphaned service accounts guide covers the fix.
Which to use: decision table
| Scenario | Recommended model | Notes |
|---|---|---|
| Vendor offers an installation-based app with resource selection | Installation app | Select only the resources needed; short-lived tokens by design |
| Integration needs a person's own data (their mailbox, calendar, files) | Delegated OAuth | Narrow scopes; admin approval for the app; review grants each quarter |
| Background sync of organisation data (CRM to data warehouse, ticketing to chat) | OAuth app authorised by a dedicated integration user, or app-only with narrow permissions | Gives a non-personal owner, scoped tokens and a clear audit identity |
| Platform supports only username and password or API token for integrations | Integration service account | API-only profile, no interactive login, IP restriction, rotation schedule |
| Integration needs tenant-wide access (backup, security monitoring, eDiscovery) | App-only OAuth with admin consent | Treat as privileged; restrict to named resources where the platform allows |
| Internal service calling a SaaS API you control | App-only OAuth (client credentials) with certificate or federated credential | See the Machine-to-Machine OAuth (Client Credentials) Guide |
| Proof of concept or trial | Delegated OAuth with a test user | Remove the grant at the end of the trial |
Trade-offs: OAuth wins on scoping and revocation but moves credential custody to the vendor, so vendor security and token lifetime matter. Integration service accounts win on clarity of identity and are sometimes the only option, but they put a static secret into another system. Small organisations should standardise on admin-approved OAuth apps with a dedicated integration user per critical integration, since it needs no extra tooling. Large organisations should add a central integration register, admin-only consent, conditional IP restrictions and per-integration monitoring in the SIEM or an SSPM tool.
Hardening whichever model you use
| Control | OAuth app | Integration service account |
|---|---|---|
| Who can approve | Admin consent only; in Salesforce set Permitted Users to "Admin approved users are pre-authorized" | Account created by the platform admin team through a request |
| Least privilege | Narrow scopes; RFC 9700 section 2.3 says access tokens should be audience-restricted and limited to the resources and actions needed | API-only profile or role; no admin role; object-level permissions only |
| Credential lifetime | Set a refresh token policy, for example Salesforce "Expire refresh token if not used for" or "Expire refresh token after", instead of the default "Refresh token is valid until revoked" | Rotation schedule for the password or API token, ideally from a secrets manager |
| Network | Keep "Enforce IP restrictions" and limit to the vendor's published ranges where supported | Login IP ranges on the account or profile |
| Interactive use | Not applicable to app-only; block user sign-in for integration users | Block interactive login; alert on any UI session |
| Ownership | Business owner and technical owner recorded per app | Owner recorded on the account and in the inventory |
| Review | Quarterly grant and scope review; Google recommends checking scopes and removing those not required or actively used | Quarterly role review and last-used check |
RFC 9700 (BCP 240, January 2025) also says refresh tokens for public clients must be sender-constrained or use refresh token rotation, and that the resource owner password credentials grant must not be used. An integration that asks for a user's password to obtain OAuth tokens is a sign to choose a different integration method.
Migrating to a safer pattern
- Inventory. List every connected app, app registration, marketplace app and integration account per platform, with scopes, authorising user, token issue date and last use. Platform how-tos: How to audit GitHub Apps and OAuth apps in an organisation, How to Inventory third party oauth apps in google workspace, How to review Salesforce connected apps and integration users.
- Find personal integrations first. Integrations authorised by, or running as, a named employee are the highest priority, because a leaver event will break them or leave access behind.
- Create the target identity. A dedicated integration user with an API-only profile, or an app-only registration, with an owner and the narrowest scopes.
- Re-authorise in parallel. Connect the integration with the new identity while the old one still works, and compare results for a test period.
- Cut over and revoke. Switch the integration, then revoke the old grant or rotate the old credential. Keep the old configuration documented for one cycle so you can roll back by re-authorising, not by restoring a shared password.
- Restrict and monitor. Apply IP restrictions and refresh token expiry, then add the integration to monitoring.
Detection and measurement
- Per-integration baselines: source IP ranges, API volume, objects queried and time of day. Alert on bulk export, new source addresses and queries against objects the integration never touched.
- New grants and credentials: alert on new admin-consented app permissions, new secrets or certificates added to existing app registrations, and new integration users.
- Interactive sign-in by integration accounts: any UI session is suspicious.
- Vendor incident trigger: when a vendor reports a breach, revoke all its tokens and rotate credentials that appeared in data it could read. The SaaS integration token breach response guide sets out the steps.
| Metric | Target |
|---|---|
| Integrations running as a named employee | Zero for production integrations |
| OAuth apps with a recorded owner and scope justification | 100% |
| Refresh tokens older than your maximum lifetime (for example 12 months) | Zero |
| Integration accounts with interactive login allowed | Zero |
| Integrations with IP restriction applied where the platform supports it | Rising quarter on quarter, 100% for tenant-wide access |
| Grants unused for 90 days and not removed | Zero after each quarterly review |
Common failure patterns
- Integration tied to an admin's personal account. It inherits that admin's full access and breaks or lingers when they leave.
- Tokens that never expire. Default refresh token policies left at "valid until revoked" for years, as in the Gainsight case above.
- Shared integration password. One service account password used by several integrations, so revoking one breaks all and logs cannot separate them.
- Self-authorised apps. Users approve apps with mail or file scopes that never reach an inventory.
- No vendor-incident playbook. When an integration vendor is breached, nobody knows which tokens exist or how to revoke them quickly.
- Admin profile on the integration user. Given during setup, never reduced.
Framework mapping
| Framework | Reference | Relevance |
|---|---|---|
| NIST SP 800-53 Rev 5 | AC-2 Account Management; AC-6 Least Privilege; SA-9 External System Services; AU-6 Audit Record Review, Analysis, and Reporting | Integration identities managed and scoped; third-party services governed; activity reviewed |
| NIST CSF 2.0 | PR.AA-01; PR.AA-05; GV.SC-07 | Non-human identities and credentials managed; least privilege; supplier risk monitored over the relationship |
| CIS Controls v8.1 | Safeguard 5.5 Establish and Maintain an Inventory of Service Accounts; 6.8 Define and Maintain Role-Based Access Control | Inventory of integration identities; role-based scoping |
| ISO/IEC 27001:2022 Annex A | A.5.18 Access rights; A.5.19 Information security in supplier relationships; A.8.2 Privileged access rights | Access granted to integrations and to the vendors that hold their tokens |
| MITRE ATT&CK v20 | T1528; T1550.001; T1098.001 | Token theft, token reuse and added credentials on app registrations |
Practitioner checklist
- Inventory every OAuth app, app registration and integration account across your main SaaS platforms.
- Move every production integration off personal accounts to a dedicated integration identity.
- Require admin approval for OAuth apps and block user self-authorisation for high-risk scopes.
- Give each integration its own identity; never share one account or secret across integrations.
- Set refresh token expiry or inactivity limits instead of "valid until revoked".
- Apply IP restrictions to integrations where the vendor publishes egress ranges.
- Use API-only profiles and block interactive login for integration accounts.
- Record a business and technical owner and review scopes quarterly.
- Write and test a revoke-and-rotate runbook for a breached integration vendor.
Worked scenarios
The scenarios below are illustrative examples, not real incidents.
OAuth app scenario: a marketing analytics tool connected to the CRM. A marketing team wants a third-party analytics tool to read campaign and contact data. The platform admin registers it as an OAuth app with admin consent only, grants read-only scopes for the two objects it needs, and sets a refresh token policy so tokens expire if unused for 30 days. Six months later the analytics vendor reports a breach of its own environment. Because the app is in the inventory with its scopes and token issue dates, the admin team revokes its tokens in one action and checks the API logs for bulk exports since the vendor's stated intrusion date.
Integration service account scenario: a nightly HR to finance sync. An internal job copies cost centre changes from the HR system into the finance platform each night. The platform does not support an OAuth client for this job, so the team creates a dedicated API-only integration account with a minimum access profile, a named owner and a certificate stored in a secrets manager. A last-used check flags the account when someone signs in with it interactively from a laptop; the team blocks interactive sign-in for the account, rotates the certificate and adds the event to its detection rules.
Standards and references
- IETF: RFC 9700 Best Current Practice for OAuth 2.0 Security
- GitHub Docs: Differences between GitHub Apps and OAuth apps
- Google Workspace Admin Help: Control API access with domain-wide delegation
- Microsoft Learn: Overview of permissions and consent in the Microsoft identity platform
- Microsoft Learn: Securing service accounts in Microsoft Entra ID
- Salesforce Help: Manage OAuth access policies for a connected app
- Salesforce Help: Salesforce Integration user licence
Related NHI Mgmt Group resources: SaaS Security Guide · SaaS and OAuth Integrations Health Check · Consent Phishing and Illicit OAuth Grants Guide · Machine-to-Machine OAuth (Client Credentials) Guide · SCIM vs JIT Provisioning