KC Server Setup in Greentext

This page discusses the purpose, design, and functionality of MCC’s authentication service with Keycloak. Please keep this page updated with latest changes if you are working on tasks relating to MCC Auth.

Purpose

MCC is the application which allows satellite operators and technicians to send commands to the CubeSat and view received telemetry. If unintended users or malicious agents can gain access to MCC controls and data, they can cause severe damage. This is why MCC authentication has fundamentally different priorities compared to ARO authentication, which is public-facing and less vital to the functioning of GS.

Why Keycloak?

Keycloak is a self-hosted, open-source identity provider, like a local Auth0. Since we are prioritizing safety and security over speed, we want to have production-grade authentication without dependency on external services (Auth0, Clerk, Supabase Auth, etc.). Additionally, its best to not have to handle password management, JWT/JWKS rotations, and retry behavior that would sap time away from meaningful development of GS. There are many ways to run the Keycloak service, but on GS we use a docker container composed together with the API for more streamlined local development and easier deployment in the future. It manages a separate users table in its H2 database, though in the future it should be connected to an external PostgreSQL database for better data management.

Design

Intended MCC Authentication/User Flow

  1. MCC User clicks a “Login” button on the frontend
  2. Frontend redirects user to Keycloak’s login/registration page via a hardcoded URL or dynamic RedirectResponse from the API
  3. User logs in or registers an account through Keycloak
  4. If successful, Keycloak redirects user to the API’s callback URL with a code query param of a one-use string
  5. In the API, /callback makes an API call to the Keycloak service to exchange the code with the user’s ID and access tokens
  6. Encoded in the ID token is the user’s information. decode the ID token to get the user’s sub (UUID4) and email
  7. Upsert the user details to the API’s database
  8. Attach token cookies to the RedirectResponse , redirecting the user to the authenticated MCC landing page
  9. Permit the user access to vulnerable endpoints using an auth dependency which returns the user object and throws 401 Unauthorized if authentication fails.
  10. If the user modifies Keycloak-shared fields (email only as of time of writing), sync updates with Keycloak through API
  11. If the user deletes account, make API call to Keycloak to delete on its database
  12. If user logs out, read id token from the cookie for hinting purposes and redirect to Keycloak’s logout URL