Why Uninstalling a Connector Does Not Revoke OAuth Access
Learn why removing a plugin or connector can leave OAuth authorization active, how to revoke it correctly, and how to verify the disconnect.
Table of Contents10 sections

You remove a connector, restart the application, and still see the service as connected. It feels like the uninstall failed. Often it did exactly what it was supposed to do.
The confusing part is that removing local integration code and revoking remote OAuth authorization are different operations. A plugin can disappear from your machine while the provider still has an authorization grant, refresh token, browser session, or cached connection record associated with the account.
The reliable fix is to identify which layer still considers the integration active, revoke the relevant authorization at the provider, clear local credentials when appropriate, then verify the connection with a fresh authenticated request.
The Four Layers Behind a “Connected” Integration
Most OAuth-backed integrations have more state than their user interface suggests.
A useful mental model is:
local integration
|
v
stored credentials
|
v
OAuth authorization grant
|
v
provider session / API access
Uninstalling usually affects the first layer. Depending on the application, it may also delete locally stored credentials. It does not automatically prove that the authorization server has invalidated the grant.
That separation is intentional. OAuth allows a resource owner to grant access to a client without making the client’s installation lifecycle the authority over the provider account.
This is similar to configuring an external tool through a portable MCP configuration: the local configuration describes how to reach a service, but the service still controls whether the presented credential is authorized.
Uninstall Is Not the Same as Revoke
Consider a desktop application that stores a refresh token after OAuth consent.
Removing the application can delete its executable and configuration files. But if the provider still recognizes the authorization grant, reinstalling the client or restoring its credential store may make the integration appear connected again.
OAuth 2.0 Token Revocation, standardized in RFC 7009, exists specifically so a client can tell an authorization server that a token is no longer needed. The specification requires support for revoking refresh tokens and recommends support for access-token revocation.
The important distinction is:
| Action | What it normally changes |
|---|---|
| Disable plugin | Stops local code from running |
| Uninstall plugin | Removes local integration files |
| Sign out | Ends a local or provider session, depending on implementation |
| Delete cached credentials | Removes the client’s local copy of tokens |
| Revoke OAuth authorization | Invalidates authorization at the provider |
| Remove provider-side app access | Removes the account’s authorization relationship |
Those actions can overlap in a well-designed product, but you should not assume they do.
Start by Asking Who Says It Is Still Connected
Before deleting more files, determine where the “connected” signal comes from.
There are three common cases.
The local application still shows the integration
The application may be reading a cached connection record rather than testing the remote API.
Restart the application and inspect its integration settings. If it exposes a disconnect action, use that before manually deleting files because the action may also revoke remote credentials.
The provider still lists the application
This is the strongest sign that uninstalling locally did not remove the provider-side authorization.
For example, Cloudflare documents a Manage OAuth authorizations area where users can view authorized applications and revoke access. That operation lives with the provider because the provider owns the authorization grant.
Google similarly documents a revocation endpoint for OAuth access and refresh tokens.
API calls still succeed
This is the most useful technical test.
If an authenticated request succeeds using a credential you expected to be invalid, the credential or a related grant may still be active. Do not infer revocation from the UI alone.
A small verification probe is enough:
curl --fail-with-body \
-H "Authorization: Bearer $ACCESS_TOKEN" \
https://api.example.com/me
Use a harmless read-only endpoint. Never test disconnection by performing a destructive API operation.
Revoke at the Authorization Boundary
When you need a real disconnect, revoke access where authorization is controlled.
The exact mechanism depends on the provider. Common options are:
- a Disconnect or Revoke access button in the provider account;
- an OAuth token revocation endpoint;
- deletion of a provider-specific API token;
- removal of an application authorization or grant.
RFC 7009 defines an HTTPS revocation endpoint pattern. A simplified request looks like this:
curl -X POST \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "token=$REFRESH_TOKEN" \
https://provider.example.com/oauth/revoke
Do not copy a generic endpoint into production. Use the provider’s documented revocation endpoint and authentication requirements.
Also pay attention to provider semantics. Revoking one access token does not universally mean every related credential is invalidated. RFC 7009 explicitly allows authorization servers to differ in how revocation affects related access tokens, refresh tokens, and grants.
Google’s documentation is a good example of why provider-specific behavior matters: its OAuth documentation describes revocation in terms of the scopes granted to a project and the tokens issued under that authorization.
Why a Connection Can Look Alive After Revocation
Even after a correct revoke operation, the interface may not update immediately.
Several caches can be involved:
provider authorization state
|
+--> API token validity
|
+--> application connection cache
|
+--> browser session
|
+--> background sync state
A stale UI does not prove that the token still works. Likewise, a missing UI badge does not prove that access has been revoked.
This is the same troubleshooting principle used in debugging broken deployment flows: verify each boundary independently instead of treating one visible symptom as proof of the whole pipeline.
After revocation, refresh the provider page, restart the client, and run a read-only API check with the old credential if doing so is safe. The expected result is an authentication or authorization failure.
A Safe Disconnect Checklist
Use this sequence when an integration refuses to disappear:
1. identify the integration and provider
2. disable background jobs that may refresh credentials
3. use the client's disconnect action if one exists
4. revoke provider-side OAuth authorization
5. remove local stored credentials
6. restart the client
7. verify the provider no longer lists the authorization
8. test the old credential against a harmless endpoint
9. reconnect only if a clean authorization is actually needed
The order matters. If a background process can still refresh credentials while you are cleaning up local state, it can make the integration appear to “come back.”
Do Not Delete Secrets Blindly
When troubleshooting authentication, random cleanup can make diagnosis harder.
Before removing credential files or environment variables, identify what they represent. A system may have separate credentials for development, CI, production, or multiple accounts. Deleting the wrong one can break an unrelated deployment without revoking the authorization you actually care about.
Prefer provider-side revocation first when the goal is security. Once the provider no longer accepts the credential, deleting local copies becomes cleanup rather than the primary control.
For CI systems, rotate or remove repository secrets only after confirming which workflow uses them. For desktop tools, check whether credentials live in a system keychain rather than a plain configuration file.
Build Integrations With a Real Disconnect Path
If you are building the integration rather than merely troubleshooting one, treat disconnect as part of the authentication lifecycle.
A robust implementation should:
- stop background refresh work before revocation;
- revoke the refresh token or grant according to provider documentation;
- delete local access and refresh tokens;
- clear cached account metadata;
- make reconnection require a fresh authorization flow;
- surface a useful error if remote revocation fails;
- keep disconnect operations idempotent where possible.
Model the state explicitly:
sealed interface ConnectionState {
data object Disconnected : ConnectionState
data object Connecting : ConnectionState
data object Connected : ConnectionState
data object Revoking : ConnectionState
data class Error(val reason: String) : ConnectionState
}
The application should not move to Disconnected merely because a local file was deleted. It should do so when its chosen disconnect contract has completed.
The Rule to Remember
When a connector still appears active after uninstalling it, do not immediately assume the uninstall mechanism is broken.
Ask which state survived.
Local installation, stored credentials, OAuth authorization, provider sessions, and cached connection metadata are separate layers. A clean disconnect means revoking access at the authorization boundary, cleaning local state, and verifying the result with evidence.
That model applies far beyond one provider. It is useful for IDE extensions, MCP connectors, CI integrations, cloud dashboards, desktop clients, and any other tool that delegates access through OAuth.
Continue Exploring
You Might Also Like

Choosing GitHub Copilot CLI Models Without Wasting Credits
A practical way to choose Copilot CLI models by task complexity, cost, context size, and failure risk instead of defaulting to the most capable option.

Git Worktrees for Parallel AI Coding Agents
Use Git worktrees to give parallel coding agents isolated files and branches without cloning the same repository for every task.

How to Use Google Search Console Data to Prioritize Content
Turn Search Console clicks, impressions, CTR, position, queries, and pages into a practical workflow for choosing what to update or write next.