npx skills add mukul975/Anthropic-Cybersecurity-SkillsMITRE ATT&CK
Overview
AWS Verified Access is a Zero Trust Network Access (ZTNA) service that provides secure, VPN-less access to corporate applications hosted in AWS. It evaluates each access request in real-time against granular conditional access policies written in the Cedar policy language, ensuring access is granted per-application only when specific security requirements such as user identity and device security posture are met and maintained. Verified Access integrates with AWS IAM Identity Center, third-party identity providers (Okta, CrowdStrike, JumpCloud, Jamf), and device management solutions. For multi-account deployments, AWS Resource Access Manager (RAM) enables sharing Verified Access groups across organizational units.
When to Use
- When deploying or configuring configuring aws verified access for ztna capabilities in your environment
- When establishing security controls aligned to compliance requirements
- When building or improving security architecture for this domain
- When conducting security assessments that require this implementation
Prerequisites
- AWS account with appropriate IAM permissions
- Identity provider (AWS IAM Identity Center, Okta, or OIDC-compatible)
- Device trust provider (CrowdStrike, Jamf, JumpCloud, or AWS Verified Access native)
- Internal Application Load Balancer (ALB) or network interface endpoint
- Understanding of Cedar policy language
- VPC with application workloads to protect
Architecture
End User (Browser)
|
| HTTPS
v
+------+--------+
| Verified |
| Access |
| Endpoint |
| (Public DNS) |
+------+--------+
|
+------+--------+
| Verified | <-- Cedar Access Policies
| Access | <-- Identity Provider Signals
| Instance | <-- Device Trust Signals
| (Policy |
| Evaluation) |
+------+--------+
|
+------+--------+
| Verified |
| Access Group |
| (App Group) |
+------+--------+
|
+------+--------+
| Internal ALB |
| or ENI Target |
+------+--------+
|
+------+--------+
| Application |
| (Private VPC) |
+--------------+Core Components
Verified Access Instance
The regional entity that evaluates access requests against policies.
# Create Verified Access Instance via AWS CLI
aws ec2 create-verified-access-instance \
--description "Production Zero Trust Instance" \
--tag-specifications 'ResourceType=verified-access-instance,Tags=[{Key=Environment,Value=production}]'Trust Providers
Identity Trust Provider (AWS IAM Identity Center)
# Create identity trust provider
aws ec2 create-verified-access-trust-provider \
--trust-provider-type user \
--user-trust-provider-type iam-identity-center \
--policy-reference-name "idc" \
--description "IAM Identity Center trust provider" \
--tag-specifications 'ResourceType=verified-access-trust-provider,Tags=[{Key=Type,Value=identity}]'Identity Trust Provider (OIDC - Okta)
aws ec2 create-verified-access-trust-provider \
--trust-provider-type user \
--user-trust-provider-type oidc \
--oidc-options '{
"Issuer": "https://company.okta.com/oauth2/default",
"AuthorizationEndpoint": "https://company.okta.com/oauth2/default/v1/authorize",
"TokenEndpoint": "https://company.okta.com/oauth2/default/v1/token",
"UserInfoEndpoint": "https://company.okta.com/oauth2/default/v1/userinfo",
"ClientId": "0oa1234567890",
"ClientSecret": "client-secret-here",
"Scope": "openid profile groups"
}' \
--policy-reference-name "okta" \
--description "Okta OIDC trust provider"Device Trust Provider (CrowdStrike)
aws ec2 create-verified-access-trust-provider \
--trust-provider-type device \
--device-trust-provider-type crowdstrike \
--device-options '{
"TenantId": "crowdstrike-tenant-id",
"PublicSigningKeyUrl": "https://api.crowdstrike.com/zero-trust/v2/certificates"
}' \
--policy-reference-name "crowdstrike" \
--description "CrowdStrike device trust provider"Attach Trust Providers to Instance
# Attach identity provider
aws ec2 attach-verified-access-trust-provider \
--verified-access-instance-id vai-0123456789abcdef \
--verified-access-trust-provider-id vatp-0123456789abcdef
# Attach device provider
aws ec2 attach-verified-access-trust-provider \
--verified-access-instance-id vai-0123456789abcdef \
--verified-access-trust-provider-id vatp-device123456Verified Access Groups
# Create a group for web applications
aws ec2 create-verified-access-group \
--verified-access-instance-id vai-0123456789abcdef \
--description "Production Web Applications" \
--policy-document 'permit(principal, action, resource)
when {
context.okta.groups.contains("production-access") &&
context.crowdstrike.assessment.overall > 50
};' \
--tag-specifications 'ResourceType=verified-access-group,Tags=[{Key=Tier,Value=web}]'Verified Access Endpoints
# Create endpoint for ALB-backed application
aws ec2 create-verified-access-endpoint \
--verified-access-group-id vag-0123456789abcdef \
--endpoint-type load-balancer \
--attachment-type vpc \
--domain-certificate-arn arn:aws:acm:us-east-1:123456789012:certificate/xxxx \
--application-domain app.internal.company.com \
--endpoint-domain-prefix myapp \
--load-balancer-options '{
"LoadBalancerArn": "arn:aws:elasticloadbalancing:us-east-1:123456789012:loadbalancer/app/internal-alb/xxxx",
"Port": 443,
"Protocol": "https",
"SubnetIds": ["subnet-abc123", "subnet-def456"]
}' \
--security-group-ids sg-0123456789abcdef \
--description "Internal HR Application"Cedar Policy Language
Policy Basics
// Allow access for users in the engineering group with compliant devices
permit(principal, action, resource)
when {
context.okta.groups.contains("engineering") &&
context.crowdstrike.assessment.overall > 70 &&
context.crowdstrike.assessment.sensor_config.status == "active"
};
// Deny access from unmanaged devices
forbid(principal, action, resource)
when {
!context.crowdstrike.assessment.sensor_config.status == "active"
};Advanced Policy Examples
// Time-based access - only during business hours (UTC)
permit(principal, action, resource)
when {
context.okta.groups.contains("contractors") &&
context.http_request.http_method == "GET" &&
context.crowdstrike.assessment.overall > 80
};
// Restrict admin access to specific user group with high device trust
permit(principal, action, resource)
when {
context.idc.groups.contains("admins") &&
context.crowdstrike.assessment.overall > 90 &&
context.crowdstrike.assessment.os_version.startswith("Windows 11") ||
context.crowdstrike.assessment.os_version.startswith("macOS 14")
};
// Allow read-only access for lower trust levels
permit(principal, action, resource)
when {
context.okta.groups.contains("read-only") &&
context.crowdstrike.assessment.overall > 30 &&
context.http_request.http_method == "GET"
};Group-Level vs Endpoint-Level Policies
// Group-level policy (applies to all endpoints in the group)
// Set on the Verified Access Group
permit(principal, action, resource)
when {
context.okta.groups.contains("employees") &&
context.crowdstrike.assessment.overall > 50
};
// Endpoint-level policy (additional restrictions for specific app)
// Set on the Verified Access Endpoint
permit(principal, action, resource)
when {
context.okta.groups.contains("hr-team") &&
context.okta.email.endsWith("@company.com")
};Terraform Configuration
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
# Verified Access Instance
resource "aws_verifiedaccess_instance" "main" {
description = "Production Zero Trust Access"
tags = {
Environment = "production"
}
}
# Identity Trust Provider (OIDC)
resource "aws_verifiedaccess_trust_provider" "okta" {
policy_reference_name = "okta"
trust_provider_type = "user"
user_trust_provider_type = "oidc"
description = "Okta identity provider"
oidc_options {
authorization_endpoint = "https://company.okta.com/oauth2/default/v1/authorize"
client_id = var.okta_client_id
client_secret = var.okta_client_secret
issuer = "https://company.okta.com/oauth2/default"
scope = "openid profile groups"
token_endpoint = "https://company.okta.com/oauth2/default/v1/token"
user_info_endpoint = "https://company.okta.com/oauth2/default/v1/userinfo"
}
}
# Device Trust Provider (CrowdStrike)
resource "aws_verifiedaccess_trust_provider" "crowdstrike" {
policy_reference_name = "crowdstrike"
trust_provider_type = "device"
device_trust_provider_type = "crowdstrike"
description = "CrowdStrike device trust"
device_options {
tenant_id = var.crowdstrike_tenant_id
}
}
# Attach providers to instance
resource "aws_verifiedaccess_instance_trust_provider_attachment" "okta" {
verifiedaccess_instance_id = aws_verifiedaccess_instance.main.id
verifiedaccess_trust_provider_id = aws_verifiedaccess_trust_provider.okta.id
}
resource "aws_verifiedaccess_instance_trust_provider_attachment" "crowdstrike" {
verifiedaccess_instance_id = aws_verifiedaccess_instance.main.id
verifiedaccess_trust_provider_id = aws_verifiedaccess_trust_provider.crowdstrike.id
}
# Verified Access Group
resource "aws_verifiedaccess_group" "web_apps" {
verifiedaccess_instance_id = aws_verifiedaccess_instance.main.id
description = "Production Web Applications"
policy_document = <<-CEDAR
permit(principal, action, resource)
when {
context.okta.groups.contains("production-access") &&
context.crowdstrike.assessment.overall > 50
};
CEDAR
tags = {
Tier = "web"
}
}
# Verified Access Endpoint
resource "aws_verifiedaccess_endpoint" "internal_app" {
verified_access_group_id = aws_verifiedaccess_group.web_apps.id
endpoint_type = "load-balancer"
attachment_type = "vpc"
domain_certificate_arn = aws_acm_certificate.app.arn
application_domain = "app.internal.company.com"
endpoint_domain_prefix = "myapp"
description = "Internal Application"
load_balancer_options {
load_balancer_arn = aws_lb.internal.arn
port = 443
protocol = "https"
subnet_ids = var.private_subnet_ids
}
security_group_ids = [aws_security_group.verified_access.id]
policy_document = <<-CEDAR
permit(principal, action, resource)
when {
context.okta.groups.contains("app-users")
};
CEDAR
}
# Logging configuration
resource "aws_verifiedaccess_instance_logging_configuration" "main" {
verifiedaccess_instance_id = aws_verifiedaccess_instance.main.id
access_logs {
cloudwatch_logs {
enabled = true
log_group = aws_cloudwatch_log_group.verified_access.name
}
s3 {
enabled = true
bucket_name = aws_s3_bucket.access_logs.id
prefix = "verified-access/"
}
}
}
resource "aws_cloudwatch_log_group" "verified_access" {
name = "/aws/verified-access/production"
retention_in_days = 90
}Multi-Account Deployment with AWS RAM
# Share Verified Access Group across accounts via RAM
resource "aws_ram_resource_share" "verified_access" {
name = "verified-access-share"
allow_external_principals = false
}
resource "aws_ram_resource_association" "group_share" {
resource_arn = aws_verifiedaccess_group.web_apps.verified_access_group_arn
resource_share_arn = aws_ram_resource_share.verified_access.arn
}
resource "aws_ram_principal_association" "workload_ou" {
principal = "arn:aws:organizations::123456789012:ou/o-xxxx/ou-xxxx-xxxxxxxx"
resource_share_arn = aws_ram_resource_share.verified_access.arn
}Monitoring and Logging
# Query access logs in CloudWatch
aws logs filter-log-events \
--log-group-name /aws/verified-access/production \
--filter-pattern '{ $.status_code = "403" }' \
--start-time $(date -d '1 hour ago' +%s000)
# CloudWatch alarm for access denials
aws cloudwatch put-metric-alarm \
--alarm-name "VerifiedAccess-HighDenialRate" \
--metric-name "AccessDenied" \
--namespace "AWS/VerifiedAccess" \
--statistic Sum \
--period 300 \
--threshold 100 \
--comparison-operator GreaterThanThreshold \
--evaluation-periods 2 \
--alarm-actions arn:aws:sns:us-east-1:123456789012:security-alertsSecurity Best Practices
- Layer policies: Use group-level policies for broad controls and endpoint-level for app-specific restrictions
- Require device trust: Always include device posture checks in Cedar policies
- Enable access logging: Send to both CloudWatch and S3 for real-time monitoring and long-term retention
- Use RAM for multi-account: Share groups across OUs instead of duplicating configuration
- Rotate OIDC secrets: Automate client secret rotation via Secrets Manager
- Test policies in non-production: Validate Cedar policies before production deployment
- Set high device trust thresholds: Require overall score above 70 for production access
- Monitor for policy drift: Use AWS Config rules to detect unauthorized changes
References
References and resources
Everything below is rendered for inspection. Script files are read-only and never run.
References 3
api-reference.md1.6 KB
AWS Verified Access ZTNA — API Reference
Libraries
| Library | Install | Purpose |
|---|---|---|
| boto3 | pip install boto3 |
AWS SDK — EC2 Verified Access API |
Key boto3 EC2 Methods
| Method | Description |
|---|---|
describe_verified_access_instances() |
List VA instances |
describe_verified_access_groups() |
List VA groups with policies |
describe_verified_access_endpoints() |
List VA application endpoints |
describe_verified_access_trust_providers() |
List identity/device trust providers |
create_verified_access_instance() |
Create new VA instance |
create_verified_access_group(VerifiedAccessInstanceId=) |
Create group under instance |
create_verified_access_endpoint() |
Expose application via VA |
modify_verified_access_group_policy() |
Update Cedar policy document |
Cedar Policy Language
permit(principal, action, resource)
when {
context.identity.groups has "engineering" &&
context.identity.email.address like "*@company.com" &&
context.device.status == "compliant"
};Trust Provider Types
| Type | Description |
|---|---|
| user / iam-identity-center | AWS IAM Identity Center OIDC |
| user / oidc | Third-party OIDC provider |
| device / jamf | Jamf device trust |
| device / crowdstrike | CrowdStrike device posture |
External References
standards.md1.7 KB
Standards Reference: AWS Verified Access ZTNA
AWS Verified Access Standards
Cedar Policy Language
- Developed by AWS for fine-grained access control
- Supports permit and forbid policies with conditions
- Evaluates context attributes (identity, device posture, request metadata)
- Open-source specification at cedarpolicy.com
AWS Well-Architected Framework - Security Pillar
- SEC03-BP01: Define access requirements
- SEC03-BP02: Grant least privilege access
- SEC03-BP05: Define permission guardrails for organization
- SEC05-BP03: Automate network protection
Zero Trust Standards
NIST SP 800-207
- Verified Access implements enhanced identity governance (Section 3.1)
- Per-request policy evaluation aligns with continuous verification
- Device posture assessment satisfies device trust requirements
- Integration with identity providers meets identity pillar requirements
CISA Zero Trust Maturity Model
- Identity Pillar: OIDC integration with MFA-enabled providers
- Device Pillar: CrowdStrike/Jamf device posture assessment
- Network Pillar: VPN-less access eliminates implicit network trust
- Application Pillar: Per-application access policies
Compliance Mappings
SOC 2
- CC6.1: Logical access security through Cedar policies
- CC6.2: Identity verification via trust providers
- CC6.3: Role-based access through group policies
- CC7.2: System monitoring through access logging
FedRAMP
- AC-2: Account Management via identity provider integration
- AC-3: Access Enforcement through Cedar policies
- AC-6: Least Privilege via per-application policies
- AU-2: Auditable Events through CloudWatch logging
- SC-7: Boundary Protection via Verified Access endpoints
workflows.md2.5 KB
Workflows: AWS Verified Access ZTNA Configuration
Workflow 1: Initial Setup
Step 1: Create Verified Access Instance
- Deploy instance in target AWS region
- Tag with environment and ownership information
Step 2: Configure Trust Providers
- Set up identity trust provider (IAM Identity Center or OIDC)
- Set up device trust provider (CrowdStrike, Jamf, JumpCloud)
- Attach both providers to the Verified Access instance
Step 3: Create Access Groups
- Define groups based on application tiers or teams
- Write group-level Cedar policies
- Set baseline identity and device requirements
Step 4: Create Endpoints
- Map each application to a Verified Access endpoint
- Configure ALB or ENI attachment
- Set application domain and certificate
- Write endpoint-specific Cedar policies
Step 5: Configure DNS and Certificates
- Create ACM certificate for application domain
- Configure Route 53 CNAME to endpoint domain
- Validate certificate and DNS resolutionWorkflow 2: Cedar Policy Development
Step 1: Define Access Requirements
- Map user groups to application access needs
- Define device compliance requirements
- Identify time-based or context-based restrictions
Step 2: Write and Test Policies
- Start with permit policies for known good access
- Add forbid policies for explicit denials
- Test with various identity and device contexts
- Validate in non-production environment
Step 3: Deploy Policies
- Apply group-level policies first
- Add endpoint-specific policies for sensitive apps
- Monitor access logs for false denials
- Iterate based on user feedback
Step 4: Ongoing Maintenance
- Review policies quarterly
- Update device trust thresholds
- Add new groups as teams change
- Remove deprecated application endpointsWorkflow 3: Multi-Account Deployment
Step 1: Design Architecture
- Deploy Verified Access in dedicated networking account
- Plan group sharing via AWS RAM
- Define organizational unit boundaries
Step 2: Share Resources
- Create RAM resource shares
- Associate Verified Access groups
- Share with target OUs or accounts
Step 3: Create Endpoints in Workload Accounts
- Accept RAM shares in workload accounts
- Create endpoints using shared groups
- Configure application-specific settings
Step 4: Centralized Monitoring
- Aggregate access logs to central S3 bucket
- Configure cross-account CloudWatch dashboards
- Set up centralized alerting for policy violationsScripts 2
agent.py4.8 KB
#!/usr/bin/env python3
"""AWS Verified Access ZTNA configuration agent using boto3."""
import json
import sys
import argparse
from datetime import datetime
try:
import boto3
except ImportError:
print("Install: pip install boto3")
sys.exit(1)
def list_verified_access_instances(session):
"""List all Verified Access instances."""
ec2 = session.client("ec2")
response = ec2.describe_verified_access_instances()
instances = []
for inst in response.get("VerifiedAccessInstances", []):
instances.append({
"id": inst["VerifiedAccessInstanceId"],
"description": inst.get("Description", ""),
"creation_time": str(inst.get("CreationTime", "")),
"trust_providers": [tp["VerifiedAccessTrustProviderId"]
for tp in inst.get("VerifiedAccessTrustProviders", [])],
})
return instances
def list_verified_access_groups(session):
"""List Verified Access groups and their policies."""
ec2 = session.client("ec2")
response = ec2.describe_verified_access_groups()
groups = []
for grp in response.get("VerifiedAccessGroups", []):
groups.append({
"id": grp["VerifiedAccessGroupId"],
"instance_id": grp.get("VerifiedAccessInstanceId", ""),
"description": grp.get("Description", ""),
"policy_enabled": grp.get("PolicyEnabled", False),
"policy_document": grp.get("PolicyDocument", ""),
})
return groups
def list_verified_access_endpoints(session):
"""List Verified Access endpoints."""
ec2 = session.client("ec2")
response = ec2.describe_verified_access_endpoints()
endpoints = []
for ep in response.get("VerifiedAccessEndpoints", []):
endpoints.append({
"id": ep["VerifiedAccessEndpointId"],
"group_id": ep.get("VerifiedAccessGroupId", ""),
"type": ep.get("EndpointType", ""),
"domain": ep.get("DomainCertificateArn", ""),
"status": ep.get("Status", {}).get("Code", ""),
"application_domain": ep.get("ApplicationDomain", ""),
})
return endpoints
def audit_trust_providers(session):
"""Audit Verified Access trust providers."""
ec2 = session.client("ec2")
response = ec2.describe_verified_access_trust_providers()
providers = []
for tp in response.get("VerifiedAccessTrustProviders", []):
providers.append({
"id": tp["VerifiedAccessTrustProviderId"],
"type": tp.get("TrustProviderType", ""),
"user_trust_type": tp.get("UserTrustProviderType", ""),
"device_trust_type": tp.get("DeviceTrustProviderType", ""),
"policy_reference": tp.get("PolicyReferenceName", ""),
})
return providers
def run_audit(profile=None, region="us-east-1"):
"""Execute AWS Verified Access audit."""
session = boto3.Session(profile_name=profile, region_name=region)
print(f"\n{'='*60}")
print(f" AWS VERIFIED ACCESS ZTNA AUDIT")
print(f" Region: {region}")
print(f" Generated: {datetime.utcnow().isoformat()} UTC")
print(f"{'='*60}\n")
instances = list_verified_access_instances(session)
print(f"--- INSTANCES ({len(instances)}) ---")
for i in instances:
print(f" {i['id']}: {i['description']} (providers: {len(i['trust_providers'])})")
providers = audit_trust_providers(session)
print(f"\n--- TRUST PROVIDERS ({len(providers)}) ---")
for p in providers:
print(f" {p['id']}: type={p['type']} user={p['user_trust_type']} device={p['device_trust_type']}")
groups = list_verified_access_groups(session)
print(f"\n--- GROUPS ({len(groups)}) ---")
for g in groups:
status = "ENABLED" if g["policy_enabled"] else "DISABLED"
print(f" {g['id']}: policy={status}")
endpoints = list_verified_access_endpoints(session)
print(f"\n--- ENDPOINTS ({len(endpoints)}) ---")
for e in endpoints:
print(f" {e['id']}: {e['application_domain']} ({e['status']})")
return {"instances": instances, "providers": providers, "groups": groups, "endpoints": endpoints}
def main():
parser = argparse.ArgumentParser(description="AWS Verified Access ZTNA Agent")
parser.add_argument("--profile", help="AWS CLI profile")
parser.add_argument("--region", default="us-east-1", help="AWS region")
parser.add_argument("--audit", action="store_true", help="Run full audit")
parser.add_argument("--output", help="Save report to JSON file")
args = parser.parse_args()
if args.audit:
report = run_audit(args.profile, args.region)
if args.output:
with open(args.output, "w") as f:
json.dump(report, f, indent=2, default=str)
print(f"\n[+] Report saved to {args.output}")
else:
parser.print_help()
if __name__ == "__main__":
main()
process.py7.6 KB
#!/usr/bin/env python3
"""
AWS Verified Access ZTNA Configuration and Policy Management.
Generates Cedar access policies, validates configurations,
and monitors Verified Access deployments.
"""
import json
import datetime
from dataclasses import dataclass, field
from pathlib import Path
@dataclass
class TrustProvider:
name: str
provider_type: str # "user" or "device"
reference_name: str
config: dict = field(default_factory=dict)
@dataclass
class AccessGroup:
name: str
description: str
policy: str
endpoints: list = field(default_factory=list)
@dataclass
class AccessEndpoint:
name: str
application_domain: str
endpoint_type: str # "load-balancer" or "network-interface"
port: int = 443
policy: str = ""
alb_arn: str = ""
class CedarPolicyGenerator:
"""Generate Cedar access policies for AWS Verified Access."""
def __init__(self, identity_ref: str = "okta", device_ref: str = "crowdstrike"):
self.identity_ref = identity_ref
self.device_ref = device_ref
def permit_group_with_device_trust(self, group: str, min_score: int = 50) -> str:
return f'''permit(principal, action, resource)
when {{
context.{self.identity_ref}.groups.contains("{group}") &&
context.{self.device_ref}.assessment.overall > {min_score}
}};'''
def permit_group_read_only(self, group: str, min_score: int = 30) -> str:
return f'''permit(principal, action, resource)
when {{
context.{self.identity_ref}.groups.contains("{group}") &&
context.{self.device_ref}.assessment.overall > {min_score} &&
context.http_request.http_method == "GET"
}};'''
def forbid_unmanaged_devices(self) -> str:
return f'''forbid(principal, action, resource)
when {{
!context.{self.device_ref}.assessment.sensor_config.status == "active"
}};'''
def permit_admin_high_trust(self, admin_group: str, min_score: int = 90) -> str:
return f'''permit(principal, action, resource)
when {{
context.{self.identity_ref}.groups.contains("{admin_group}") &&
context.{self.device_ref}.assessment.overall > {min_score} &&
context.{self.identity_ref}.email.endsWith("@company.com")
}};'''
def combine_policies(self, policies: list) -> str:
return "\n\n".join(policies)
class VerifiedAccessConfigGenerator:
"""Generate Terraform configuration for AWS Verified Access."""
def __init__(self):
self.trust_providers: list[TrustProvider] = []
self.groups: list[AccessGroup] = []
self.endpoints: list[AccessEndpoint] = []
def add_trust_provider(self, name: str, provider_type: str,
reference_name: str, config: dict = None):
self.trust_providers.append(TrustProvider(
name=name, provider_type=provider_type,
reference_name=reference_name, config=config or {}
))
def add_group(self, name: str, description: str, policy: str):
self.groups.append(AccessGroup(name=name, description=description, policy=policy))
def add_endpoint(self, group_name: str, name: str, domain: str,
port: int = 443, policy: str = "", alb_arn: str = ""):
endpoint = AccessEndpoint(
name=name, application_domain=domain,
endpoint_type="load-balancer", port=port,
policy=policy, alb_arn=alb_arn
)
for group in self.groups:
if group.name == group_name:
group.endpoints.append(endpoint)
self.endpoints.append(endpoint)
def generate_terraform(self) -> str:
sections = [self._provider_block()]
sections.append('\n# Verified Access Instance')
sections.append('''resource "aws_verifiedaccess_instance" "main" {
description = "Production Zero Trust Access"
tags = {
Environment = "production"
ManagedBy = "terraform"
}
}''')
for tp in self.trust_providers:
sections.append(self._trust_provider_block(tp))
for group in self.groups:
sections.append(self._group_block(group))
for endpoint in self.endpoints:
sections.append(self._endpoint_block(endpoint))
return "\n\n".join(sections)
def _provider_block(self) -> str:
return '''terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}'''
def _trust_provider_block(self, tp: TrustProvider) -> str:
resource_name = tp.name.replace("-", "_")
return f'''resource "aws_verifiedaccess_trust_provider" "{resource_name}" {{
policy_reference_name = "{tp.reference_name}"
trust_provider_type = "{tp.provider_type}"
description = "{tp.name} trust provider"
}}
resource "aws_verifiedaccess_instance_trust_provider_attachment" "{resource_name}" {{
verifiedaccess_instance_id = aws_verifiedaccess_instance.main.id
verifiedaccess_trust_provider_id = aws_verifiedaccess_trust_provider.{resource_name}.id
}}'''
def _group_block(self, group: AccessGroup) -> str:
resource_name = group.name.replace("-", "_")
return f'''resource "aws_verifiedaccess_group" "{resource_name}" {{
verifiedaccess_instance_id = aws_verifiedaccess_instance.main.id
description = "{group.description}"
policy_document = <<-CEDAR
{group.policy}
CEDAR
}}'''
def _endpoint_block(self, endpoint: AccessEndpoint) -> str:
resource_name = endpoint.name.replace("-", "_").replace(".", "_")
policy_block = ""
if endpoint.policy:
policy_block = f'''
policy_document = <<-CEDAR
{endpoint.policy}
CEDAR'''
return f'''resource "aws_verifiedaccess_endpoint" "{resource_name}" {{
verified_access_group_id = aws_verifiedaccess_group.web_apps.id
endpoint_type = "load-balancer"
attachment_type = "vpc"
application_domain = "{endpoint.application_domain}"
description = "{endpoint.name}"{policy_block}
}}'''
def export_terraform(self, output_path: str):
config = self.generate_terraform()
path = Path(output_path)
path.parent.mkdir(parents=True, exist_ok=True)
with open(path, "w") as f:
f.write(config)
return config
def main():
"""Generate example AWS Verified Access configuration."""
# Generate Cedar policies
cedar = CedarPolicyGenerator(identity_ref="okta", device_ref="crowdstrike")
group_policy = cedar.combine_policies([
cedar.permit_group_with_device_trust("production-access", 50),
cedar.forbid_unmanaged_devices(),
])
admin_policy = cedar.permit_admin_high_trust("platform-admins", 90)
readonly_policy = cedar.permit_group_read_only("read-only-users", 30)
print("Generated Cedar Policies:")
print("=" * 60)
print("\nGroup Policy (production access):")
print(group_policy)
print(f"\nAdmin Policy:")
print(admin_policy)
print(f"\nRead-Only Policy:")
print(readonly_policy)
# Generate Terraform config
gen = VerifiedAccessConfigGenerator()
gen.add_trust_provider("okta-identity", "user", "okta")
gen.add_trust_provider("crowdstrike-device", "device", "crowdstrike")
gen.add_group("web-apps", "Production Web Applications", group_policy)
gen.add_endpoint("web-apps", "internal-app", "app.internal.company.com", 443)
gen.add_endpoint("web-apps", "admin-portal", "admin.internal.company.com", 443,
policy=admin_policy)
config = gen.export_terraform("verified_access.tf")
print("\n" + "=" * 60)
print("Generated Terraform Configuration:")
print("=" * 60)
print(config[:3000])
if __name__ == "__main__":
main()