docs: clarify oauth vs api key and add setup steps
This commit is contained in:
parent
754e495607
commit
2c250f601b
33
README.md
33
README.md
|
|
@ -29,18 +29,27 @@ We use Terraform to manage Firebase Authentication and Firestore. To set this up
|
|||
### 1. Manual Prerequisites (One-time)
|
||||
1. **Create a Project**: Go to [Google Cloud Console](https://console.cloud.google.com/) and create a new project.
|
||||
2. **Enable Billing**: Link a Billing Account to this project (Required for Terraform to enable Identity Platform).
|
||||
3. **Local Auth**:
|
||||
```bash
|
||||
gcloud auth login
|
||||
gcloud auth application-default login
|
||||
```
|
||||
4. **Configure Secrets**:
|
||||
Run the helper script to create and populate the required secrets in Google Secret Manager:
|
||||
```bash
|
||||
./scripts/manage_secrets.py
|
||||
```
|
||||
*(You will need the Client ID and Secret from the GCP Console > APIs & Services > Credentials)*
|
||||
5. **Verify**: Log in to the application. You should see the member banner.
|
||||
3. **Local Auth**:
|
||||
```bash
|
||||
gcloud auth login
|
||||
gcloud auth application-default login
|
||||
```
|
||||
4. **Configure OAuth (Crucial Step)**:
|
||||
* Go to [APIs & Services > OAuth consent screen](https://console.cloud.google.com/apis/credentials/consent).
|
||||
* Select **External** -> Create.
|
||||
* Fill in: App Name ("Haumdaucher"), Support Email, and Developer Contact Email. Click **Save and Continue** (You can skip scopes/test users for now).
|
||||
* Go to [Credentials](https://console.cloud.google.com/apis/credentials).
|
||||
* Click **+ Create Credentials** > **OAuth client ID**.
|
||||
* Type: **Web application**.
|
||||
* Name: "Haumdaucher Web".
|
||||
* **Important**: Add `http://localhost:5173` to **Authorized JavaScript origins**.
|
||||
* Click **Create**.
|
||||
5. **Configure Secrets**:
|
||||
Run the helper script and paste the **Client ID** and **Client Secret** you just created:
|
||||
```bash
|
||||
./scripts/manage_secrets.py
|
||||
```
|
||||
6. **Verify**: Log in to the application. You should see the member banner.
|
||||
|
||||
## 🛠 Local Development Requirements
|
||||
|
||||
|
|
|
|||
|
|
@ -109,6 +109,12 @@ def main():
|
|||
create_secret(secret_id)
|
||||
|
||||
# Prompt for value
|
||||
if secret_id == "haumdaucher-oauth-client-id":
|
||||
print(f" ℹ️ Go to GCP Console > Credentials > OAuth 2.0 Client IDs")
|
||||
print(f" Copy the 'Client ID' (ends in .apps.googleusercontent.com)")
|
||||
elif secret_id == "haumdaucher-oauth-client-secret":
|
||||
print(f" ℹ️ Copy the 'Client Secret' (shorter string, hidden in console)")
|
||||
|
||||
print(f" Enter value for {description} (Input hidden): ")
|
||||
# Use getpass logic via manual read to support all shells or just input() but masked?
|
||||
# getpass in python is better.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,48 @@
|
|||
# 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").
|
||||
|
||||
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.
|
||||
Loading…
Reference in New Issue