This implementation plan covers migrating the AgentForge Career OS authentication from local JWT credentials/Clerk specs to Firebase Authentication (both frontend and backend) and replacing the in-memory slowapi rate-limiter with a robust Redis-based sliding-window rate-limiter middleware.
Furthermore, it outlines a Subagent-Driven parallel execution strategy to complete these tasks quickly and with high test coverage.
Warning
Authentication Paradigm Shift: This migration moves the responsibility of password storage, hashing, and email verification completely to Firebase Authentication. The backend will no longer store password hashes or issue JWTs. Instead, it will act as an OAuth Resource Server, validating standard RS256 Firebase ID Tokens against Google's public certificates.
Important
Zero-Config Backend Verification:
To avoid requiring a sensitive service-account.json credential file in local development or environment variables, the backend will verify Firebase ID tokens by decoding them dynamically using Google's public certificates fetched from:
https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com
This makes deployment extremely secure, lightweight, and zero-config.
Note
Firebase Project Configuration:
- Do you have an active Firebase Project ID we should use for the local
.envsetup? (If not, we will default toagentforge-career-oswhich can be overridden viaFIREBASE_PROJECT_IDin.env). - For social logins (e.g. Google OAuth), do you want to enable a "Login with Google" button on the login screen alongside email/password? (Highly recommended since Firebase makes Google OAuth trivial to add in React).
- Add
firebase_project_id: str = "agentforge-career-os"parameter toSettings. - Keep
redis_urland ensure it's loaded properly.
- Firebase Token Verification: Refactor
get_current_userto verify Firebase ID tokens usingpython-jose:- Fetch Google's public certs dynamically.
- Match the key ID (
kid) from the JWT header. - Decode and verify the token audience (Firebase Project ID) and issuer (
https://securetoken.google.com/<project-id>). - Extract the user's
email,name, and Firebasesub(UID).
- Auto-Provisioning (SSO): If a user with the decoded email does not exist in the Postgres database, automatically create a new
Userrecord (with empty/random password hash since auth is external) and initialize theirProfilerecord (is_onboarded=False). - Custom Redis Rate Limiter:
- Create a custom async
RedisRateLimiterclass usingredis.asyncio. - Implement a sliding window rate-limiting algorithm using Redis sorted sets (
ZADD,ZREMRANGEBYSCORE,ZCARD,EXPIRE). - Replace the local in-memory
slowapiinstance with this Redis rate limiter.
- Create a custom async
- Simplify auth endpoints. Since registration and login occur directly in the React frontend via Firebase SDK, we can:
- Keep
/auth/meto return the currently authenticated user's Postgres record via the updatedget_current_userdependency. - Deprecate or simplify
/auth/loginand/auth/registerendpoints (or have them return stubs, as they are no longer required to issue tokens).
- Keep
- Install the standard Firebase Client SDK:
npm install firebase.
- Create a Firebase initialization utility that pulls config keys from
import.meta.env(e.g.VITE_FIREBASE_API_KEY,VITE_FIREBASE_PROJECT_ID). - Initialize and export
authfrom"firebase/auth". - Provide standard fallbacks for local developer environments if keys are missing.
- Refactor
AuthProviderto use Firebase Auth under the hood:- Listen to state changes with
onAuthStateChanged(auth, async (firebaseUser) => ... ). - On state change, fetch the ID token:
const token = await firebaseUser.getIdToken(). - Save the ID token in local storage and call
setAuthToken(token). - Fetch the PostgreSQL user profile from
/auth/meon the backend. - Refactor
loginto callsignInWithEmailAndPassword(auth, email, password). - Refactor
registerto callcreateUserWithEmailAndPassword(auth, email, password)and update the profile. - Refactor
logoutto callsignOut(auth).
- Listen to state changes with
- Ensure they consume the updated
loginandregisterfunctions from the Auth Context. - Optional: Add a "Sign in with Google" button to support social logins natively via Firebase.
To execute this plan in parallel without merge conflicts, we will assign two specialized subagents operating on isolated parts of the codebase:
graph TD
classDef subagent fill:#10B981,stroke:#059669,stroke-width:2px,color:#fff;
classDef main fill:#6366F1,stroke:#4F46E5,stroke-width:2px,color:#fff;
Main[Parent Agent: Antigravity] --> Task1[Task 1: Backend Security & Rate Limiter]:::subagent
Main --> Task2[Task 2: Frontend Firebase Integration]:::subagent
Task1 --> Code1[backend/app/dependencies.py<br>backend/app/config.py<br>backend/app/api/v1/auth.py]
Task2 --> Code2[src/lib/firebase.ts<br>src/lib/auth-context.tsx<br>src/pages/Login.tsx]
Code1 --> Merge[Parent Sync & Review Gates]:::main
Code2 --> Merge
- Scope:
backend/app/dependencies.py,backend/app/config.py,backend/app/api/v1/auth.py - Task: Implement dynamic Firebase ID Token verification against Google's public x509 certs, implement auto-provisioning of Postgres user records on successful token verification, and build the custom async Redis sliding window rate-limiter middleware.
- Scope:
package.json,src/lib/firebase.ts,src/lib/auth-context.tsx,src/pages/Login.tsx,src/pages/Register.tsx - Task: Install the Firebase SDK, initialize Firebase client-side, rewire
auth-context.tsxto handle authentication, credentials, and tokens via Firebase Auth, and update the login/register views.
- Backend Verification Stub: We will create a unit test suite in the backend testing the JWT decoding using mock Firebase ID tokens.
- Redis Rate Limiter Validation: We will write tests to hit rate-limited endpoints repeatedly and verify that HTTP 429 Too Many Requests is returned once thresholds are crossed.
- Frontend Vitest Verification: Run Vite unit tests using
npm run testto verify no rendering regressions on the auth screens.
- Launch the backend FastAPI app alongside Redis and Qdrant using
docker-compose up. - Launch the frontend Vite dev server, perform user sign-up and sign-in, and check the PostgreSQL console to verify that the User and Profile records are automatically provisioned.