Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Customer Authentication #120

Open
nickevansuk opened this issue Nov 13, 2019 · 3 comments
Open

Customer Authentication #120

nickevansuk opened this issue Nov 13, 2019 · 3 comments

Comments

@nickevansuk
Copy link
Contributor

@nickevansuk nickevansuk commented Nov 13, 2019

Proposer

MCRactive, Westminster City Council, Everyone Active, Gladstone, Playwaze, SportBuddy, Deuce, Bristol City Council, London Sport, Played, Sport:80

Reference email threads: 1, 2, 3

Use Case

As an existing member of Everyone Active, I want to be able to use my membership through MCRactive, Active Westminster, Deuce, and SportBuddy to find and book activities and facilities, ensuring that I pay prices that include any membership discounts (include discounted to "free" if appropriate).

This is particularly useful to the activity provider for retention-based use cases (e.g. brokers that provide health tracking or motivational tools).

Why is this needed?

The existing booking specification includes a recommendation for "11.7.3 Customer level authentication”, but no mechanism to allow these details to be used as part of the booking flows, except for an example extension which does not include enough information to fully specify an implementation.

User journey

  1. An anonymous Customer using a Broker is prompted to choose between "Guest Checkout" and "Use my existing membership".

    • To ensure this journey is smooth, the Broker will need access to the Customer's e-mail address to send e-mail notifications.
  2. A logged-in Customer using a Broker is prompted to "Connect my existing membership" so that subsequent purchases can make use of that membership where relevant.

    • Although as per 16.6.1 Simplified VAT invoices a customer's details are not required on the VAT invoice for the simple case, it may be useful to have basic personal data (e.g. e-mail address) available to the Broker for the purposes of accurate record keeping - i.e. so that the VAT invoices created by the Broker are not incorrectly attributed.

Proposal

Open Booking API 1.0 CR section 11.7.3 currently recommends the popular standard OpenID Connect for Customer Authentication. The OpenID Connect flow is the same flow that is used for "Login with Facebook" or "Login with Google" that many users are already familiar with:

Untitled drawing (5)

This proposal recommends building on this existing recommendation with a mechanism to allow this authenticated Customer to make a booking.

Model additions

This can be achieved with minor updates to the existing specification, via the introduction of a new AuthenticatedPerson type that subclasses Person. This AuthenticatedPerson can be used as both a customer and attendee, in place of a "guest" Person, and alongside other "guest" Persons.

The AuthenticatedPerson type includes an additional accessToken property, which is used to demonstrate the Broker's authorization to book on behalf of the Customer. Following Open ID Connect conventions, a accessToken is usually short lived (e.g. 1-2 hours).

Classes

Class subClasses Description
oa:AuthenticatedPerson schema:Person Represents a Person that has authenticated with the Seller, and granted access to the Broker to book on their behalf.

Properties

(Class) Property Expected Type Description
(oa:AuthenticatedPerson)
oa:accessToken
schema:Text An access token that verifies the Broker's authorisation to book on behalf of a specific Customer.

Restricted access to Booking System personal data

To inform the Customer that their linked account has been used to create the Order, for the purposes of audit and attribution, to take payment, and to allow for e-mail notifications to be sent in user journey (1) a minimal set of fields of personal data are required.

The proposal recommends that the customer's e-mail (and membership identifier, if different from e-mail) MUST be supplied in the response to C1 , C2 , and B within AuthenticatedPerson, using email and identifier properties as appropriate. Additional properties of Person MAY also be supplied, such as givenName and familyName. The OpenID Connect flow will capture explicit consent from the customer to share this data, which mitigates any concerns around GDPR.

To ensure minimum exposure of the personal data that the Customer has agreed to share, the accessToken MUST be either an opaque token (that contains no personal data) or an encrypted JWT (that contains only the Customer's unique identifier, and is encrypted). If an encrypted JWT is used, the accessToken MUST NOT be stored for longer than its expiry (typically 1-2 days).

In order to ensure that the personal data received is not used outside of the bounds of providing the service, this personal data MUST NOT be used for any other purpose outside of generating invoices, VAT receipts and notifications relating specifically to that unique Order. For the avoidance of doubt, it MUST NOT be used for creation of an account in the Broker, or for other communication outside of those required to service that specific Order, without the Seller's explicit consent (and Customer's explicit consent, where GDPR requires it).

Security

Due to the ability for B to return personal data from the Booking System, which relies on the accessToken being supplied from the results of user authentication, the code flow of Open ID Connect is strongly recommended, and the implicit flow RFC6749 MUST NOT be used (ref).

Offline access

In order to allow the Broker to make bookings without requiring continual re-authentication of the Customer, Offline Access MUST be permitted, where the user has explicitly consented (as per OpenID Connect spec), using a refresh_token.

Pricing

The prices returned for the Offers requested by the Broker on behalf of the Customer MUST match the expectations of the Customer based on any existing membership with the Seller.

Broker contract with Booking System

Currently "The Broker MUST call C1 (without Customer details)", however with this proposal the Broker MAY supply the AuthenticatedPerson at C1 , if known, to have C1 return the correct pricing.

Open Questions and Design Decisions

Access to additional personal data

It is possible for the specification to recommend a means for Brokers to access additional personal data about the Customer, via the OpenID Connect /userinfo endpoint of the Booking System. A Booking System MAY make a number of claims available to the Broker via this mechanism within the Open ID Connect specification.

Do we want to recommend use of /userinfo within the Open Booking API?

To keep the core of Open Booking API cleanly separated from the authentication approach, to adopt a privacy-first approach, and to ensure that the API remains applicable to the broadest number of use cases - the proposal currently recommends that it is better to not include reference to /userinfo specifically in the Open Booking API specification, and certainly not to require it for the flow.

OpenID Connect id_token vs access_token

In the OpenID Connect specification, the intended audience of the id_token is the client application (Broker), where the intended audience of the access_token is the resource server (Booking System). The token for this use case is primarily intended to be received by the Booking System, to provide access to book on the user's behalf. Hence the access_token is the relevant token to use here. The access_token also contains the minimum personally identifiable information by default.

OpenID Connect id_token vs /userinfo via access_token

Within OpenID Connect there are two standard options for getting the authenticated user's details: the OpenID Connect (OIDC) specification includes:

  • ID Token
    • Contains the information at the time the authentication took place, which may be the last time a refresh_token was used.
    • Typically "one-time usage", and for example in Auth0 by default is valid for 36000 seconds (10 hours).
    • Contains user profile attributes, is consumed by an Application (Broker) and typically used for user interface display.
  • /userinfo endpoint accessible via an access_token
    • Provides an updated view of the user information.
    • Can be accessed for the lifetime of the access_token, which can be extended via the refresh_token.

Due to the possibility of token substitution attacks, the /userinfo response is not guaranteed to be about the End-User identified by the sub (subject) element of the ID Token. "The sub Claim in the UserInfo Response MUST be verified to exactly match the sub Claim in the ID Token; if they do not match, the UserInfo Response values MUST NOT be used.". Hence the id_token is required even with access to /userinfo.

As above, perhaps it is better to not recommend either of the above specifically, and not to require them in the flow.

Example

C1 , C2 and B request:

  "customer": {
    "@type": "AuthenticatedPerson",
    "accessToken": "SlAV32hkKG"
  },

C1 , C2 and B response:

  "customer": {
    "@type": "AuthenticatedPerson",
    "identifier": "314251861",
    "email": "geoffcapes@example.com",
    "givenName": "Geoff",
    "familyName": "Capes"
  },
@nickevansuk

This comment has been minimized.

Copy link
Contributor Author

@nickevansuk nickevansuk commented Nov 19, 2019

Discussing with Debbie at Everyone Active, she's pointed out that Westminster are looking for a custom set of fields for the verification, and hence an implementation may need to support more than one set of credential options, e.g. "Member ID and Pin", "Card Number and Last Name", "E-mail address and Password" etc.

Untitled drawing (6)

Also note that the above would be useful for booking where there is a restriction in place, to allow existing members to book e.g. "Casual Gym" or "Climbing Wall" (which require an induction). These would not be available to normal guest checkout customers, so we would need a way of differentiating those activities that require an account or Customer Authentication vs those that are ok to book as guest?

So in the open data, could we have a flag or similar to say "requires Customer Authentication to book"?

E.g. for Casual Gym there's an online booking video on the Everyone Active website.

Also note that the advanced booking period may be different for logged in customers compared with guests, so the open data would need to indicate this? Within Gladstone this is by price level / subscription, so it will vary wildly between customers - and so perhaps e.g. a simple membership-only version of oa:validFromBeforeStartDate is too simple?

Also note you'd need to display the privacy policy of the broker in the same window along with their consent.

The validation page also needs the ability to block login if too many failed login attempts have occurred, for security.

@nickevansuk

This comment has been minimized.

Copy link
Contributor Author

@nickevansuk nickevansuk commented Nov 19, 2019

Nick's summary of Debbie's thoughts:

  • Book-ahead windows seem like the main problem, as the open data won't include the diversity of these, so they would have to be rationalised to "with membership" and "without membership", or the Guest Checkout bookahead is advertised and members may not realise they can book opportunities which they have advanced bookahead access to.
  • Might there be other solutions to "Casual Gym" or "Climbing Wall" inductions that could also work for guests?
@nickevansuk

This comment has been minimized.

Copy link
Contributor Author

@nickevansuk nickevansuk commented Nov 20, 2019

Types of "Authentication"

On the call today we discussed the three different types of "authentication" available via the Open Booking API following this proposal.

Customer Authentication W3C discussion

Option 1 - Broker Login

Pricing available: Rationalised discount pricing end-to-end

This is already possible with the current Open Booking API specification. The Customer has an account with the Broker (e.g. MCRactive or Change4Life), and uses the information they have already stored within that account to make a "Guest Checkout" booking with the Seller ("provider") via the Booking System.

This would be used for casual participants within Active Westminster (Phase 2) and MCRactive (Phase 1), as well as apps like Decathlon Play that include a login.

Using this method it is possible for a limited ("rationalised") set of discount prices (Offers) to be published through the open feeds, and for Brokers to be given permission by the Seller (via their contractual terms) to use these Offers when booking. It is the Broker's responsibility to choose the appropriate price level for the Customer.

Example usecases:

  • Decathlon Play allowing the user's Decathlon existing login to be used to book.
  • 30% discount entitlements given to Pay-and-Play members with an MCRactive card. Entitlements are managed by MCRactive, and they control the Offer that the Customer books via the MCRactive website, with agreement from the Seller.
  • 30% and 40% discount entitlements given to Pay-and-Play members with an Active Westminster card (Phase 2). Entitlements are managed by Active Westminster, and they control the Offer that the Customer books via the Active Westminster website, with agreement from the Seller.

Option 2 - One-off Provider Account Login

Pricing available: Membership pricing at checkout only (not during "Select" / Search)

The Customer does not have an account with the Broker, and is presented with the option to either (i) "Guest Checkout" or (ii) "Login with Everyone Active".

This would be used for e.g. Phase 1 of Active Westminster (white-labelled to "Login with Active Westminster"), or for apps like Change4Life where a parent might find an activity for their child that they hadn't realised was already part of their existing membership.

Once the booking is made, the Customer can cancel it via e.g. the confirmation e-mail link sent by the Broker (using the standard "Customer requested cancellation" flow), or through the existing account within the Booking System (which triggers the existing second half of the "Customer requested cancellation" flow as per the existing specification).

Example usecases:

  • Change4Life does not have a login button, but would still allow Customers to use their existing membership.
  • Active Westminster Phase 1 where the "entitlement" is managed within Gladstone by Everyone Active as a "membership".

Option 3 - Connect My Provider Account

Pricing available: Membership pricing at checkout only (not during "Select" / Search)

The customer has an account with Broker, and wishes to "link" their monthly membership so that they can place bookings with the Seller using their existing membership account.

There is not a two-way flow of bookings, so the Broker would only have visibility of bookings made through that Broker (not all bookings). All bookings would appear in the Customer's existing account within the Booking System.

Example usecases:

  • MCRactive where the customer can "link" their Better monthly membership within their MCRactive account to allow them to make bookings using the MCRactive app and website.
  • Behavioural change motivating / rewards apps (e.g. health insurance, employee wellness) that remind users to participate in activities, will proactively suggest activities within a Customers' existing membership if they have one

Further questions raised

The customer journey for (2) and (3) does not display member pricing until checkout, is this an issue?

N.B: Rationalised discount card prices are possible, see Option 1 above.

As the OpenActive architecture is based primarily on open data feeds, it is not possible within the current specifications to display bespoke members pricing in the search / select stage of the customer journey. Such a feature would require a separate "Opportunity API", which has been previously discussed in the OpenActive community, but is not on the short or medium term roadmap of OpenActive standards at present. This is unrelated to the Open Booking API, and could work alongside it to present accurate member pricing at the point of search. Note that such an Opportunity API would be less useful for displaying opportunities from a number of providers, and more useful for displaying accurate membership pricing for a single provider.

For the first version of this Customer Authentication, is it sufficient to not have member pricing available until checkout? Or is it better to delay Customer Authentication until a date in the future when an Opportunity API may also be available?

What about Opportunities that are only available to members, or a subset of members?

All bookable activities need to be available as open data, though some can be marked as "membership required" (openactive/modelling-opportunity-data#80), this proposal does not cover activities that are exclusively available to some members (e.g. only "Gold" memberships). An Opportunity API, as above, would be required to have detailed membership pricing and eligibility available during browse.

How much of an issue is this with existing providers? Are many activities "exclusive"?

What would a customer expect in terms of communication?

If a user has booked through Change4Life using their existing provider membership, the Change4life user would receive messages related to this booking from the Broker (Change4Life) instead of the Provider direct (as they have paid via the Broker). If they cancel within the Booking System or the Broker, the communication must come from the Broker in both cases, along with the refund processed (triggered using the the "Customer requested cancellation" flow).

Would this match the user’s expectations?

Which Offer should a broker use?

If a number of “discount card” prices are available, how does the Broker differentiate between Offers? For Brokers and Data Users who are looking to display a single adult headline price, or a single child headline price, which do they choose?

Do we need to add a standard vocabulary to describe adult and child, and “discount hard required” (with a link to where one can acquire the discount card) so that all data users can include that in their user experiences?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
1 participant
You can’t perform that action at this time.