54 lines
3.2 KiB
Markdown
54 lines
3.2 KiB
Markdown
# Technical Details: Authentication & Infrastructure
|
|
|
|
This document explains the "Hybrid" approach we use for managing Authentication infrastructure on Google Cloud Platform (GCP).
|
|
|
|
## 🏗 The Architecture
|
|
|
|
We use **Terraform** to manage our "Infrastructure as Code". This gives us reproducibility and version control. However, Authentication involves sensitive credentials that have security restrictions preventing full automation.
|
|
|
|
### Components
|
|
1. **Firebase Auth (Identity Platform)**: Handles user login (Google Sign-In).
|
|
2. **Firestore**: database storing the "Allowlist" of approved emails.
|
|
3. **Secret Manager**: securely stores the OAuth credentials used by Identity Platform.
|
|
|
|
## 🔐 The "Client Secret" Dilemma
|
|
|
|
### 1. Why is there a Manual Step?
|
|
When you enable Firebase Authentication, Google creates an **OAuth 2.0 Client ID** for your web application. This Client ID comes with a **Client Secret**.
|
|
|
|
**The Restriction**: Google Cloud's security model **does not allow** retrieving an existing Client Secret via the API or CLI (`gcloud`). It is only visible:
|
|
1. At the moment of creation.
|
|
2. In the GCP Console UI (where you can "download JSON").
|
|
|
|
> [!IMPORTANT]
|
|
> **"Browser key" vs "OAuth Client"**:
|
|
> You might see a "Browser key (auto created by Firebase)" in the console. This is an **API Key**, which is public and safe to share.
|
|
> **However**, for the Identity Platform backend configuration (`google_identity_platform_default_supported_idp_config`), we strictly need the **OAuth 2.0 Client Secret**, which acts as a password for the server. Do not confuse the two!
|
|
|
|
Because Terraform interacts via the API, it **cannot** fetch this secret on its own. If we tried to create a *new* Client ID via Terraform, we would hit another blocker: the **OAuth Consent Screen** requires manual configuration in the Console.
|
|
|
|
### 2. The Solution: "Bootstrap" Script
|
|
To bridge this gap, we use a "Bootstrap" workflow:
|
|
|
|
1. **Creation**: Firebase auto-creates the credentials.
|
|
2. **Retrieval**: You manually copy them from the Console (the only place they are visible).
|
|
3. **Storage**: You run `scripts/manage_secrets.py` to save them into **Google Secret Manager**.
|
|
4. **Consumption**: Terraform reads the secure values from Secret Manager to configure the Identity Provider.
|
|
|
|
## 🔄 Authentication Flow
|
|
|
|
1. **User Visits Site**: The Vue.js app initializes Firebase using public config (API Key, Auth Domain).
|
|
2. **Login**: User clicks "Login". The app invokes `signInWithPopup(googleProvider)`.
|
|
* Google checks the allow-listed domains (`localhost`, `*.firebaseapp.com`).
|
|
* The "Client ID" is used to identify the app to Google.
|
|
3. **Token Exchange**: Identity Platform validates the user's Google credentials using the **Client Secret** (configured via Terraform).
|
|
4. **Success**: If valid, the user is signed in.
|
|
5. **Authorization**: The app watches `config/allowlist` in Firestore.
|
|
* If `user.email` is in the list -> **Banner: "Do bist a haumdaucher"**.
|
|
* If not -> Access is restricted.
|
|
|
|
## 📝 Terraform Resources involved
|
|
* `google_identity_platform_default_supported_idp_config`: Configures the "Google" provider.
|
|
* `data "google_secret_manager_secret_version"`: Fetches the stored credentials.
|
|
* `google_firestore_document`: Manages the allowlist.
|