CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-google-cloud-recaptcha-enterprise

Google Cloud reCAPTCHA Enterprise API client library for protecting websites and applications from fraud

Pending
Overview
Eval results
Files

ip-override-management.mddocs/

IP Override Management

Management of IP address overrides for testing and development environments. IP overrides allow specific IP addresses to be treated differently during reCAPTCHA assessments, enabling controlled testing scenarios and development workflows.

Capabilities

Add IP Override

Adds IP addresses to the override list for a specific key, allowing controlled testing behavior.

def add_ip_override(
    request: AddIpOverrideRequest = None,
    *,
    parent: str = None,
    ip_override_data: IpOverrideData = None,
    retry: Union[retries.Retry, gapic_v1.method._MethodDefault] = _MethodDefault._DEFAULT_VALUE,
    timeout: Union[float, object] = _MethodDefault._DEFAULT_VALUE,
    metadata: Sequence[Tuple[str, str]] = ()
) -> AddIpOverrideResponse:
    """
    Adds an IP override for a key.

    Args:
        request: The request object for adding IP override
        parent: Required. The key name in format 'projects/{project}/keys/{key}'
        ip_override_data: Required. IP override configuration
        retry: Retry configuration for the request
        timeout: Timeout for the request in seconds
        metadata: Additional metadata for the request

    Returns:
        AddIpOverrideResponse: Confirmation of IP override addition

    Raises:
        google.api_core.exceptions.InvalidArgument: If IP override data is invalid
        google.api_core.exceptions.NotFound: If the key doesn't exist
        google.api_core.exceptions.PermissionDenied: If insufficient permissions
    """

Usage Example

from google.cloud import recaptchaenterprise
from google.cloud.recaptchaenterprise_v1.types import IpOverrideData

client = recaptchaenterprise.RecaptchaEnterpriseServiceClient()

# Add IP override for testing
ip_override = IpOverrideData(
    ip="203.0.113.0/24",  # IP address or CIDR block
    override_type=IpOverrideData.OverrideType.ALLOW
)

request = recaptchaenterprise.AddIpOverrideRequest(
    parent="projects/your-project/keys/your-key-id",
    ip_override_data=ip_override
)

response = client.add_ip_override(request=request)
print("IP override added successfully")

Remove IP Override

Removes IP addresses from the override list for a specific key.

def remove_ip_override(
    request: RemoveIpOverrideRequest = None,
    *,
    parent: str = None,
    ip_override_data: IpOverrideData = None,
    retry: Union[retries.Retry, gapic_v1.method._MethodDefault] = _MethodDefault._DEFAULT_VALUE,
    timeout: Union[float, object] = _MethodDefault._DEFAULT_VALUE,
    metadata: Sequence[Tuple[str, str]] = ()
) -> RemoveIpOverrideResponse:
    """
    Removes an IP override for a key.

    Args:
        request: The request object for removing IP override
        parent: Required. The key name in format 'projects/{project}/keys/{key}'
        ip_override_data: Required. IP override to remove
        retry: Retry configuration for the request
        timeout: Timeout for the request in seconds
        metadata: Additional metadata for the request

    Returns:
        RemoveIpOverrideResponse: Confirmation of IP override removal

    Raises:
        google.api_core.exceptions.NotFound: If override or key doesn't exist
        google.api_core.exceptions.InvalidArgument: If IP override data is invalid
        google.api_core.exceptions.PermissionDenied: If insufficient permissions
    """

List IP Overrides

Retrieves all IP overrides for a specific key with support for pagination.

def list_ip_overrides(
    request: ListIpOverridesRequest = None,
    *,
    parent: str = None,
    retry: Union[retries.Retry, gapic_v1.method._MethodDefault] = _MethodDefault._DEFAULT_VALUE,
    timeout: Union[float, object] = _MethodDefault._DEFAULT_VALUE,
    metadata: Sequence[Tuple[str, str]] = ()
) -> ListIpOverridesResponse:
    """
    Lists IP overrides for a key.

    Args:
        request: The request object for listing IP overrides
        parent: Required. The key name in format 'projects/{project}/keys/{key}'
        retry: Retry configuration for the request
        timeout: Timeout for the request in seconds
        metadata: Additional metadata for the request

    Returns:
        ListIpOverridesResponse: List of IP overrides for the key

    Raises:
        google.api_core.exceptions.NotFound: If the key doesn't exist
        google.api_core.exceptions.PermissionDenied: If insufficient permissions
    """

Request and Response Types

IpOverrideData

class IpOverrideData:
    """IP override configuration data."""
    ip: str                           # IP address or CIDR block
    override_type: OverrideType       # Type of override behavior

class OverrideType(Enum):
    """Types of IP override behavior."""
    OVERRIDE_TYPE_UNSPECIFIED = 0
    ALLOW = 1                         # Always allow (bypass normal assessment)

Request Types

class AddIpOverrideRequest:
    """Request message for adding an IP override."""
    parent: str                       # Required. Key name in format 'projects/{project}/keys/{key}'
    ip_override_data: IpOverrideData  # Required. IP override configuration

class AddIpOverrideResponse:
    """Response message for adding an IP override."""
    pass  # Empty response confirming addition

class RemoveIpOverrideRequest:
    """Request message for removing an IP override."""
    parent: str                       # Required. Key name
    ip_override_data: IpOverrideData  # Required. IP override to remove

class RemoveIpOverrideResponse:
    """Response message for removing an IP override."""
    pass  # Empty response confirming removal

class ListIpOverridesRequest:
    """Request message for listing IP overrides."""
    parent: str                       # Required. Key name
    page_size: int                   # Optional. Maximum results per page
    page_token: str                  # Optional. Pagination token

class ListIpOverridesResponse:
    """Response message for listing IP overrides."""
    ip_overrides: List[IpOverrideData]  # List of IP overrides
    next_page_token: str             # Token for next page of results

Usage Examples

Development Environment Setup

# Add development office IP ranges
dev_office_override = IpOverrideData(
    ip="192.168.1.0/24",
    override_type=IpOverrideData.OverrideType.ALLOW
)

client.add_ip_override(
    parent="projects/your-project/keys/dev-key",
    ip_override_data=dev_office_override
)

# Add specific developer IP
dev_home_override = IpOverrideData(
    ip="203.0.113.42",
    override_type=IpOverrideData.OverrideType.ALLOW
)

client.add_ip_override(
    parent="projects/your-project/keys/dev-key",
    ip_override_data=dev_home_override
)

Testing Environment Configuration

# Add testing infrastructure IPs
test_server_override = IpOverrideData(
    ip="10.0.0.0/16",  # Internal test network
    override_type=IpOverrideData.OverrideType.ALLOW
)

client.add_ip_override(
    parent="projects/your-project/keys/test-key",
    ip_override_data=test_server_override
)

# Add CI/CD pipeline IPs
ci_override = IpOverrideData(
    ip="198.51.100.10",  # CI server IP
    override_type=IpOverrideData.OverrideType.ALLOW
)

client.add_ip_override(
    parent="projects/your-project/keys/test-key",
    ip_override_data=ci_override
)

Managing IP Overrides

# List all current overrides
list_request = recaptchaenterprise.ListIpOverridesRequest(
    parent="projects/your-project/keys/your-key"
)

response = client.list_ip_overrides(request=list_request)

print("Current IP overrides:")
for override in response.ip_overrides:
    print(f"  {override.ip} - {override.override_type}")

# Remove specific override
remove_request = recaptchaenterprise.RemoveIpOverrideRequest(
    parent="projects/your-project/keys/your-key",
    ip_override_data=IpOverrideData(
        ip="203.0.113.42",
        override_type=IpOverrideData.OverrideType.ALLOW
    )
)

client.remove_ip_override(request=remove_request)
print("IP override removed")

Batch IP Override Management

def add_multiple_ip_overrides(client, key_name, ip_addresses):
    """Add multiple IP overrides to a key."""
    for ip_addr in ip_addresses:
        override = IpOverrideData(
            ip=ip_addr,
            override_type=IpOverrideData.OverrideType.ALLOW
        )
        
        try:
            client.add_ip_override(
                parent=key_name,
                ip_override_data=override
            )
            print(f"Added override for {ip_addr}")
        except Exception as e:
            print(f"Failed to add override for {ip_addr}: {e}")

# Add development team IPs
dev_ips = [
    "203.0.113.10",
    "203.0.113.11", 
    "203.0.113.12",
    "192.168.0.0/24"
]

add_multiple_ip_overrides(
    client,
    "projects/your-project/keys/dev-key",
    dev_ips
)

Cleanup and Maintenance

def cleanup_ip_overrides(client, key_name):
    """Remove all IP overrides from a key."""
    # List all current overrides
    response = client.list_ip_overrides(parent=key_name)
    
    # Remove each override
    for override in response.ip_overrides:
        try:
            client.remove_ip_override(
                parent=key_name,
                ip_override_data=override
            )
            print(f"Removed override for {override.ip}")
        except Exception as e:
            print(f"Failed to remove override for {override.ip}: {e}")

# Clean up development key
cleanup_ip_overrides(client, "projects/your-project/keys/old-dev-key")

IP Address Formats

Supported Formats

# Single IP address (IPv4)
single_ipv4 = IpOverrideData(
    ip="203.0.113.42",
    override_type=IpOverrideData.OverrideType.ALLOW
)

# CIDR block (IPv4)
cidr_ipv4 = IpOverrideData(
    ip="192.168.1.0/24",
    override_type=IpOverrideData.OverrideType.ALLOW
)

# Single IP address (IPv6)
single_ipv6 = IpOverrideData(
    ip="2001:db8::1",
    override_type=IpOverrideData.OverrideType.ALLOW
)

# CIDR block (IPv6)
cidr_ipv6 = IpOverrideData(
    ip="2001:db8::/32",
    override_type=IpOverrideData.OverrideType.ALLOW
)

Common Network Ranges

# Private IP ranges (RFC 1918)
private_ranges = [
    "10.0.0.0/8",      # Class A private
    "172.16.0.0/12",   # Class B private
    "192.168.0.0/16"   # Class C private
]

# Localhost ranges
localhost_ranges = [
    "127.0.0.0/8",     # IPv4 localhost
    "::1/128"          # IPv6 localhost
]

# Example corporate network
corporate_ranges = [
    "203.0.113.0/24",  # Office network
    "198.51.100.0/24", # Data center
    "192.0.2.0/24"     # Development lab
]

Error Handling

from google.api_core import exceptions

try:
    client.add_ip_override(request=request)
except exceptions.InvalidArgument as e:
    print(f"Invalid IP address format: {e}")
    # Check IP address syntax, CIDR notation
except exceptions.NotFound as e:
    print(f"Key not found: {e}")
    # Verify key name and project
except exceptions.AlreadyExists as e:
    print(f"IP override already exists: {e}")
    # Check for duplicate overrides

try:
    client.remove_ip_override(request=request)
except exceptions.NotFound as e:
    print(f"IP override not found: {e}")
    # Verify override exists before removal

Best Practices

Development Workflow

  • Use separate keys for development and testing environments
  • Add office and VPN IP ranges for development teams
  • Include CI/CD system IPs for automated testing
  • Document IP overrides with clear descriptions

Security Considerations

  • Regularly audit and cleanup unused IP overrides
  • Use specific IP ranges rather than broad allowlists
  • Monitor override usage through logging
  • Remove overrides when no longer needed

Testing Strategy

  • Test applications with and without IP overrides
  • Verify override behavior matches expectations
  • Use IP overrides for controlled testing scenarios
  • Validate production behavior without overrides

Maintenance

  • Regular review of active IP overrides
  • Update IP ranges when network changes occur
  • Remove overrides for decommissioned systems
  • Document override purposes and ownership

Integration with Development Workflows

CI/CD Pipeline Integration

import os

def setup_ci_ip_overrides():
    """Setup IP overrides for CI/CD environment."""
    client = recaptchaenterprise.RecaptchaEnterpriseServiceClient()
    
    ci_key = os.environ.get('RECAPTCHA_CI_KEY')
    ci_ips = os.environ.get('CI_IP_ADDRESSES', '').split(',')
    
    for ip in ci_ips:
        if ip.strip():
            override = IpOverrideData(
                ip=ip.strip(),
                override_type=IpOverrideData.OverrideType.ALLOW
            )
            
            client.add_ip_override(
                parent=ci_key,
                ip_override_data=override
            )

# Call during CI setup
setup_ci_ip_overrides()

Local Development Helper

def get_my_ip():
    """Get current public IP for development override."""
    import requests
    try:
        response = requests.get('https://api.ipify.org')
        return response.text.strip()
    except Exception:
        return None

def add_dev_ip_override(key_name):
    """Add current IP to development key overrides."""
    client = recaptchaenterprise.RecaptchaEnterpriseServiceClient()
    my_ip = get_my_ip()
    
    if my_ip:
        override = IpOverrideData(
            ip=my_ip,
            override_type=IpOverrideData.OverrideType.ALLOW
        )
        
        client.add_ip_override(
            parent=key_name,
            ip_override_data=override
        )
        print(f"Added IP override for {my_ip}")
    else:
        print("Could not determine current IP address")

# Add current IP to development key
add_dev_ip_override("projects/your-project/keys/dev-key")

Install with Tessl CLI

npx tessl i tessl/pypi-google-cloud-recaptcha-enterprise

docs

account-security-analysis.md

assessment-operations.md

firewall-policies.md

index.md

ip-override-management.md

key-management.md

metrics-analytics.md

tile.json