zero trust architecture

Implementing BeyondCorp Zero Trust Access Model

Implementing Google's BeyondCorp zero trust access model to eliminate implicit trust from the network perimeter, enforce identity-aware access controls using IAP, Access Context Manager, and Chrome Enterprise Premium for VPN-less secure application access.

access-context-managerbeyondcorpgoogle-cloudiapidentity-aware-proxyzero-trustztna
Install this skill
npx skills add mukul975/Anthropic-Cybersecurity-Skills
Framework mappings

When to Use

  • When replacing traditional VPN infrastructure with identity-based application access
  • When migrating to Google Cloud and requiring zero trust access for internal applications
  • When implementing device trust verification as a prerequisite for resource access
  • When needing context-aware access policies based on user identity, device posture, and location
  • When securing access for remote and hybrid workforce without network-level trust

Do not use when applications require raw network-level access (e.g., UDP-based protocols not supported by IAP), for consumer-facing public applications, or when the organization lacks an identity provider with MFA capabilities.

Prerequisites

  • Google Cloud organization with Cloud Identity or Google Workspace
  • Identity-Aware Proxy (IAP) API enabled on the GCP project
  • Chrome Enterprise Premium license for endpoint verification
  • Applications deployed behind a Google Cloud Load Balancer or on App Engine/Cloud Run
  • Endpoint Verification extension deployed on all corporate devices
  • Access Context Manager API enabled

Workflow

Step 1: Configure Access Context Manager with Access Levels

Define access levels that represent trust tiers based on device and user attributes.

# Enable required APIs
gcloud services enable iap.googleapis.com
gcloud services enable accesscontextmanager.googleapis.com
gcloud services enable beyondcorp.googleapis.com
 
# Create an access policy (organization level)
gcloud access-context-manager policies create \
  --organization=ORG_ID \
  --title="BeyondCorp Enterprise Policy"
 
# Create a basic access level for corporate managed devices
cat > corporate-device-level.yaml << 'EOF'
- devicePolicy:
    allowedEncryptionStatuses:
      - ENCRYPTED
    osConstraints:
      - osType: DESKTOP_CHROME_OS
        minimumVersion: "13816.0.0"
      - osType: DESKTOP_WINDOWS
        minimumVersion: "10.0.19045"
      - osType: DESKTOP_MAC
        minimumVersion: "13.0.0"
    requireScreenlock: true
    requireAdminApproval: true
  regions:
    - US
    - GB
    - DE
EOF
 
gcloud access-context-manager levels create corporate-managed \
  --policy=POLICY_ID \
  --title="Corporate Managed Device" \
  --basic-level-spec=corporate-device-level.yaml
 
# Create a custom access level using CEL expressions
gcloud access-context-manager levels create high-trust \
  --policy=POLICY_ID \
  --title="High Trust Level" \
  --custom-level-spec=high-trust-cel.yaml

Step 2: Deploy Identity-Aware Proxy on Applications

Enable IAP on backend services to enforce identity verification before granting access.

# Create OAuth consent screen
gcloud iap oauth-brands create \
  --application_title="Corporate Applications" \
  --support_email=security@company.com
 
# Create OAuth client for IAP
gcloud iap oauth-clients create BRAND_NAME \
  --display_name="BeyondCorp IAP Client"
 
# Enable IAP on a backend service (GCE/GKE behind HTTPS LB)
gcloud compute backend-services update internal-app-backend \
  --iap=enabled,oauth2-client-id=CLIENT_ID,oauth2-client-secret=CLIENT_SECRET \
  --global
 
# Enable IAP on App Engine
gcloud iap web enable \
  --resource-type=app-engine \
  --oauth2-client-id=CLIENT_ID \
  --oauth2-client-secret=CLIENT_SECRET
 
# Enable IAP on Cloud Run service
gcloud run services add-iam-policy-binding internal-api \
  --member="serviceAccount:service-PROJECT_NUM@gcp-sa-iap.iam.gserviceaccount.com" \
  --role="roles/run.invoker" \
  --region=us-central1

Step 3: Configure IAM Bindings with Access Level Conditions

Bind IAP access to specific groups with access level requirements.

# Grant access to engineering group with corporate device requirement
gcloud iap web add-iam-policy-binding \
  --resource-type=backend-services \
  --service=internal-app-backend \
  --member="group:engineering@company.com" \
  --role="roles/iap.httpsResourceAccessor" \
  --condition="expression=accessPolicies/POLICY_ID/accessLevels/corporate-managed,title=Require Corporate Device"
 
# Grant access to contractors with high-trust requirement
gcloud iap web add-iam-policy-binding \
  --resource-type=backend-services \
  --service=internal-app-backend \
  --member="group:contractors@company.com" \
  --role="roles/iap.httpsResourceAccessor" \
  --condition="expression=accessPolicies/POLICY_ID/accessLevels/high-trust,title=Require High Trust"
 
# Configure re-authentication settings (session duration)
gcloud iap settings set --project=PROJECT_ID \
  --resource-type=compute \
  --service=internal-app-backend \
  --reauth-method=LOGIN \
  --max-session-duration=3600s

Step 4: Deploy Endpoint Verification on Corporate Devices

Roll out Chrome Enterprise Endpoint Verification for device posture collection.

# Deploy Endpoint Verification via Chrome policy (managed browsers)
# In Google Admin Console > Devices > Chrome > Apps & extensions
# Force-install: Endpoint Verification extension ID: callobklhcbilhphinckomhgkigmfocg
 
# Verify device inventory in Admin SDK
gcloud endpoint-verification list-endpoints \
  --filter="deviceType=CHROME_BROWSER" \
  --format="table(deviceId, osVersion, isCompliant, encryptionStatus)"
 
# Create device trust connector for third-party EDR signals
gcloud beyondcorp app connections create crowdstrike-connector \
  --project=PROJECT_ID \
  --location=global \
  --application-endpoint=host=crowdstrike-api.internal:443,port=443 \
  --type=TCP_PROXY_TUNNEL \
  --connectors=projects/PROJECT_ID/locations/us-central1/connectors/connector-1
 
# List enrolled devices and their compliance status
gcloud alpha devices list --format="table(name,deviceType,complianceState)"

Step 5: Implement BeyondCorp Enterprise Threat Protection

Enable URL filtering, malware scanning, and DLP for Chrome Enterprise users.

# Configure Chrome Enterprise Premium threat protection rules
# In Google Admin Console > Security > Chrome Enterprise Premium
 
# Create a BeyondCorp Enterprise connector for on-prem apps
gcloud beyondcorp app connectors create onprem-connector \
  --project=PROJECT_ID \
  --location=us-central1 \
  --display-name="On-Premises App Connector"
 
gcloud beyondcorp app connections create hr-portal \
  --project=PROJECT_ID \
  --location=us-central1 \
  --application-endpoint=host=hr.internal.company.com,port=443 \
  --type=TCP_PROXY_TUNNEL \
  --connectors=projects/PROJECT_ID/locations/us-central1/connectors/onprem-connector
 
# Enable security investigation tool for access anomaly detection
gcloud logging read '
  resource.type="iap_tunnel"
  jsonPayload.decision="DENY"
  timestamp >= "2026-02-22T00:00:00Z"
' --project=PROJECT_ID --format=json --limit=100

Step 6: Monitor and Audit BeyondCorp Access Decisions

Set up comprehensive logging and alerting for zero trust policy enforcement.

# Create a log sink for IAP access decisions
gcloud logging sinks create iap-access-audit \
  --destination=bigquery.googleapis.com/projects/PROJECT_ID/datasets/beyondcorp_audit \
  --log-filter='resource.type="iap_tunnel" OR resource.type="gce_backend_service"'
 
# Query BigQuery for access pattern analysis
bq query --use_legacy_sql=false '
SELECT
  protopayload_auditlog.authenticationInfo.principalEmail AS user,
  resource.labels.backend_service_name AS application,
  JSON_EXTRACT_SCALAR(protopayload_auditlog.requestMetadata.callerSuppliedUserAgent, "$") AS device,
  protopayload_auditlog.status.code AS decision_code,
  COUNT(*) AS request_count
FROM `PROJECT_ID.beyondcorp_audit.cloudaudit_googleapis_com_data_access`
WHERE timestamp > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 24 HOUR)
GROUP BY user, application, device, decision_code
ORDER BY request_count DESC
LIMIT 50
'
 
# Create an alert policy for repeated access denials
gcloud alpha monitoring policies create \
  --display-name="BeyondCorp Repeated Access Denials" \
  --condition-display-name="High denial rate" \
  --condition-filter='resource.type="iap_tunnel" AND jsonPayload.decision="DENY"' \
  --condition-threshold-value=10 \
  --condition-threshold-duration=300s \
  --notification-channels=projects/PROJECT_ID/notificationChannels/CHANNEL_ID

Key Concepts

Term Definition
BeyondCorp Google's zero trust security framework that shifts access controls from network perimeter to per-request identity and device verification
Identity-Aware Proxy (IAP) Google Cloud service that intercepts HTTP requests and verifies user identity and device context before forwarding to backend applications
Access Context Manager GCP service that defines fine-grained attribute-based access control policies using access levels and service perimeters
Endpoint Verification Chrome Enterprise extension that collects device attributes (OS version, encryption, screen lock) for access level evaluation
Access Levels Named conditions in Access Context Manager that define minimum requirements (device posture, IP range, geography) for resource access
Chrome Enterprise Premium Google's commercial BeyondCorp offering providing threat protection, URL filtering, DLP, and continuous access evaluation

Tools & Systems

  • Google Cloud IAP: Identity-aware reverse proxy enforcing per-request authentication and authorization for GCP-hosted applications
  • Access Context Manager: Policy engine defining access levels based on device attributes, IP ranges, and geographic locations
  • Chrome Enterprise Premium: Extended BeyondCorp capabilities including real-time threat protection and data loss prevention
  • Endpoint Verification: Device posture collection agent deployed as Chrome extension to all corporate endpoints
  • BeyondCorp Enterprise Connectors: Secure tunnel connectors enabling IAP protection for on-premises applications
  • Cloud Audit Logs: Immutable log records of all IAP access decisions for compliance and forensic analysis

Common Scenarios

Scenario: Migrating 50+ Internal Applications from VPN to BeyondCorp

Context: A technology company with 3,000 employees uses Cisco AnyConnect VPN for accessing internal applications. The VPN introduces latency, creates a single point of failure, and grants excessive network access after authentication.

Approach:

  1. Inventory all 50+ applications and categorize by hosting (GCP, on-prem, SaaS) and protocol (HTTPS, TCP, SSH)
  2. Deploy Endpoint Verification to all corporate devices and establish baseline device posture data over 2 weeks
  3. Create access levels in Access Context Manager: corporate-managed, contractor-device, high-trust
  4. Enable IAP on GCP-hosted HTTPS applications first (App Engine, Cloud Run, GKE services)
  5. Deploy BeyondCorp Enterprise connectors for on-premises applications
  6. Migrate users in 3 phases: IT/Engineering (week 1-2), General staff (week 3-4), Executives/Finance (week 5-6)
  7. Configure re-authentication policies: 8 hours for general apps, 1 hour for financial systems
  8. Set up BigQuery audit pipeline for continuous monitoring and anomaly detection
  9. Decommission VPN after 30-day parallel operation period

Pitfalls: Some legacy applications may not support HTTPS proxying and require TCP tunnel mode. Device enrollment takes time; plan a 2-week onboarding period before enforcing device posture requirements. Break-glass accounts with bypassed access levels must be created and tested for identity provider outages.

Output Format

BeyondCorp Zero Trust Implementation Report
==================================================
Organization: TechCorp Inc.
Implementation Date: 2026-02-23
Migration Phase: Phase 2 of 3
 
ACCESS ARCHITECTURE:
  Identity Provider: Google Workspace
  Access Proxy: Google Cloud IAP
  Device Management: Chrome Enterprise + Endpoint Verification
  Threat Protection: Chrome Enterprise Premium
  On-Prem Connector: BeyondCorp Enterprise Connector (3 instances)
 
ACCESS LEVEL COVERAGE:
  Access Level: corporate-managed
    Devices enrolled:              2,847 / 3,000 (94.9%)
    Compliant devices:             2,712 / 2,847 (95.3%)
  Access Level: high-trust
    Devices enrolled:              312 / 350 (89.1%)
    Compliant devices:             298 / 312 (95.5%)
 
APPLICATION MIGRATION:
  GCP HTTPS apps (IAP-protected):  32 / 35 (91.4%)
  On-prem apps (via connector):    12 / 15 (80.0%)
  SaaS apps (via SAML/OIDC):       8 / 8 (100%)
  Total migrated:                  52 / 58 (89.7%)
 
SECURITY METRICS (last 30 days):
  Total access requests:           1,247,832
  Denied by IAP policy:            3,412 (0.27%)
  Denied by access level:          1,208 (0.10%)
  Re-authentication triggered:     45,219
  Anomalous access patterns:       12 (investigated)
  VPN-related incidents (before):  8/month
  BeyondCorp incidents (after):    1/month
 
VPN DECOMMISSION STATUS:
  Parallel operation remaining:    14 days
  Users still on VPN:              148 (5%)
  Planned decommission:            2026-03-15
Source materials

References and resources

Everything below is rendered for inspection. Script files are read-only and never run.

References 3

api-reference.md1.6 KB

API Reference: BeyondCorp Zero Trust Assessment Agent

Dependencies

Library Version Purpose
requests >=2.28 HTTP client for Google Cloud IAP and Access Context Manager APIs

CLI Usage

python scripts/agent.py \
  --project my-gcp-project \
  --output-dir /reports/ \
  --output beyondcorp_report.json

Functions

get_gcloud_token() -> str

Runs gcloud auth print-access-token to obtain Bearer token.

list_iap_resources(project_id, token) -> list

GET IAP tunnel destination groups for the project.

get_iap_settings(project_id, resource, token) -> dict

GET IAP settings for a specific compute service resource.

list_access_levels(org_id, policy_name, token) -> list

GET /accessPolicies/{name}/accessLevels from Access Context Manager.

audit_iap_bindings(project_id, token) -> list

POST getIamPolicy and filters for IAP-related role bindings.

assess_zero_trust_posture(project_id, token) -> dict

Evaluates IAP coverage, binding security, checks for allUsers exposure.

generate_report(project_id, token) -> dict

Computes zero trust score (0-100) based on findings.

Google Cloud APIs Used

API Endpoint
IAP iap.googleapis.com/v1/projects/{id}/iap_tunnel/...
Access Context Manager accesscontextmanager.googleapis.com/v1/accessPolicies/...
Resource Manager cloudresourcemanager.googleapis.com/v1/projects/{id}:getIamPolicy

Output Schema

{
  "project": "my-project",
  "posture": {"iap_resources": 5, "findings": []},
  "zero_trust_score": 85
}
standards.md2.7 KB

BeyondCorp Zero Trust Standards & References

NIST SP 800-207: Zero Trust Architecture

  • Section 2: Zero Trust Tenets - defines the core principles BeyondCorp implements
  • Section 3.1: Policy Engine (PE) and Policy Administrator (PA) - maps to IAP and Access Context Manager
  • Section 3.2: Trust Algorithm - corresponds to Access Levels evaluation
  • Section 4.1: Device Agent/Gateway-Based Deployment - matches BeyondCorp connector model
  • URL: https://csrc.nist.gov/publications/detail/sp/800-207/final

CISA Zero Trust Maturity Model v2.0 (April 2023)

  • Identity Pillar: MFA enforcement, continuous validation - maps to IAP re-authentication
  • Device Pillar: Device health monitoring, compliance enforcement - maps to Endpoint Verification
  • Network Pillar: Micro-segmentation, encrypted traffic - maps to IAP tunnel encryption
  • Application Pillar: Application access authorization - maps to per-service IAP policies
  • Data Pillar: Data access governance, DLP - maps to Chrome Enterprise Premium DLP
  • URL: https://www.cisa.gov/zero-trust-maturity-model

Google BeyondCorp Papers

Google Cloud IAP Documentation

NIST SP 800-63-3: Digital Identity Guidelines

DoD Zero Trust Reference Architecture v2.0

workflows.md5.0 KB

BeyondCorp Zero Trust Implementation Workflow

Phase 1: Discovery and Planning (Weeks 1-2)

1.1 Application Inventory

  1. Enumerate all internal applications accessed via VPN or corporate network
  2. Classify each application by:
    • Hosting environment: GCP (App Engine, GKE, Compute Engine, Cloud Run), on-premises, SaaS
    • Protocol: HTTPS, TCP, SSH, RDP
    • Authentication method: SAML, OIDC, Kerberos, LDAP, custom
    • Sensitivity: Public, Internal, Confidential, Restricted
  3. Document current access patterns: which groups access which applications
  4. Identify applications that cannot be proxied (raw UDP, custom protocols)

1.2 Device Inventory

  1. Enumerate all corporate-managed and BYOD devices
  2. Document OS distribution: Windows, macOS, ChromeOS, Linux, iOS, Android
  3. Verify device management coverage: Intune, Jamf, Chrome Enterprise
  4. Identify gaps in device management enrollment

1.3 Access Level Design

  1. Define trust tiers based on organizational risk appetite:
    • Tier 1 (Basic): Any authenticated user from any device
    • Tier 2 (Standard): Authenticated user from enrolled device with screen lock
    • Tier 3 (Enhanced): Authenticated user from compliant device with disk encryption
    • Tier 4 (High): Authenticated user from managed device with EDR, specific geography
  2. Map applications to required trust tiers
  3. Define exception process for access level overrides

Phase 2: Infrastructure Setup (Weeks 3-4)

2.1 Google Cloud Configuration

  1. Enable required APIs: IAP, Access Context Manager, BeyondCorp Enterprise, Cloud Audit Logs
  2. Configure OAuth consent screen and IAP OAuth clients
  3. Set up IAP service accounts with minimal permissions
  4. Configure Cloud DNS for IAP-protected applications

2.2 Access Context Manager Setup

  1. Create access policy at the organization level
  2. Define access levels using basic conditions (device policy, IP ranges, regions)
  3. Define custom access levels using CEL expressions for complex conditions
  4. Test access levels with a pilot group before broad deployment

2.3 Endpoint Verification Deployment

  1. Deploy Endpoint Verification Chrome extension via Google Admin Console policy
  2. Configure extension settings: data collection scope, reporting frequency
  3. Allow 1-2 weeks for device inventory population
  4. Validate device attribute collection against access level requirements

Phase 3: Application Migration (Weeks 5-10)

3.1 GCP-Hosted HTTPS Applications

  1. Ensure applications are behind an HTTPS Load Balancer
  2. Enable IAP on each backend service
  3. Configure IAM bindings with access level conditions
  4. Test access with pilot users before expanding
  5. Monitor IAP access logs for false denials

3.2 On-Premises Applications

  1. Deploy BeyondCorp Enterprise connectors in on-premises DMZ
  2. Create app connections mapping external DNS to internal endpoints
  3. Configure IAP tunnels for TCP-based applications
  4. Validate network connectivity from connector to internal applications
  5. Test end-to-end access through IAP connector

3.3 SaaS Applications

  1. Configure SAML/OIDC federation from Google Workspace to SaaS apps
  2. Apply conditional access policies at the IdP level
  3. Enable session controls and re-authentication requirements

Phase 4: Policy Enforcement (Weeks 11-12)

4.1 Gradual Enforcement

  1. Start with audit-only mode: log but do not block non-compliant access
  2. Review audit logs to identify users/devices that would be blocked
  3. Communicate requirements and provide remediation guidance
  4. Enable enforcement in stages: Tier 2 first, then Tier 3, then Tier 4

4.2 Re-authentication Configuration

  1. Set session duration per application based on sensitivity:
    • General applications: 8-hour session
    • Sensitive applications: 4-hour session
    • Critical applications: 1-hour session
  2. Configure re-authentication method: LOGIN (full re-auth) or SECURE_KEY (FIDO2 touch)

Phase 5: VPN Decommission (Weeks 13-16)

5.1 Parallel Operation

  1. Run VPN and BeyondCorp in parallel for 30 days
  2. Monitor VPN usage to identify remaining dependencies
  3. Migrate stragglers and address edge cases
  4. Document break-glass procedures for BeyondCorp failure scenarios

5.2 VPN Retirement

  1. Disable new VPN connections
  2. Notify all users of VPN decommission date
  3. Remove VPN client from managed devices
  4. Decommission VPN infrastructure
  5. Redirect VPN DNS entries to BeyondCorp access portal

Phase 6: Continuous Monitoring (Ongoing)

6.1 Access Analytics

  1. Build BigQuery dashboards for access pattern analysis
  2. Configure alerting for anomalous access patterns:
    • Access from new geographies
    • Access outside business hours
    • Repeated authentication failures
    • Device compliance changes
  3. Perform monthly access reviews of IAP bindings

6.2 Policy Optimization

  1. Review access level effectiveness quarterly
  2. Adjust device posture requirements based on threat landscape
  3. Update session duration policies based on incident trends
  4. Validate break-glass procedures monthly

Scripts 2

agent.py4.8 KB
Display-only source. This catalog never executes bundled scripts.
#!/usr/bin/env python3
"""BeyondCorp zero trust access assessment agent using Google Cloud IAP API via requests."""

import argparse
import json
import logging
import os
import subprocess
import sys
from datetime import datetime
from typing import List

try:
    import requests
except ImportError:
    sys.exit("requests required: pip install requests")

logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")
logger = logging.getLogger(__name__)


def get_gcloud_token() -> str:
    """Get access token from gcloud CLI."""
    try:
        result = subprocess.run(
            ["gcloud", "auth", "print-access-token"], capture_output=True, text=True, timeout=10)
        return result.stdout.strip()
    except FileNotFoundError:
        return ""


def list_iap_resources(project_id: str, token: str) -> List[dict]:
    """List IAP-protected resources in a GCP project."""
    url = f"https://iap.googleapis.com/v1/projects/{project_id}/iap_tunnel/locations/-/destGroups"
    resp = requests.get(url, headers={"Authorization": f"Bearer {token}"}, timeout=30)
    if resp.status_code == 200:
        return resp.json().get("destGroups", [])
    return []


def get_iap_settings(project_id: str, resource: str, token: str) -> dict:
    """Get IAP settings for a specific resource."""
    url = f"https://iap.googleapis.com/v1/projects/{project_id}/iap_web/compute/services/{resource}:iapSettings"
    resp = requests.get(url, headers={"Authorization": f"Bearer {token}"}, timeout=30)
    if resp.status_code == 200:
        return resp.json()
    return {"error": resp.status_code}


def list_access_levels(org_id: str, policy_name: str, token: str) -> List[dict]:
    """List Access Context Manager access levels."""
    url = f"https://accesscontextmanager.googleapis.com/v1/accessPolicies/{policy_name}/accessLevels"
    resp = requests.get(url, headers={"Authorization": f"Bearer {token}"}, timeout=30)
    if resp.status_code == 200:
        return resp.json().get("accessLevels", [])
    return []


def audit_iap_bindings(project_id: str, token: str) -> List[dict]:
    """Audit IAM policy bindings for IAP-secured resources."""
    url = f"https://cloudresourcemanager.googleapis.com/v1/projects/{project_id}:getIamPolicy"
    resp = requests.post(url, headers={"Authorization": f"Bearer {token}"},
                         json={}, timeout=30)
    if resp.status_code != 200:
        return []
    bindings = resp.json().get("bindings", [])
    iap_bindings = [b for b in bindings if "iap" in b.get("role", "").lower()]
    return iap_bindings


def assess_zero_trust_posture(project_id: str, token: str) -> dict:
    """Assess BeyondCorp zero trust posture for a project."""
    iap_resources = list_iap_resources(project_id, token)
    iap_bindings = audit_iap_bindings(project_id, token)
    findings = []
    if not iap_resources:
        findings.append({"severity": "HIGH", "finding": "No IAP-protected resources found"})
    if not iap_bindings:
        findings.append({"severity": "HIGH", "finding": "No IAP IAM bindings configured"})
    allUsers = any("allUsers" in str(b.get("members", [])) for b in iap_bindings)
    if allUsers:
        findings.append({"severity": "CRITICAL", "finding": "IAP binding includes allUsers"})
    return {
        "iap_resources": len(iap_resources),
        "iap_bindings": len(iap_bindings),
        "findings": findings,
    }


def generate_report(project_id: str, token: str) -> dict:
    """Generate BeyondCorp zero trust assessment report."""
    report = {
        "analysis_date": datetime.utcnow().isoformat(),
        "project": project_id,
        "posture": assess_zero_trust_posture(project_id, token),
    }
    score = 100
    for f in report["posture"]["findings"]:
        if f["severity"] == "CRITICAL":
            score -= 30
        elif f["severity"] == "HIGH":
            score -= 15
    report["zero_trust_score"] = max(0, score)
    return report


def main():
    parser = argparse.ArgumentParser(description="BeyondCorp Zero Trust Assessment Agent")
    parser.add_argument("--project", required=True, help="GCP project ID")
    parser.add_argument("--token", default="", help="Access token (or uses gcloud)")
    parser.add_argument("--output-dir", default=".")
    parser.add_argument("--output", default="beyondcorp_report.json")
    args = parser.parse_args()

    token = args.token or get_gcloud_token()
    if not token:
        logger.error("No access token. Run: gcloud auth print-access-token")
        sys.exit(1)

    os.makedirs(args.output_dir, exist_ok=True)
    report = generate_report(args.project, token)
    out_path = os.path.join(args.output_dir, args.output)
    with open(out_path, "w") as f:
        json.dump(report, f, indent=2)
    logger.info("Report saved to %s", out_path)
    print(json.dumps(report, indent=2))


if __name__ == "__main__":
    main()
process.py14.3 KB
Display-only source. This catalog never executes bundled scripts.
#!/usr/bin/env python3
"""
BeyondCorp Zero Trust Access Model - Assessment and Audit Tool

Audits GCP IAP configuration, Access Context Manager access levels,
and Endpoint Verification device compliance to validate BeyondCorp
deployment readiness and ongoing compliance.

Requirements:
    pip install google-cloud-iap google-cloud-access-context-manager
    pip install google-cloud-logging google-auth pandas
"""

import json
import subprocess
import sys
from datetime import datetime, timedelta, timezone
from typing import Any


def run_gcloud(args: list[str]) -> dict | list | str:
    """Execute a gcloud command and return parsed JSON output."""
    cmd = ["gcloud"] + args + ["--format=json"]
    result = subprocess.run(cmd, capture_output=True, text=True, timeout=60)
    if result.returncode != 0:
        print(f"[ERROR] gcloud {' '.join(args[:3])}...: {result.stderr.strip()}")
        return {}
    try:
        return json.loads(result.stdout) if result.stdout.strip() else {}
    except json.JSONDecodeError:
        return result.stdout.strip()


def audit_iap_enabled_services(project_id: str) -> list[dict[str, Any]]:
    """List all backend services with IAP enabled and their policy bindings."""
    print("\n[1/6] Auditing IAP-enabled backend services...")

    backends = run_gcloud([
        "compute", "backend-services", "list",
        "--project", project_id
    ])
    if not isinstance(backends, list):
        print("  No backend services found or unable to list.")
        return []

    iap_services = []
    for backend in backends:
        name = backend.get("name", "unknown")
        iap_config = backend.get("iap", {})
        iap_enabled = iap_config.get("enabled", False)

        if iap_enabled:
            # Get IAM policy for this backend service
            policy = run_gcloud([
                "iap", "web", "get-iam-policy",
                "--resource-type=backend-services",
                "--service", name,
                "--project", project_id
            ])
            bindings = policy.get("bindings", []) if isinstance(policy, dict) else []

            iap_services.append({
                "service_name": name,
                "iap_enabled": True,
                "oauth2_client_id": iap_config.get("oauth2ClientId", "N/A"),
                "bindings_count": len(bindings),
                "bindings": bindings,
                "has_access_level_conditions": any(
                    b.get("condition") for b in bindings
                )
            })
            status = "WITH" if iap_services[-1]["has_access_level_conditions"] else "WITHOUT"
            print(f"  [IAP ON]  {name} - {len(bindings)} bindings {status} access level conditions")
        else:
            print(f"  [IAP OFF] {name}")

    return iap_services


def audit_access_levels(policy_id: str) -> list[dict[str, Any]]:
    """Enumerate and validate Access Context Manager access levels."""
    print("\n[2/6] Auditing Access Context Manager access levels...")

    levels = run_gcloud([
        "access-context-manager", "levels", "list",
        "--policy", policy_id
    ])
    if not isinstance(levels, list):
        print("  No access levels found or unable to list.")
        return []

    access_levels = []
    for level in levels:
        name = level.get("name", "").split("/")[-1]
        title = level.get("title", "Untitled")
        basic = level.get("basic", {})
        custom = level.get("custom", {})

        level_info = {
            "name": name,
            "title": title,
            "type": "basic" if basic else "custom",
            "combining_function": basic.get("combiningFunction", "AND"),
            "conditions_count": len(basic.get("conditions", [])),
            "has_device_policy": False,
            "has_ip_restriction": False,
            "has_region_restriction": False,
            "requires_encryption": False,
            "requires_screenlock": False,
        }

        for condition in basic.get("conditions", []):
            device_policy = condition.get("devicePolicy", {})
            if device_policy:
                level_info["has_device_policy"] = True
                enc_statuses = device_policy.get("allowedEncryptionStatuses", [])
                if "ENCRYPTED" in enc_statuses:
                    level_info["requires_encryption"] = True
                if device_policy.get("requireScreenlock"):
                    level_info["requires_screenlock"] = True
            if condition.get("ipSubnetworks"):
                level_info["has_ip_restriction"] = True
            if condition.get("regions"):
                level_info["has_region_restriction"] = True
                level_info["allowed_regions"] = condition["regions"]

        access_levels.append(level_info)
        print(f"  [{level_info['type'].upper()}] {title} ({name})")
        print(f"    Device policy: {level_info['has_device_policy']}, "
              f"Encryption: {level_info['requires_encryption']}, "
              f"Screen lock: {level_info['requires_screenlock']}")

    return access_levels


def audit_endpoint_verification(project_id: str) -> dict[str, Any]:
    """Check Endpoint Verification device enrollment and compliance."""
    print("\n[3/6] Auditing Endpoint Verification device compliance...")

    devices = run_gcloud([
        "alpha", "devices", "list",
        "--format=json"
    ])
    if not isinstance(devices, list):
        print("  Unable to retrieve device inventory. Ensure Endpoint Verification is deployed.")
        return {"total": 0, "compliant": 0, "non_compliant": 0}

    stats = {
        "total": len(devices),
        "compliant": 0,
        "non_compliant": 0,
        "os_distribution": {},
        "encryption_status": {"encrypted": 0, "unencrypted": 0, "unknown": 0},
        "non_compliant_devices": []
    }

    for device in devices:
        os_type = device.get("osType", "UNKNOWN")
        stats["os_distribution"][os_type] = stats["os_distribution"].get(os_type, 0) + 1

        compliance = device.get("complianceState", "UNKNOWN")
        if compliance == "COMPLIANT":
            stats["compliant"] += 1
        else:
            stats["non_compliant"] += 1
            stats["non_compliant_devices"].append({
                "device_id": device.get("name", "unknown"),
                "os": os_type,
                "compliance_state": compliance
            })

    compliance_rate = (stats["compliant"] / stats["total"] * 100) if stats["total"] > 0 else 0
    print(f"  Total devices: {stats['total']}")
    print(f"  Compliant: {stats['compliant']} ({compliance_rate:.1f}%)")
    print(f"  Non-compliant: {stats['non_compliant']}")
    print(f"  OS distribution: {stats['os_distribution']}")

    return stats


def audit_iap_access_logs(project_id: str, hours: int = 24) -> dict[str, Any]:
    """Analyze IAP access logs for denials and anomalies."""
    print(f"\n[4/6] Analyzing IAP access logs (last {hours} hours)...")

    start_time = (datetime.now(timezone.utc) - timedelta(hours=hours)).isoformat()

    log_filter = (
        f'resource.type="iap_tunnel" OR resource.type="gce_backend_service" '
        f'AND timestamp >= "{start_time}"'
    )

    logs = run_gcloud([
        "logging", "read", log_filter,
        "--project", project_id,
        "--limit=1000"
    ])
    if not isinstance(logs, list):
        print("  No IAP access logs found or unable to query.")
        return {"total": 0, "allowed": 0, "denied": 0}

    stats = {
        "total": len(logs),
        "allowed": 0,
        "denied": 0,
        "denied_users": {},
        "denied_applications": {},
        "top_accessed_apps": {}
    }

    for entry in logs:
        payload = entry.get("jsonPayload", {})
        decision = payload.get("decision", "ALLOW")
        user = payload.get("authenticationInfo", {}).get("principalEmail", "unknown")
        resource = entry.get("resource", {}).get("labels", {}).get("backend_service_name", "unknown")

        stats["top_accessed_apps"][resource] = stats["top_accessed_apps"].get(resource, 0) + 1

        if decision == "DENY":
            stats["denied"] += 1
            stats["denied_users"][user] = stats["denied_users"].get(user, 0) + 1
            stats["denied_applications"][resource] = stats["denied_applications"].get(resource, 0) + 1
        else:
            stats["allowed"] += 1

    denial_rate = (stats["denied"] / stats["total"] * 100) if stats["total"] > 0 else 0
    print(f"  Total requests: {stats['total']}")
    print(f"  Allowed: {stats['allowed']}")
    print(f"  Denied: {stats['denied']} ({denial_rate:.1f}%)")
    if stats["denied_users"]:
        top_denied = sorted(stats["denied_users"].items(), key=lambda x: x[1], reverse=True)[:5]
        print(f"  Top denied users: {top_denied}")

    return stats


def audit_session_policies(project_id: str) -> list[dict[str, Any]]:
    """Check IAP session duration and re-authentication settings."""
    print("\n[5/6] Auditing IAP session and re-authentication policies...")

    backends = run_gcloud([
        "compute", "backend-services", "list",
        "--project", project_id
    ])
    if not isinstance(backends, list):
        return []

    session_policies = []
    for backend in backends:
        iap = backend.get("iap", {})
        if not iap.get("enabled"):
            continue

        name = backend.get("name", "unknown")
        settings = run_gcloud([
            "iap", "settings", "get",
            "--project", project_id,
            "--resource-type=compute",
            "--service", name
        ])

        if isinstance(settings, dict):
            access_settings = settings.get("accessSettings", {})
            reauth = access_settings.get("reauthSettings", {})
            session_policies.append({
                "service": name,
                "max_session_duration": reauth.get("maxAge", "Not configured"),
                "reauth_method": reauth.get("method", "Not configured"),
                "policy_type": reauth.get("policyType", "DEFAULT")
            })
            print(f"  {name}: session={reauth.get('maxAge', 'default')}, "
                  f"method={reauth.get('method', 'default')}")

    return session_policies


def generate_compliance_report(
    project_id: str,
    iap_services: list,
    access_levels: list,
    device_stats: dict,
    log_stats: dict,
    session_policies: list
) -> str:
    """Generate a comprehensive BeyondCorp compliance report."""
    print("\n[6/6] Generating BeyondCorp compliance report...")

    now = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M UTC")
    total_services = len(iap_services)
    with_conditions = sum(1 for s in iap_services if s["has_access_level_conditions"])
    device_compliance = (
        (device_stats["compliant"] / device_stats["total"] * 100)
        if device_stats["total"] > 0 else 0
    )

    report = f"""
BeyondCorp Zero Trust Compliance Audit Report
{'=' * 55}
Project: {project_id}
Generated: {now}
Audit Period: Last 24 hours

1. IAP COVERAGE
   IAP-enabled services:            {total_services}
   Services with access levels:     {with_conditions} / {total_services}
   Coverage rate:                   {(with_conditions / total_services * 100) if total_services else 0:.1f}%

2. ACCESS LEVELS
   Total access levels defined:     {len(access_levels)}
   With device policy:              {sum(1 for a in access_levels if a['has_device_policy'])}
   Requiring encryption:            {sum(1 for a in access_levels if a['requires_encryption'])}
   Requiring screen lock:           {sum(1 for a in access_levels if a['requires_screenlock'])}
   With IP restrictions:            {sum(1 for a in access_levels if a['has_ip_restriction'])}
   With region restrictions:        {sum(1 for a in access_levels if a['has_region_restriction'])}

3. DEVICE COMPLIANCE
   Total enrolled devices:          {device_stats['total']}
   Compliant devices:               {device_stats['compliant']} ({device_compliance:.1f}%)
   Non-compliant devices:           {device_stats['non_compliant']}

4. ACCESS LOG ANALYSIS (24h)
   Total access requests:           {log_stats['total']}
   Allowed:                         {log_stats['allowed']}
   Denied:                          {log_stats['denied']}
   Denial rate:                     {(log_stats['denied'] / log_stats['total'] * 100) if log_stats['total'] else 0:.1f}%

5. SESSION POLICIES
   Services with re-auth policy:    {len(session_policies)}

6. RECOMMENDATIONS
"""
    recommendations = []
    if with_conditions < total_services:
        recommendations.append(
            f"   - {total_services - with_conditions} IAP services lack access level conditions. "
            "Add device posture requirements."
        )
    if device_compliance < 95:
        recommendations.append(
            f"   - Device compliance is {device_compliance:.1f}% (target: 95%). "
            "Remediate non-compliant devices."
        )
    if not any(a["requires_encryption"] for a in access_levels):
        recommendations.append(
            "   - No access levels require disk encryption. Add encryption requirement to sensitive app tiers."
        )
    if len(session_policies) < total_services:
        recommendations.append(
            f"   - {total_services - len(session_policies)} services lack explicit session policies. "
            "Configure re-authentication."
        )
    if not recommendations:
        recommendations.append("   - No critical issues found. Continue monitoring.")

    report += "\n".join(recommendations)

    return report


def main():
    if len(sys.argv) < 2:
        print("Usage: python process.py <project-id> [access-policy-id]")
        print("\nExample:")
        print("  python process.py my-gcp-project 123456789")
        sys.exit(1)

    project_id = sys.argv[1]
    policy_id = sys.argv[2] if len(sys.argv) > 2 else None

    print(f"BeyondCorp Zero Trust Audit - Project: {project_id}")
    print("=" * 55)

    iap_services = audit_iap_enabled_services(project_id)
    access_levels = audit_access_levels(policy_id) if policy_id else []
    device_stats = audit_endpoint_verification(project_id)
    log_stats = audit_iap_access_logs(project_id)
    session_policies = audit_session_policies(project_id)

    report = generate_compliance_report(
        project_id, iap_services, access_levels,
        device_stats, log_stats, session_policies
    )
    print(report)

    report_path = f"beyondcorp_audit_{project_id}_{datetime.now().strftime('%Y%m%d')}.txt"
    with open(report_path, "w") as f:
        f.write(report)
    print(f"\nReport saved to: {report_path}")


if __name__ == "__main__":
    main()

Assets 1

template.mdtext/markdown · 4.8 KB
Keep exploring