Skip to content

Add Google Health API authorization support#332

Merged
this-Aditya merged 11 commits into
devfrom
google-health-api
Jun 4, 2026
Merged

Add Google Health API authorization support#332
this-Aditya merged 11 commits into
devfrom
google-health-api

Conversation

@this-Aditya

Copy link
Copy Markdown
Member

A new authorization service handles Google's oauth2 flow.
Because the same participant may already have a Fitbit account from before the Google Health migration, the identity payload also carries an optional legacy Fitbit user ID, so we can keep both linked to the same RestSourceUser without losing history.

PKCE is enabled for Google as an extra security layer on top of the standard oauth2 flow. If it turns out Google's auth servers don't play nicely with the PKCE flow in , I'll drop it and fall back to the plain oauth2 path.

@yatharthranjan yatharthranjan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @this-Aditya, looks nice. Has this been tested working? If so, can we release this soon (so at least we can authorise new participants on this, we can always pull the data later)

clientId: <GOOGLE_CLIENT_ID>
clientSecret: <GOOGLE_CLIENT_SECRET>
scope: https://www.googleapis.com/auth/googlehealth.activity_and_fitness.readonly https://www.googleapis.com/auth/googlehealth.health_metrics_and_measurements.readonly https://www.googleapis.com/auth/googlehealth.sleep.readonly https://www.googleapis.com/auth/googlehealth.profile.readonly
oauthVersion: oauth2

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this required config? should it not be oauth2 by default?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it is OAuth 2.0 by default. I only kept it here to highlight it.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

likely remove it if that is the default and does not require configuration

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I do it now, or after the Garmin migration? We might be able to remove this configuration completely then, since we'll only be left with oauth 2.0.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes i think for garmin, it should still be configurable if needed (especially for legacy deployments and until Garmin forces use of OAuth2.0)

Comment thread authorizer-app-backend/authorizer.yml Outdated
tokenEndpoint: https://oauth2.googleapis.com/token
clientId: <GOOGLE_CLIENT_ID>
clientSecret: <GOOGLE_CLIENT_SECRET>
scope: https://www.googleapis.com/auth/googlehealth.activity_and_fitness.readonly https://www.googleapis.com/auth/googlehealth.health_metrics_and_measurements.readonly https://www.googleapis.com/auth/googlehealth.sleep.readonly https://www.googleapis.com/auth/googlehealth.profile.readonly

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what about other scopes like - nutrition, irn, ecg, location (some studies have been explicitly requesting location records for activities recently so would be good to include if possible)?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, we can add these, but google docs says that we can only request the scopes for which we are collecting data. So, if we want to increase the number of data points, we can add them

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes shoudl at least add nutrition, irn and ecg

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay

@this-Aditya

Copy link
Copy Markdown
Member Author

Has this been tested working?

Yeah, I've tested it. If you'd like, you can also verify it on staging.

If so, can we release this soon (so at least we can authorise new participants on this, we can always pull the data later)

I think that even if we release it soon, we still need to pass google's verification process and CASA, which I think will take some time.

One more thing -- when participants authorize google, the current flow deregisters them from fitbit. If we initially add this to the rest sources only, I think it would be nice if they could choose a start date later, and the historical data would then be covered by backfill. Otherwise, we'll only receive data from the start date onward through push notifications.

@yatharthranjan

Copy link
Copy Markdown
Member

I think that even if we release it soon, we still need to pass google's verification process and CASA, which I think will take some time.

I think for new deployments it would work up to 100 users without verification?

One more thing -- when participants authorize google, the current flow deregisters them from fitbit. If we initially add this to the rest sources only, I think it would be nice if they could choose a start date later, and the historical data would then be covered by backfill. Otherwise, we'll only receive data from the start date onward through push notifications.

If the updated push endpoint is not deployed yet (only authorise in updated rest-source-auth), then when we are ready and do deploy push-endpoint, should it not backfill from the start date?

if (sourceTypeOauthMap[GARMIN_AUTH].equals("oauth2", ignoreCase = true)) {
// Bind Garmin service based on configured oauthVersion: "oauth2" → PKCE flow, "oauth1" → legacy flow.
val garminUsesPkce = restSourceClients.clients.firstOrNull { it.sourceType == GARMIN_AUTH }?.usesPkce == true
if (garminUsesPkce) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think more readable to just use oauthVersion from config here

@this-Aditya this-Aditya Jun 2, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've updated this in PR #333. As this PR derives usesPkce from the RestSourceClient, I think that's a better place to handle it than doing it here.


bind(OAuth2RestSourceAuthorizationService::class.java)
.to(RestSourceAuthorizationService::class.java)
.named(FITBIT_AUTH)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we somehow mark this as deprecated?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice if we could do this after september 2026, as they will still receive data from the fitbit app until september if they signed up using their google account.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think ok to mark as deprecated (not decomissioned), with details on when it will be non-functional (sept 2026)

@this-Aditya

Copy link
Copy Markdown
Member Author

I think for new deployments it would work up to 100 users without verification?

Yeah, there are 100 users in testing, but while the app is in testing, we need to manually add users' email addresses. (Alternatively, could you try making the user internal? I can't do that) Screenshot 2026-06-02 at 17 08 37

If we publish the app without verification, users can still select the advanced options and proceed with authorization, although they will see this warning:
Screenshot 2026-06-02 at 17 09 06

@this-Aditya

Copy link
Copy Markdown
Member Author

If the updated push endpoint is not deployed yet (only authorise in updated rest-source-auth), then when we are ready and do deploy push-endpoint, should it not backfill from the start date?

Sorry, I meant that the push endpoint is also deployed. But this version explicitly handles the inconsistencies between the documentation and the actual responses. Based on the real responses, we are only rejecting some data that contains partial information, otherwise, it is working perfectly fine on stage.

@yatharthranjan

Copy link
Copy Markdown
Member

I think for the new deployments we can live with the warning as it will be better than asking participants to authorise again. But i will confirm with the study team what they prefer.

how long does CASA review take?

@this-Aditya

Copy link
Copy Markdown
Member Author

I think for the new deployments we can live with the warning, as it will be better than asking participants to authorise again. But I will confirm with the study team what they prefer.

Yeah, but we can only recruit 100 participants, and we are now aiming for one client ID (I assume), so it would be across all projects. Is it sufficient before we get verified?

how long does CASA review take?

It depends on which third-party assessor lab we pick, and also varies by tier (we need at least Tier 2, or maybe Tier 3). But I think it is going to take substantial time. Some mention it takes 1-3 weeks once testing starts (or 2-4 weeks for Tier 3). And as we request restricted scopes, it can take longer (Google says this).

yatharthranjan
yatharthranjan previously approved these changes Jun 2, 2026

@yatharthranjan yatharthranjan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, please merge the base branch (outdated atm)

@mpgxvii mpgxvii self-requested a review June 4, 2026 07:51

@mpgxvii mpgxvii left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! LGTM.

@this-Aditya this-Aditya merged commit 2906310 into dev Jun 4, 2026
11 of 14 checks passed
@this-Aditya this-Aditya deleted the google-health-api branch June 4, 2026 07:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Migrate source authorization from Fitbit OAuth to Google Health API OAuth

3 participants