Defending Google ADK Agents with Vijil Dome

Defending Google ADK Agents with Vijil Dome

Defending Google ADK Agents with Vijil Dome

Opinion

Anuj Tambwekar

May 21, 2025

In our previous blog post, we showed how easily you can test agents built with Google ADK for reliability, safety, and security using Vijil Evaluate. We uncovered some failure modes of the ADK Travel Concierge agent in the process–particularly its vulnerability to various jailbreak attacks.

In this blog post, we'll show how to defend an agent built with ADK using Vijil Dome, our holistic guardrails module that protects against jailbreaks and prompt injections, prevents toxic content generation, ensures PII is obfuscated from agent responses, and a lot more.

We'll continue with the same travel agent example from our previous post and show you how to integrate Vijil Dome into your workflow.  

Add Dome to Your Agent

Agents in ADK have before_model_callback and after_model_callback functions that are executed right before and after the model in the agent is invoked. Following ADK best practices, add the input and output guardrails of Dome into the agent via these callbacks.

Replace the existing agent.py file in the travel_concierge folder with the code below:

"""Demonstration of Travel AI Concierge using Agent Development Kit"""
from google.adk.agents import Agent
from travel_concierge import prompt
from travel_concierge.sub_agents.booking.agent import booking_agent
from travel_concierge.sub_agents.in_trip.agent import in_trip_agent
from travel_concierge.sub_agents.inspiration.agent import inspiration_agent
from travel_concierge.sub_agents.planning.agent import planning_agent
from travel_concierge.sub_agents.post_trip.agent import post_trip_agent
from travel_concierge.sub_agents.pre_trip.agent import pre_trip_agent
from travel_concierge.tools.memory import _load_precreated_itinerary
# These are the additional imports you need to add Dome to an ADK agent
from vijil_dome import Dome
from vijil_dome.integrations.adk import generate_adk_input_callback, generate_adk_output_callback
# Dome is Async first, however ADK does not yet support async model callbacks
# Nest asyncio is required for compatibility until async callbacks are supported
import nest_asyncio
nest_asyncio.apply()
# Create an instance of Dome
# Dome is customizable and configurable, but here we use the default configuration
# This blocks prompt injections, prevents toxic content generation, and obfuscates PII
dome = Dome()
# Now we can generate the callback functions to guard our agents
# You can optionally customize the input or output messages here, and pass along any additional callbacks for your agent. 
guard_input = generate_adk_input_callback(dome)
guard_output = generate_adk_output_callback(dome)
# Since we have a multi-agent example here, lets protect all the sub agents as well
sub_agents = [
    inspiration_agent,
    planning_agent,
    booking_agent,
    pre_trip_agent,
    in_trip_agent,
    post_trip_agent,
]
for agent in sub_agents:
    agent.before_model_callback = guard_input
    agent.after_model_callback = guard_output
# Finally, add guardrails to the root agent
root_agent = Agent(
    model="gemini-2.0-flash-001",
    name="root_agent",
    description="A Travel Concierge using the services of multiple sub-agents",
    instruction=prompt.ROOT_AGENT_INSTR,
    sub_agents=sub_agents,
    before_agent_callback=_load_precreated_itinerary,
    before_model_callback=guard_input,
    after_model_callback=guard_output,
)

Note: Dome is designed to be async-first. However, ADK does not yet support async before and after model callbacks, which is why we use nest_asyncio.

The code block above just does three things that the original agent.py file does not:

  1. It instantiates an instance of Dome with our recommended default configuration

  2. It  creates two functions - guard_input and guard_output, that use Dome to scan inputs and outputs to determine if they are safe

  3. It applies guard_input and guard_output to the callback of every sub-agent and the root agent. 

By applying these functions to every sub-agent, we ensure that every agent is individually protected, reducing the impact and reach of a malicious tool call or rogue agent in the multi-agent setup. 

Run the Agent

Dome is now a part of your agent. You can run the travel concierge agent just like you normally would:

adk run travel_concierge

You can also evaluate it with Vijil Evaluate just like you would the base agent. 

Deploy ADK Agents Protected with Dome

ADK agents protected with Dome can be deployed using Cloud Run. We recommend using Cloud Run as it makes it easy to include the wheel files needed to install Dome in the container, and allows you to provision a container that is sufficiently large to host your agent.

Deployment Steps

  1. Create the dome directory structure. You likely already did this during the setup step.

travel_concierge/
├── dome/
   ├── vijil_dome-0.1.0-py3-none-any.whl
│   └── vijil_core-0.1.6-py3-none-any.whl
  1. Create a requirements.txt file in the travel_concierge directory with the following content::

./travel_concierge/dome/vijil_dome-0.1.0-py3-none-any.whl
./travel_concierge/dome/vijil_core-0.1.6-py3-none-any.whl[guardrails]
nest_asyncio
  1. Create a Dockerfile in the travel_concierge directory with the following content:

FROM python:3.11-slim
WORKDIR /app
# Create a non-root user
RUN adduser --disabled-password --gecos "" myuser
# Change ownership of /app to myuser
RUN chown -R myuser:myuser /app
# Switch to the non-root user
USER myuser
# Set up environment variables
ENV PATH="/home/myuser/.local/bin:$PATH"
ENV GOOGLE_GENAI_USE_VERTEXAI=1
ENV GOOGLE_CLOUD_PROJECT="vijil-blue"
ENV GOOGLE_CLOUD_LOCATION="us-central1"
# This is specifically for the travel concierge agent
ENV TRAVEL_CONCIERGE_SCENARIO="/app/agents/eval/itinerary_empty_default.json"
# Install ADK
RUN pip install google-adk
# Copy agent files
COPY "agents/travel_concierge/" "/app/agents/travel_concierge/"
# This extra file is specifically for the travel concierge agent
COPY "agents/eval/" "/app/agents/eval/"
RUN pip install -r "/app/agents/travel_concierge/requirements.txt"
EXPOSE 8000
CMD adk api_server --port=8000 "/app/agents"
  1. Deploy the agent with the following command:

gcloud run deploy adk-travel-dome --source <PATH TO YOUR FOLDER> --project <YOUR GCP PROJECT> --port 8000 --labels created-by=adk --cpu=4 --memory=8Gi

Important: We recommend using 4 CPUs with 8GB of memory to prevent your container from running out of memory under load. The default settings of 1 CPU and 512MB of memory are insufficient for Dome's default configuration.

That's it! You can invoke your protected agent in the exact same fashion you would invoke any other agent deployed on ADK via Cloud Run. 

Comparing Trust Scores

The standard ADK Travel Concierge scored 81.23 on our security evaluation and was vulnerable to multiple jailbreaks such as ILANA and Miasma. It was also capable of generating malware and leaking private information.

Defended by Dome, the Travel Concierge gains 15.6 points on the security score, achieving 96.77, and blocks all the failure modes we found earlier. We also see a small increase in the overall Trust Score to 95.65.

This is clearly an example of how Dome can improve the trustworthiness of an agent. We expect that your custom agent is instructed to perform a broader role with more domain-specific tasks. Vijil Dome is designed to augment the perimeter defense around custom agents. We’d love to hear from you about the difference you notice in your own testing before and after using Vijil Dome.

Next Step

Dome makes it easy to ensure that your agents remain compliant with your policies.

Vijil Dome is available as a Python package for a free private preview. Contact us at contact@vijil.ai and we'll send you a link to install Dome and try it out at no cost. 

© 2025 Vijil. All rights reserved.

© 2025 Vijil. All rights reserved.

© 2025 Vijil. All rights reserved.