About the project
What inspired you?
I was inspired by the persistent challenge of securing modern web applications. The traditional security workflow is often slow and manual: a developer writes code, a static (SAST) tool finds a potential flaw, a developer manually tries to fix it, and then (maybe) a dynamic (DAST) tool later verifies if the fix worked.
I wanted to automate and accelerate this entire "find, fix, verify" loop. My inspiration was to build a single, intelligent system that could act as an AI security partner—one that not only finds flaws but also suggests the code to fix them and then proves the fix works by trying to hack the patched application, all within a single, iterative workflow.
How I built my project
RiskGuard is a multi-agent "Human-in-the-Loop" (HITL) security platform built on the Google Cloud ecosystem.
Architecture:
- Frontend: A responsive UI built in React and Vite, served by a Cloud Run Service.
- Backend: The entire backend is orchestrated by the Google Agent Development Kit (ADK), running as a separate Cloud Run Service. This backend manages the agentic workflow and serves all API tools.
- AI Agents: I created a multi-agent system using Gemini (via
langchain-google-genai) for intelligence:- SAST Agent: Reads the user's uploaded code and uses Gemini to perform a "code review" to find potential vulnerabilities.
- Fixer Agent: Takes the SAST report and the vulnerable code, and prompts Gemini to generate a
diff-formatted patch to fix the flaw. - Planning Agent: Takes the SAST report and the live sandbox URL, and uses Gemini to generate a JSON-based attack plan for the DAST scan.
- The "Find, Fix, Verify" Loop:
- A user uploads their code.
- The ADK backend (
start_full_scantool) stores the code in Cloud Storage, triggers Cloud Build to create a Docker image, and deploys the vulnerable app to a temporary Cloud Run Service (Sandbox). - The SAST and Fixer agents run. The UI pauses, showing the user the suggested fixes.
- The user clicks "Apply Fix." The backend (
apply_fix_and_update_statetool) patches the code locally. - The user clicks "Run DAST." The backend (
continue_scan_with_dasttool) destroys the old sandbox and re-deploys the patched code to a new sandbox. - The Planning Agent creates an attack plan.
- The ADK backend triggers a separate, secure Cloud Run Job (DAST Executor), which attacks the new, patched sandbox.
- The UI receives the DAST report. If the attack failed (the fix worked!), the user can finish. If the attack succeeded (the fix failed!), the user can trigger a new "Regenerate Fixes" tool (
regenerate_fixes), repeating the loop.
Challenges I faced
- Flask to ADK Migration: My biggest challenge was migrating from a stateful Flask server (using a global
scan_state) to the stateless, tool-based architecture of the ADK. This required re-architecting the frontend (App.tsx) to be the "source of truth" for thescan_stateand passing it to/from each ADK tool. - The Iterative DAST Loop: I initially had a major logic flaw where the DAST scan would run and then immediately destroy the sandbox in a
finallyblock. This meant if a fix failed, the user was stuck. I had to refactor this into three separate tools (continue_scan_with_dast,regenerate_fixes, andfinish_and_destroy_sandbox) to create the iterative loop. - Secure DAST: I couldn't run the exploit code inside the main backend. I solved this by creating a separate, isolated Cloud Run Job for the DAST attack, which the ADK backend triggers. This aligns perfectly with Google Cloud's best practices.
What I learned
- How to Build with ADK: I learned how to build a complex, streaming, multi-tool agent system using the Google Agent Development Kit.
- State Management is Key: I learned how to manage stateless backends by using the frontend as the state holder, which is a powerful and scalable pattern.
- Orchestrating Cloud Run: I learned how to use different Cloud Run resource types for their specific strengths: a Service for the 24/7 backend/frontend and a Job for a secure, run-to-completion task like the DAST exploit.
- Power of Gemini: I was incredibly impressed by Gemini's ability to handle highly domain-specific tasks like generating accurate
diffpatches for code.
Log in or sign up for Devpost to join the conversation.