Skip to main content

Authentication and Authorization in Microservices

· 7 min read

Requirements

  • design an auth solution that starts simple but could scale with the business
  • consider both security and user experiences
  • talk about the future trends in this area

Big Picture: AuthN, AuthZ, and Identity Management

First-things-first, let's get back to basics

  • Authentication: figure out who you are
  • Authorization: figure out what you can do

In the beginning... Let there be a simple service...

  • Layered Architecture
  • Client stores a cookie or token as the proof of login status. (valet key pattern)

  • Server persists a corresponding session
  • Token is usually in the format of JWT, signed by keys fetched from somewhere secure (environment variables, AWS KMS, HarshiCorp Vault, etc.)

  • Popular web frameworks often prepare out-of-box auth solutions

Then, as the business grows, we scale the system with AKF scale cube:

  • X-axis: Horizontal clone
  • Y-axis: Functional decomposition
  • Z-axis: Sharding

Plus Conway's law: organization designs the systems mirroring its communication structure. We usually evolve the architecture to micro-services (see why microservices? for more)

  • Btw, "microservices vs. monolith" and "multi-repo vs. mono-repo" are different things.
  • For the enterprise, there are employee auth and customer auth. We focus more on the customer auth.

In the microservice world, let's take a functional slice of the authn and authz services, and there is an Identity and Access Management (IAM) team working on it.

  • Identity-aware proxy is a reverse proxy that allows either public endpoints or checks credentials for protected endpoints. If the credential is not presented but required, redirect the user to an identity provider. e.g. k8s ingress controller, nginx, envoy, Pomerium, ory.sh/oathkeeper, etc.
  • Identity provider and manager is one or a few services that manage the user identity through certain workflows like sign in, forgot password, etc. e.g. ory.sh/kratos, keycloak
  • OAuth2 and OpenID Connect provider enables 3rd-party developers to integrate with your service.
  • Authorization service controls who can do what.

Authentication

Identity Provider

  • The simplest solution is to submit the user's proof of identity and issue service credentials.
    • bcrypt, scrypt for password hash
  • However, modern apps often deal with complex workflows like conditional sign up, multi-step login, forgot password, etc. Those workflows are essentially state transition graphs in the state machine.

Workflow: User Settings and Profile Updates

Ory.sh/Kratos as an Example Architecture

2. Third-party OAuth2

OAuth2 let the user or client go through four major workflows (not sure which one to use? see this) like

  1. Authorization Code Grant for web
  2. Implicit Grant for mobile
  3. Resource Owner Password Credentials Grant for legacy app
  4. Client Credentials Grant for backend application flow

And then finally get the access token and refresh token

  1. access token is short-lived, and hence the attacking window is short if it is compromised
  2. refresh token works only when combined with client id and secret

The assumption is that there are so many entities involved in this workflow - client, resource owner, authorization server, resource server, network, etc. More entities introduce more exposure to attack. A comprehensive protocol should consider all kinds of edge cases. For example, what if the network is not HTTPs / cannot be fully trusted?

OpenID connect is the identity protocol based on OAuth2, and it defines customizable RESTful API for products to implement Single Sign-On (SSO).

There are a lot of tricky details in those workflows and token handling processes. Don't reinvent the wheel.

3. Multi-factor authentication

Problem: Credential stuffing attack

Users tend to reuse the same username and password across multiple sites. When one of those sites suffers from a data breach, hackers brute-force attack other sites with those leaked credentials.

  • Multi-factor authentication: SMS, Email, Phone Voice OTP, Authenticator TOTP
  • Rate limiter, fail to ban, and anomaly detection

Challenge: Bad deliverability of Email or SMS

  • Do not share marketing email channels with transactional ones.
  • Voice OTP usually has better deliverability.

5. Passwordless

  1. biometric: Fingerprints, facial ID, voice ID
  1. QR code
  • SQRL standard
  • Another way to implement:

  1. Push Notification

How could clients subscribe to the server's state? Short polling, long polling, web socket, or server-sent events.

4. Vendors on the market

Don't reinvent the wheel.

6. Optimization

Challenge 1: Web login is super slow or cannot submit login form at all.

  • JS bundle is too large for mobile web
    • Build a lite PWA version of your SPA (single-page web app). whatever makes the bundle small - e.g. preact or inferno
    • Or do not use SPA at all. Simple MPA (multi-page web app) works well with a raw HTML form submission
  • Browser compatibility
    • Use BrowserStack or other tools to test on different browsers
  • Data centers are too far away
    • Put static resources to the edge / CDN and relay API requests through Google backbone network
    • Build a local DC 😄

See Web App Delivery Optimization for more info

Challenge 2: Account taking-over

Challenge 3: Account creation takes too long

When the backend system gets too large, a user creation may fan out to many services and create a lot of entries in different data sources. It feels bad to wait for 15 seconds at the end of sign up, right?

  1. collect and sign up incrementally
  2. async

Authorization

isAuthorized(subject, action, resource)

1. Role-based Access Control (RBAC)

2. Policy-base Access Control (PBAC)

{
"subjects": ["alice"],
"resources": ["blog_posts:my-first-blog-post"],
"actions": ["delete"],
"effect": "allow"
}

Challenge: single point of failure and cascading failures

  • preprocess and cache permissions
  • leverage request contexts
    • assumptions: requests inside of a datacenter are trusted vs. not trusted
  • fail open vs. fail closed

Privacy

1. PII, PHI, PCI

Western culture has a tradition to respect privacy, especially after the Nazis murdered millions of people. Here are some typical sensitive data types: Personally Identifiable Information (PII), Protected Health Information (PHI, regulated by HIPAA), and Credit Card or Payment Card Industry (PCI) Information.

2. Differential Privacy

Redacting sensitive information alone may not be good enough to prevent data associated with other datasets.

Differential privacy helps analysts extract data from the databases containing personal information but still protects individuals' privacy.

3. Decentralized Identity

To decouple id from a centralized identity provider and its associated sensitive data, we can use decentralized id (DID) instead.

  • it is essentially in the format of URN: did:example:123456789abcdefghijk
  • it could be derived from asymmetric keys and its target business domain.
    • it does not involve your personal info, unlike the traditional way
    • See DID method for how it is working with blockchains.
  • it preserves privacy by
    • use different DIDs for different purposes
    • selective disclosure / verifiable claims

Imagine that Alice has a state-issued DID and wants to buy some alcohol without disclosing her real name and precise age.

drinking

A DID solution:

  • Alice has an identity profile having did:ebfeb1f712ebc6f1c276e12ec21, name, avatar url, birthday and other sensitive data.
  • Create a claim that did:ebfeb1f712ebc6f1c276e12ec21 is over the age 21
  • A trusted third-party signs the claim and make it a verifiable claim
  • Use the verifiable claim as the proof of age

Summary

This article is an overview of authn and authz in microservices, and you don't have to memorize everything to be an expert. Here are some takeaways:

  1. follow standard protocols and don't reinvent the wheel
  2. do not under-estimate the power of the security researchers/hackers
  3. it is hard to be perfect, and it does not have to be perfect. Prioritize your development comprehensively
References: