From 3930d739f848add98644d2159c555858273bf72f Mon Sep 17 00:00:00 2001 From: Keith Lawrence Date: Mon, 18 Sep 2023 11:46:25 +0100 Subject: [PATCH] Add documentation about the pipeline for One Login updates --- docs/one-login-pipeline.md | 61 ++++++++++++++++++++++++++++++++++++++ docs/one-login.md | 52 +++++++++++++++++--------------- 2 files changed, 89 insertions(+), 24 deletions(-) create mode 100644 docs/one-login-pipeline.md diff --git a/docs/one-login-pipeline.md b/docs/one-login-pipeline.md new file mode 100644 index 00000000..a92cdef2 --- /dev/null +++ b/docs/one-login-pipeline.md @@ -0,0 +1,61 @@ +# One Login to GOV.UK pipeline + +One Login is an OpenID Connect (OIDC) provider, which GOV.UK accounts are based on. Currently the only thing that a GOV.UK account handles is email alert subscriptions. Subscriptions are handled in two ways, one that requires a GOV.UK account, one that does not. (As of time of writing, there are 2.5 million subscribers using the old no-account method, 211,000 using the new account-based method). + +So a user who has subscribed to email alerts will create records in 3 places if an account is required: + +- A One Login account record in One Login +- An account record in account-api +- A subscriber record in email-alert-api + +…but only one (a subscriber record in email-alert-api) if an account is not required (this is the magic-email path) + +Therefore not all Subscriber records in email-alert-api will have a corresponding account record in account-api, but currently all account-api records have a corresponding subscriber record in email-alert-api. + +## How Email Alert records are created + +There are a series of paths in email-alert-frontend which end up with an email subscription being made. The exact path depends on the component used for signup, and how that component is configured. + +### Single Page Notification Button Component + +This component is the more complicated, and renders as a box with a bell icon and text inside. It’s progressively enhanced with the ability to query whether the user already has a subscription (in which case it allows them to cancel it). + +If the user is logged in, this component calls the account api endpoint /api/personalisation/check-email-subscription from the browser, passing it the base path of the current page. If the logged-in user already has a subscription to that page, it will alter the action of the button to unsubscribe. + +The behaviour of the button when pressed depends on the skip_account parameter passed to the component. If true, the button acts to create a subscription by POSTing to the email-alert-frontend endpoint /email-signup with the details of the subscription to be created in the request body. This causes a magic-email subscription to be created (ie one with no account-api record) + +If skip_account is false, though, the button POSTs to the email-alert frontend endpoint /email/subscriptions/single-page/new . This endpoint requires the user to be logged in with a One Login account. If they are not logged in, it will redirect them to a login/create account page (after which they’ll be directed back). If logged in, it calls the email-alert-api methods “authenticate_subscriber_by_govuk_account” and “get_subscriptions” to get the existing subscriptions for that account holder for that page, then toggles that subscription (if it doesn’t exist, it will make one. If it already exists, it will end it). + +### Subscription Links Gem Component + +This component is a simple link that creates a subscription with a GET to /email-signup passing the link as a query parameter. This causes a magic-email subscription to be created (ie one with no account-api record) + +### Application-specified Subscription Links + +These links aren’t in a component, and are generated by Collections and Finder Frontend. They GET the email-alert-frontend endpoint /email/subscriptions/new, which again requires the user to be logged in with a One Login account, and will redirect them to login/create an account if they do not already have one. It then calls the email-alert-api methods “link_subscriber_to_govuk_account” and “subscribe” to create the subscription. This is not a toggle, as with the single page notification button - it will not unsubscribe an existing subscription. + +## How Account records are created + +When one of the email alert paths above requires an account but doesn’t find it, it redirects the user to the One Login endpoint “https://signin.account.gov.uk/sign-in-or-create”. The One Login account is logged into or created at that point, and then the user is redirected back to the /callback endpoint on account-api that creates the account-api record and then redirects to the subscription path with the user already logged in. + +## How Email Alert / Account records are updated + +When a user is logged into their One Login account (at home.account.gov.uk/your-services), they can see a list of services attached to that account. If one of them is GOV.UK email subscriptions, there is a link to https://www.gov.uk/email/manage?from=your-services, which is the email management page on email-alert-frontend. This is a simple link, but the query parameter tells email-alert-frontend that the user is already logged in. + +Moving to the security tab, the user gets the option to change their email address, their password, and to delete their account. + +- Email address changes should affect Account API / Email Alerts (they should change where the email alerts go to) +- Password changes **should not** affect GOV.UK (as an OIDC relying party, we shouldn't be privy to password information from the provider) +- Deleting the account should affect Account API / Email Alerts (they should remove both the account and the subscriber record, and any subscriptions attached to the subscriber) + +### Email Address Changes: + +When the user changes the email address in One Login a direct call is made to the account api PUT /api/oidc_users, which causes the user to be looked up by the OneLogin subject_identifier field (or created, if it doesn’t exist). Then the email and verified email fields are updated (these appear to be the only fields that _can_ be updated by this call). Problems can occur if the subject_identifier for a user has changed in One Login - then we’ll try to create a new account api record with the new subject_identifier, but it will fail to create because the email field has to be unique. Emails also have to be unique in One Login, so theoretically this shouldn’t happen, but if a user is deleted in One Login but not in Account API, it can. + +Once the account API record has been changed, a call is made from account API to email alert API to update the attached email alert api subscriber record (if one exists). + +### One Login Account Deletions: + +When an account is deleted (either by user or support agent) in One Login, a pub/sub message is created, then picked up by a service which makes the call to the account api DELETE /api/oidc_users/. This causes the user to be looked up by the OneLogin subject_identifier. If it exists, a call is made to email alert api to unsubscribe the subscriber record (making it eligible for historic account deletion). After that, the Account API account record is destroyed. + +If the service call to Account API fails, the message goes into a Dead Letter Queue, which causes the One Login team to get an alert by email (they then go and manually investigate the problem). If the call between Account API and Email Alert API fails, we are notified by Sentry. diff --git a/docs/one-login.md b/docs/one-login.md index a938a462..f3608ed8 100644 --- a/docs/one-login.md +++ b/docs/one-login.md @@ -1,7 +1,7 @@ -# Digital Identity +# One Login This document gets into some of the details of the integration with -Digital Identity, and where it can go wrong. For a high-level +One Login, and where it can go wrong. For a high-level overview, see [the developer docs][]. [the developer docs]: https://docs.publishing.service.gov.uk/manual/govuk-account.html @@ -9,58 +9,62 @@ overview, see [the developer docs][]. ## Big picture The [`OidcUser` model][], which represents a user who has -authenticated via Digital Identity, holds four special pieces of data: +authenticated via One Login, holds four special pieces of data: - The `sub`, or "subject identifier", is a unique identifier assigned - by Digital Identity when the account is created, and never changes. + by One Login when the account is created, and never changes. Other data, like an email address, can change: so this is what we use to identify users. - The `legacy_sub` is the user's subject identifier from the old [account manager prototype][]. Only accounts which were created - before the Digital Identity migration have this set. We use this to + before the One Login migration have this set. We use this to join up old data. - The `email` is the user's current email address. It is set by - Digital Identity calling the `/api/oidc-users/:subject_identifier` + One Login calling the `/api/oidc-users/:subject_identifier` endpoint. - The `email_verified` is a boolean denoting whether the user's email - address is verified. It is set by Digital Identity calling the - `/api/oidc-users/:subject_identifier` endpoint. As Digital Identity + address is verified. It is set by One Login calling the + `/api/oidc-users/:subject_identifier` endpoint. As One Login require immediate verification of email addresses, this is always true. Communication flows in both directions between account-api and Digital Identity: -- When a user is updated or deleted, Digital Identity call the +- When a user is updated or deleted, One Login call the endpoints in [`Internal::OidcUsersController`][]. -- When a user logs in, we call Digital Identity from the +- When a user logs in, we call One Login from the [`Internal::AuthenticationController`][]. +These calls can affect both Account API and Email Alert API, read +more about the [One Login to GOV.UK pipeline][one-login-pipeline]. + [`OidcUser` model]: https://github.com/alphagov/account-api/blob/main/app/models/oidc_user.rb [`Internal::OidcUsersController`]: https://github.com/alphagov/account-api/blob/main/app/controllers/internal/oidc_users_controller.rb [`Internal::AuthenticationController`]: https://github.com/alphagov/account-api/blob/main/app/controllers/internal/authentication_controller.rb [account manager prototype]: https://github.com/alphagov/govuk-account-manager-prototype/ +[One Login to GOV.UK pipeline]: / ## Errors This is a non-exhaustive list of problems that could be due to -something breaking with the Digital Identity integration. +something breaking with the One Login integration. -Firstly, check if the problem is on the Digital Identity side: +Firstly, check if the problem is on the One Login side: - If the user got the problem on `https://account.gov.uk` (or some - subdomain of that), then it's Digital Identity. + subdomain of that), then it's One Login. - If account-api is persistently unable to connect to - `https://oidc.account.gov.uk`, then it's Digital Identity. + `https://oidc.account.gov.uk`, then it's One Login. -If the problem is on the Digital Identity side, or if you need support +If the problem is on the One Login side, or if you need support from them, ask for help in `#di-authentication` on Slack. -If the problem is not clearly to do with Digital Identity, read on. +If the problem is not clearly to do with One Login, read on. ### Email address out of date @@ -80,7 +84,7 @@ trying to change to: other_user = OidcUser.find_by(email: "desired new email address") ``` -Digital Identity enforces that email addresses are unique, so we +One Login enforces that email addresses are unique, so we shouldn't ever have two users with the same email address. If there is another user with the desired email address, something may @@ -118,12 +122,12 @@ DETAIL: Key (email)=(email@example.com) already exists. #### There is no relevant error If a user has the wrong email address and there is no relevant error, -then Digital Identity may not have called the +then One Login may not have called the `/api/oidc-users/:subject_identifier` endpoint, or their call may have failed due to some error which wasn't reported. Check Kibana to see if the call was made and what the response code -was. If the call wasn't made at all, contact Digital Identity for +was. If the call wasn't made at all, contact One Login for support. ### Can't log in @@ -140,7 +144,7 @@ user = OidcUser.find_by(email: "address") #### Can't log in for the first time When a user first logs in, we create an `OidcUser` record just holding -their subject identifier, and query Digital Identity for their email +their subject identifier, and query One Login for their email address. So if there is no `OidcUser` record with the email address, this @@ -158,7 +162,7 @@ DETAIL: Key (sub)=(foo) already exists. This should never happen in production. -As subject identifiers come from Digital Identity, contact them for +As subject identifiers come from One Login, contact them for support and give the duplicate subject identifier (`foo` in the example above). @@ -187,7 +191,7 @@ destroyed. This record holds the subject identifier, and we use it to end any active sessions that user still has. If a user logs into an account that has a subject identifier with a -corresponding `Tombstone` record, Digital Identity have re-used a +corresponding `Tombstone` record, One Login have re-used a subject identifier, or un-deleted the account. We currently assume this does not happen. @@ -201,12 +205,12 @@ Ask the `#di-authentication` channel in Slack whether their service is up, and ask if they are seeing an elevated rate of invalid authorization codes or access tokens from GOV.UK. -If Digital Identity are experiencing a problem, we just have to wait +If One Login are experiencing a problem, we just have to wait for them to fix it. Otherwise, we have a bug in account-api, or perhaps elsewhere in the GOV.UK stack. One thing to try would be to clear our cached copy of -the Digital Identity OIDC configuration: +the One Login OIDC configuration: ```ruby Rails.cache.clear