Overview
Guardrails provide a mechanism to control agent behavior by inspecting the browser state before each action. You can implement custom guardrails to block actions based on URLs, page content, or other state information.
from nova_act import NovaAct, GuardrailDecision, GuardrailInputState
def my_guardrail(state: GuardrailInputState) -> GuardrailDecision:
if "blocked-site.com" in state.browser_url:
return GuardrailDecision.BLOCK
return GuardrailDecision.PASS
with NovaAct(starting_page="https://example.com",
state_guardrail=my_guardrail) as nova:
nova.act("Navigate and click")
GuardrailDecision
Enum representing the decision returned by a state guardrail callback.
Values
Allow the agent to continue execution.
Block the agent from continuing and raise ActStateGuardrailError.
Example
from nova_act import GuardrailDecision
def safe_guardrail(state):
# Allow execution
return GuardrailDecision.PASS
def blocking_guardrail(state):
# Block execution
return GuardrailDecision.BLOCK
A named tuple representing the state of the agent that is passed to guardrail callbacks.
Fields
The current URL of the browser page.
Example
from nova_act import GuardrailInputState, GuardrailDecision
def url_guardrail(state: GuardrailInputState) -> GuardrailDecision:
print(f"Current URL: {state.browser_url}")
# Check URL patterns
if state.browser_url.startswith("https://trusted-site.com"):
return GuardrailDecision.PASS
return GuardrailDecision.BLOCK
GuardrailCallable
Type alias for guardrail callback functions.
from typing import Callable
from nova_act import GuardrailInputState, GuardrailDecision
GuardrailCallable = Callable[[GuardrailInputState], GuardrailDecision]
Creating Guardrails
Basic URL Guardrail
Block navigation to specific domains:
from nova_act import NovaAct, GuardrailDecision, GuardrailInputState
def block_social_media(state: GuardrailInputState) -> GuardrailDecision:
blocked_domains = ["facebook.com", "twitter.com", "instagram.com"]
for domain in blocked_domains:
if domain in state.browser_url:
print(f"Blocked access to {domain}")
return GuardrailDecision.BLOCK
return GuardrailDecision.PASS
with NovaAct(
starting_page="https://example.com",
state_guardrail=block_social_media
) as nova:
# Agent will be blocked if it tries to navigate to social media
nova.act("Research the topic")
Whitelist Guardrail
Only allow navigation to approved domains:
from nova_act import NovaAct, GuardrailDecision, GuardrailInputState
def whitelist_domains(state: GuardrailInputState) -> GuardrailDecision:
allowed_domains = [
"example.com",
"trusted-site.com",
"api.service.com"
]
# Check if current URL is in whitelist
for domain in allowed_domains:
if domain in state.browser_url:
return GuardrailDecision.PASS
print(f"Blocked access to non-whitelisted domain: {state.browser_url}")
return GuardrailDecision.BLOCK
with NovaAct(
starting_page="https://example.com",
state_guardrail=whitelist_domains
) as nova:
nova.act("Complete the workflow")
Protocol Guardrail
Restrict to HTTPS only:
from nova_act import NovaAct, GuardrailDecision, GuardrailInputState
def https_only(state: GuardrailInputState) -> GuardrailDecision:
if state.browser_url.startswith("https://"):
return GuardrailDecision.PASS
print(f"Blocked non-HTTPS URL: {state.browser_url}")
return GuardrailDecision.BLOCK
with NovaAct(
starting_page="https://example.com",
state_guardrail=https_only
) as nova:
nova.act("Navigate securely")
Composite Guardrail
Combine multiple guardrail checks:
from nova_act import NovaAct, GuardrailDecision, GuardrailInputState
class CompositeGuardrail:
def __init__(self):
self.blocked_domains = ["malicious.com", "spam.com"]
self.allowed_protocols = ["https://", "file://"]
def __call__(self, state: GuardrailInputState) -> GuardrailDecision:
# Check protocol
if not any(state.browser_url.startswith(p) for p in self.allowed_protocols):
print(f"Blocked due to protocol: {state.browser_url}")
return GuardrailDecision.BLOCK
# Check blocked domains
for domain in self.blocked_domains:
if domain in state.browser_url:
print(f"Blocked domain: {domain}")
return GuardrailDecision.BLOCK
return GuardrailDecision.PASS
guardrail = CompositeGuardrail()
with NovaAct(
starting_page="https://example.com",
state_guardrail=guardrail
) as nova:
nova.act("Complete the task")
Logging Guardrail
Log all URL visits without blocking:
from nova_act import NovaAct, GuardrailDecision, GuardrailInputState
import logging
logger = logging.getLogger(__name__)
def log_all_urls(state: GuardrailInputState) -> GuardrailDecision:
logger.info(f"Agent visiting: {state.browser_url}")
return GuardrailDecision.PASS
with NovaAct(
starting_page="https://example.com",
state_guardrail=log_all_urls
) as nova:
nova.act("Browse and search")
# All URLs will be logged
Error Handling
When a guardrail blocks an action, an ActStateGuardrailError is raised:
from nova_act import (
NovaAct,
GuardrailDecision,
GuardrailInputState,
ActStateGuardrailError
)
def strict_guardrail(state: GuardrailInputState) -> GuardrailDecision:
if "restricted" in state.browser_url:
return GuardrailDecision.BLOCK
return GuardrailDecision.PASS
with NovaAct(
starting_page="https://example.com",
state_guardrail=strict_guardrail
) as nova:
try:
# If agent navigates to restricted URL, it will be blocked
nova.act("Navigate to restricted area")
except ActStateGuardrailError as e:
print(f"Guardrail blocked: {e.message}")
print(f"Session: {e.metadata.session_id}")
When Guardrails Are Called
Guardrails are called at strategic points during agent execution:
- After observation: After the agent observes the current page state
- Before backend invocation: Before sending the observation to the model
- On every step: For each actuation step the agent takes
from nova_act import NovaAct, GuardrailDecision, GuardrailInputState
def debug_guardrail(state: GuardrailInputState) -> GuardrailDecision:
print(f"Guardrail check at URL: {state.browser_url}")
return GuardrailDecision.PASS
with NovaAct(
starting_page="https://example.com",
state_guardrail=debug_guardrail
) as nova:
# Guardrail will be called multiple times during execution
nova.act("Click through several pages")
Best Practices
Keep guardrails fast: Guardrails are called frequently during agent execution. Keep checks lightweight and avoid expensive operations.
Log blocked actions: Always log when blocking an action to help debug and understand agent behavior.
Use for safety, not logic: Guardrails are for safety constraints, not business logic. Don’t use them to control normal workflow flow.
Guardrails only see the browser URL, not the full page content. For content-based filtering, you may need to use other mechanisms.
Advanced Example
Comprehensive guardrail with rate limiting and pattern matching:
from nova_act import (
NovaAct,
GuardrailDecision,
GuardrailInputState,
ActStateGuardrailError
)
import re
from collections import defaultdict
from datetime import datetime, timedelta
class AdvancedGuardrail:
def __init__(self):
self.blocked_patterns = [
r".*\.(exe|dll|bat|cmd)$", # Executable files
r".*malicious.*", # Suspicious domains
r".*admin\/delete.*" # Dangerous admin actions
]
self.visit_counts = defaultdict(int)
self.max_visits_per_domain = 10
def __call__(self, state: GuardrailInputState) -> GuardrailDecision:
url = state.browser_url
# Pattern matching
for pattern in self.blocked_patterns:
if re.match(pattern, url, re.IGNORECASE):
print(f"Blocked by pattern {pattern}: {url}")
return GuardrailDecision.BLOCK
# Rate limiting per domain
domain = self._extract_domain(url)
self.visit_counts[domain] += 1
if self.visit_counts[domain] > self.max_visits_per_domain:
print(f"Rate limit exceeded for domain: {domain}")
return GuardrailDecision.BLOCK
return GuardrailDecision.PASS
def _extract_domain(self, url: str) -> str:
match = re.search(r"https?://([^/]+)", url)
return match.group(1) if match else url
guardrail = AdvancedGuardrail()
try:
with NovaAct(
starting_page="https://example.com",
state_guardrail=guardrail
) as nova:
nova.act("Browse and complete tasks")
except ActStateGuardrailError as e:
print(f"Workflow blocked by guardrail: {e}")
See Also
- SecurityOptions - For file system access control
- Errors - For error types including
ActStateGuardrailError
- NovaAct - For using guardrails with the main client