mcp: delete upstream oauth2 token (#5707)

## Summary

Adds `POST /.pomerium/mcp/routes/disconnect` that allows an MCP client
application to request upstream OAuth2 tokens to be purged, so that a
user may get a new ones with possibly different scopes.

## Related issues

Fix
https://linear.app/pomerium/issue/ENG-2545/mcp-user-should-be-able-to-purge-their-upstream-oauth2-token

## User Explanation

<!-- How would you explain this change to the user? If this
change doesn't create any user-facing changes, you can leave
this blank. If filled out, add the `docs` label -->

## Checklist

- [x] reference any related issues
- [x] updated unit tests
- [x] add appropriate label (`enhancement`, `bug`, `breaking`,
`dependencies`, `ci`)
- [x] ready for review
This commit is contained in:
Denis Mishin 2025-07-08 09:46:45 -07:00 committed by GitHub
parent f5c5326c72
commit 8a89c975d9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 141 additions and 12 deletions

View file

@ -189,3 +189,24 @@ func (storage *Storage) GetUpstreamOAuth2Token(
return v, nil
}
// DeleteUpstreamOAuth2Token removes the upstream OAuth2 token for a given host and user ID
func (storage *Storage) DeleteUpstreamOAuth2Token(
ctx context.Context,
host string,
userID string,
) error {
data := protoutil.NewAny(&oauth21proto.TokenResponse{})
_, err := storage.client.Put(ctx, &databroker.PutRequest{
Records: []*databroker.Record{{
Id: fmt.Sprintf("%s|%s", host, userID),
Data: data,
Type: data.TypeUrl,
DeletedAt: timestamppb.Now(),
}},
})
if err != nil {
return fmt.Errorf("failed to delete upstream oauth2 token for session: %w", err)
}
return nil
}