Accessing APIs using OAuth on the federated (WordPress) web
1. Felix Arntz / WordCamp Europe 2021
Accessing APIs using OAuth
on the federated (WordPress) web
2. Site Kit is a one-stop solution
for WordPress users to use
everything Google has to offer
to make them successful on the
web.
4. When an application needs to access data from a
third-party application, this typically needs to happen
through an API that the third-party application provides.
Such an API typically requires authentication and
authorization.
5. Various mechanisms for third-party authentication
● Application passwords
● Basic Auth
● JWT
● …
● OAuth 2.0
https://datatracker.ietf.org/doc/html/rfc6749
6. You’ve probably used OAuth 2.0 before...
https://make.wordpress.org/core/2020/03/19/associating-github-accounts-with-wordpress-org-profiles/
7. OAuth 2.0 is widely used
https://developers.google.com/identity/protocols/oauth2/web-server
https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow
https://docs.github.com/en/developers/apps/building-oauth-apps/authorizing-oauth-apps
9. The user-facing OAuth flow
User wants to connect client app to their
third-party service account
Third-party service prompts user for
consent to grant client app access
Client app can now access data from third-party service on behalf of the user through an access token
OAuth consent screen
10. Technical sequence of the three-legged flow
/oauth2/auth/
/wp-admin/oauth2callback/
/wp-admin
/oauth2/token/
redirect
redirect
POST
with client ID
with client ID and secret
11. Glossary of notable OAuth terms
Client ID: persistently identifies the client application
Client secret: “password” for the client ID
Redirect URI: callback URI on client application site that the user is
redirected to after having granted access
Access token: short-lived token needed to issue actual API requests
Refresh token: long-lived token needed to get a new refresh token
(without prompting the user again)
14. Differences between WordPress and traditional use-case
WordPress is distributed
Each WordPress site lives completely
independent of each other
WordPress is open-source
Everyone can browse the source code
This also applies to any other open-source CMS, not just WordPress!
15. Resulting problems for OAuth in WordPress
● Because open-source: The plugin itself cannot keep the client ID and secret
away from its users, since the source code is public.
→ How do we centrally handle client ID and client secret?
● Because distributed: There is no predefined redirect URI that could be
configured in OAuth, since every WordPress site lives independently of each
other.
→ How do we redirect back to the individual WordPress site?
16. The “easy” way*: Client applications for each site
● Configuring a client application is a
technically advanced task
● Getting a client application verified
may require much time
● Each client application needs to be
manually maintained
● This is a no-go (for most audiences)!
* easy for developers,
not for end users!
18. The high-level principles we followed
● User experience: We should not bother users with configuring and maintaining
their own client application.
● Security: We must not compromise on the privacy and security requirements
that the OAuth 2.0 framework has established.
19. Introducing “Site Kit Service”
● Internalizes client credentials
● Proxies all interactions between WP
sites and the Google OAuth server
● Delegates tokens to WP sites
● Every WP site is a client to SKS, but
SKS is the only client to Google OAuth
Site Kit
Service
access
token
site
credentials
client
credentials,
refresh token
authority for client
credentials, access
tokens, refresh tokens
authority for site
credentials,
accesses client
credentials
accesses site
credentials and
access tokens
20. Technical sequence of the “delegation” flow
/oauth2/auth/
/wp-admin/oauth2callback/
/wp-admin
/oauth2/token/
redirect
redirect
POST
with client ID
with client ID and secret
21. Technical sequence of the “delegation” flow
/oauth2/auth/
/oauth2/auth/
/oauth2/callback/
/wp-admin/oauth2callback/
/wp-admin
Site Kit
Service
Site Kit
Service
/oauth2/token/
Site Kit
Service
/oauth2/token/
redirect
redirect
redirect
redirect
POST POST
with client ID
with site ID
with client ID and secret
with site ID and secret
22. A single client, but many sites
Site Kit
Service
client ID & client secret
site ID & site secret
/oauth2/site/
Site Kit
Service
● Site ID identifies a site
● Site secret authorizes that site
● Sites are registered through an extra
Site Kit Service endpoint
● Site credentials are generated upon
registration
23. Verifying site ownership
Site Kit
Service
/wp-admin/verification/
sends verification token
and temporary “site code”
1. Places verification token publicly, e.g.
in a file or an HTML meta tag
2. Exchanges the temporary site code
for the real site credentials via SKS
24. Updated technical sequence of the “delegation” flow
/oauth2/auth/
/oauth2/auth/
/oauth2/callback/
/wp-admin/oauth2callback/
/wp-admin
Site Kit
Service
Site Kit
Service
/oauth2/token/
Site Kit
Service
/oauth2/token/
/oauth2/site/
Site Kit
Service
/wp-admin
Site Kit
Service
site registration proxied OAuth flow
25. Requirements for delegating access tokens
/wp-admin/oauth2callback/ /oauth2/token/
Site Kit
Service
/oauth2/token/
Returns an error if one of the
requirements is not met
Redirects the user to the
appropriate Site Kit Service
screen to meet the requirement
1. The user must be a verified user of
the site.
2. The user must consent to Site Kit
Service delegating the token.
26. Requirements for credentials storage and encryption
WordPress Site Kit Service Google OAuth
Unaware of client credentials Relies on client credentials Controls client credentials
Stores site credentials with encryption Creates and controls site credentials Unaware of site credentials
Stores access token with encryption Passes through access token but does
not store it
Creates and controls access token
Stores encrypted refresh token with
encryption
Passes through encrypted refresh
token but does not store it
Creates and controls refresh token
Learn more about encryption in the WordPress database:
https://felix-arntz.me/blog/storing-confidential-data-in-wordpress/
Site Kit
Service
27. Complete technical sequence of the “delegation” flow
/oauth2/auth/
/oauth2/auth/
/oauth2/callback/
/wp-admin/oauth2callback/
/wp-admin
Site Kit
Service
Site Kit
Service
/oauth2/token/
Site Kit
Service
/oauth2/token/
/oauth2/site/
Site Kit
Service
/wp-admin
Site Kit
Service
site registration proxied OAuth flow
Site Kit
Service
Site Kit
Service
token requirement
checks
29. Best practices for using OAuth in a WordPress plugin
● Rely on a centralized proxy service that internalizes the OAuth client credentials.
● Generate site credentials on demand, as equivalent to the OAuth credentials.
● Require site ownership verification before exposing any credentials or tokens.
● Require explicit delegation consent in addition to OAuth access consent.
● Never expose the client secret or real refresh tokens.
30. How is your WordPress plugin doing?
● Are you using or planning to use third-party service data in your plugin?
● Is the approach you’re using fulfilling UX and security best practices?
● What are any pain points you’re encountering with OAuth in WordPress?
● Would the outlined approach be feasible for your plugin as well?
Let’s discuss!