Couchbase Sync Gateway supports OpenID Connect or OIDC-based client authentication.
In this context, clients may be Couchbase Lite clients that synchronize data with Sync Gateway over the Internet using the websockets-based replication protocol or they could be web frontend or mobile apps accessing Sync Gateway through the public REST endpoint.
In the first blog post in this series, we discussed the fundamentals of OIDC and OAuth2 authentication and authorization flows and in last week’s blog post, we learned more in-depth about OIDC implicit flow-based Sync Gateway client authentication.
In this post, I’ll introduce you to OIDC authorization code flow-based client authentication within the context of Couchbase Sync Gateway replication.
This post assumes familiarity with OIDC and OAuth2 flows for authentication and authorization. If you’re unfamiliar with the flows or need a refresher, please check out the earlier blog posts linked above.
Couchbase Sync Gateway OIDC Configuration
The Couchbase Sync Gateway must be configured for OIDC authentication on a per database basis.
Below is a basic OIDC config for Authorization Code. Refer to the official Couchbase documentation for a complete listing of all OIDC config options.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
"oidc": { "default_provider":"google", "providers": { "google": { "issuer":"https://accounts.google.com", "client_id":"YOUR_CLIENT_ID", "validation_key":"YOUR_CLIENT_SECRET", "callback_url":"http://SYNC_GATEWAY_ADDRESS:4984/default/_oidc_callback", "register":true, "username_claim":"email", "disable_session":false } } } |
issuer
is the authentication URL corresponding to the OIDC identity providerclient_id
is generated as part of the app registration process with the OIDC provider. The client here refers to the Couchbase Lite app or web app. Note that theclient_id
does not correspond to the end user of the app who is technically the resource owner.validation_key
corresponds to theclient_secret
and should be generated as part of the app registration process with the OIDC provider.callback_url
is the URL to be redirected to on Sync Gateway after the client obtains the identity token (ID token).register
flag, if set totrue
, will result in the user being automatically created on Sync Gateway following successful ID token validation.username_claim
corresponds to the JWT claim to be used as the Sync Gateway username. By default, the Sync Gateway username would take the formissuer+subject
whereissuer
refers to the usernameprefix
. The prefix value defaults to the issuer claim and can be configured to use a different claim value via theuser_prefix
config option.disable_session
, if set totrue
, can be used to override the automatic session creation by the Sync Gateway following successful authentication.
Couchbase Sync Gateway OIDC Discovery
On startup, the Sync Gateway connects to the discovery endpoint associated with the configured OIDC provider/issuer to fetch relevant provider metadata. The metadata includes relevant information required for token validation such as issuer public keys, supported encryption algorithms used for encoding the claims in the ID token, etc.
The discovery endpoint corresponds to a well-known discovery URL associated with the issuer. If needed, you can override the URL via Sync Gateway discovery_url config option.
OIDC Authorization Code Flow for Client Authentication
This flow is based on the standard OIDC authorization code flow discussed in the OIDC basics blog (part one of the series).
Authentication
- When a user logs into the Couchbase Lite client app, the client invokes the _oidc REST endpoint on Sync Gateway to initiate the OIDC Auth Code flow.
- Sync Gateway redirects the client app to the OIDC provider URL.
- The client initiates the authorization code flow with the OIDC provider to retrieve the authorization code. This is per standard OIDC flow procedures outlined in the OIDC basics blog.
- The client is redirected to the Sync Gateway with the authorization code. The redirect URL corresponds to the OIDC callback REST endpoint.
- The client app invokes the OIDC callback REST endpoint with the authorization code.
- The Sync Gateway exchanges the code for the ID token, the refresh token, and the access token by sending a suitable request to the OIDC provider. The request includes the
client_id
andclient_secret
which were configured on Sync Gateway. This allows the OIDC provider to validate that only trusted clients are able to retrieve the tokens. - Sync Gateway validates the ID token locally. Following successful token validation, a corresponding
UserCtx
object is created.- The metadata retrieved from the OIDC Provider Discovery URL during startup is used to validate the token in “offline mode.”
- If this is the first time that the user is authenticating with the Sync Gateway and if a corresponding user does not exist on the server, the Sync Gateway automatically creates a user if the
register
config option is set totrue
.- Note: The user that is created is not associated with any access grants such as channels or roles, so this auto registration would work for public users with no user-specific access grants. We will discuss a flow later in this post that describes how to create users with user-specific access grants.
- A session is created for the user with an idle session timeout of 24 hours. The session is created ONLY IF the
disable_session
is set to false.
- The session ID and refresh tokens are sent back to the client app.
- Client app initiates a replication by setting the session ID as the session cookie using the
SessionAuthenticator
. - Sync Gateway checks the validity of the session to determine if the session has been deleted or has expired.
- If the session is active, the session gets auto-extended to 24 hours if 10% of idle session timeout has elapsed.
- Following successful initialization, replication proceeds as usual and document changes on the client app and Sync Gateway side are synchronized.
- If the user is deleted during an active replication, the replication is terminated.
- If the access grants associated with the user have changed, then documents that get impacted by the updated access grants won’t be replicated. So for instance, if a user loses access to a channel, then the documents in that channel won’t be pulled.
Token Refresh
One of the advantages of the authorization code flow is that in addition to the ID token, a refresh token is also returned to the client app. The client app can use the refresh token to automatically request a new auth code without requiring the end user to reauthenticate with their login credentials.
- When the client app wants to refresh the token, it makes a request to the OIDC refresh REST endpoint with the refresh token.
- The Sync Gateway exchanges the refresh token for the updated ID token and access token by sending a suitable request to the OIDC provider. The request includes the
client_id
andclient_secret
which were configured on Sync Gateway. This allows the OIDC Provider to validate that only trusted clients are able to retrieve the tokens. - Sync Gateway validates the ID token locally. Following successful token validation, a corresponding
UserCtx
object is created.- The metadata retrieved from the OIDC provider discovery URL during startup is used to validate the token in “offline mode.”
- A new session is created for the user with an idle session timeout of 24 hours. The session is created ONLY IF the
disable_session
is set to false.
- The session ID and ID tokens are sent back to the client app.
- The client app initiates a replication using session ID as the session cookie following the same steps as in the previous flow.
Associating Access Grants to Authenticated Users
Sync Gateway channels and roles are two key elements of Sync Gateway’s access control mechanism. They define the access grants associated with a user, dictating the set of documents that the user has read and write access to.
There are a couple of options to assign access grants to a user:
- Dynamic assignment of users to channels or roles by the sync function with the access() or role() APIs using an access grant document which specifies the channels or roles that a user must be assigned to.
- Static assignment of grants to users via the admin _user REST API.
As you’ve seen from the previous flows, the Couchbase Sync Gateway can be configured to automatically create the authenticated user on the Sync Gateway following successful authentication. However, the created user is not associated with any access grants. This works for a public user with public channel access.
But what if you wanted to assign user-specific access grants? This task is typically handled via a backend application server that would be responsible for creating or updating the user. The Sync Gateway is only responsible for OIDC authentication.
Here is a typical flow:
- A backend process or app server is responsible for registering users with the OIDC provider.
- Subsequent to the registration, the app server creates a corresponding user on Sync Gateway via the
_user REST API
or by adding a suitable access grant document. - Next time the user logs into the app, OIDC authentication proceeds using the authorization code flow procedures described earlier.
- Regardless of the type of OIDC flow, once the ID token is validated by the Sync Gateway, the Sync Gateway does not create a user because it already exists.
- Replication proceeds as usual using the authenticated user.
- If a user is updated on the OIDC Provider, the app server updates the corresponding user on the Sync Gateway via the
_user REST API
or by updating the access grant document.- If a user is deleted during an active replication, the replication is terminated.
- If the access grants associated with the user have changed, then documents that get impacted by the updated access grants won’t be replicated. For instance, if a user loses access to a channel then the documents in that channel won’t be pulled.
Frequently Asked Question (FAQ)
Which is better: implicit flow or authorization code flow?
There isn’t a preferred flow from my perspective. The implicit flow is simple and is generally preferred by most of our users. Since mobile apps have a secure store, the ID and access tokens can be securely stored in the local keystore on the device. You can learn more in this blog post about how to leverage OIDC implicit flow for Sync Gateway authentication.
The advantage of the authorization code flow is that it provides slightly better security. This is because the tokens are granted to the Sync Gateway in exchange for the authorization code only when the OIDC Provider is presented with a valid client_id
and client_secret
. This ensures that only authenticated clients get the tokens. Also the refresh tokens allow refreshing of the auth sessions without requiring the end user to enter their credentials every time.
More Resources
In this post, we described OIDC authentication support in Sync Gateway. Here are some additional resources you might want to check out:
If you have questions or feedback, please leave a comment below or email me at priya.rajagopal@couchbase.com. The Couchbase Forums are another good place to reach out with questions.
Acknowledgements
I would like to thank Sync Gateway architect Adam Fraser for his input on this blog post.
Catch up with the rest of the posts in this series on authentication and authorization: