The aws:verifiedaccess/endpoint:Endpoint resource, part of the Pulumi AWS provider, defines a Verified Access endpoint that validates user identity and device posture before allowing access to applications or network resources. This guide focuses on three endpoint types: ALB-based endpoints for web applications, network interface endpoints for direct EC2 access, and CIDR-based endpoints for subnet-level protection.
Verified Access endpoints belong to Verified Access groups and reference existing infrastructure such as ALBs, network interfaces, subnets, ACM certificates, and security groups. The examples are intentionally small. Combine them with your own Verified Access groups, load balancers, and access policies.
Route traffic through an Application Load Balancer
Most Verified Access deployments protect web applications behind an Application Load Balancer, validating identity and device posture before forwarding requests.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const example = new aws.verifiedaccess.Endpoint("example", {
applicationDomain: "example.com",
attachmentType: "vpc",
description: "example",
domainCertificateArn: exampleAwsAcmCertificate.arn,
endpointDomainPrefix: "example",
endpointType: "load-balancer",
loadBalancerOptions: {
loadBalancerArn: exampleAwsLb.arn,
port: 443,
protocol: "https",
subnetIds: .map(subnet => (subnet.id)),
},
securityGroupIds: [exampleAwsSecurityGroup.id],
verifiedAccessGroupId: exampleAwsVerifiedaccessGroup.id,
});
import pulumi
import pulumi_aws as aws
example = aws.verifiedaccess.Endpoint("example",
application_domain="example.com",
attachment_type="vpc",
description="example",
domain_certificate_arn=example_aws_acm_certificate["arn"],
endpoint_domain_prefix="example",
endpoint_type="load-balancer",
load_balancer_options={
"load_balancer_arn": example_aws_lb["arn"],
"port": 443,
"protocol": "https",
"subnet_ids": [subnet["id"] for subnet in public],
},
security_group_ids=[example_aws_security_group["id"]],
verified_access_group_id=example_aws_verifiedaccess_group["id"])
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var example = new Aws.VerifiedAccess.Endpoint("example", new()
{
ApplicationDomain = "example.com",
AttachmentType = "vpc",
Description = "example",
DomainCertificateArn = exampleAwsAcmCertificate.Arn,
EndpointDomainPrefix = "example",
EndpointType = "load-balancer",
LoadBalancerOptions = new Aws.VerifiedAccess.Inputs.EndpointLoadBalancerOptionsArgs
{
LoadBalancerArn = exampleAwsLb.Arn,
Port = 443,
Protocol = "https",
SubnetIds = .Select(subnet =>
{
return subnet.Id;
}).ToList(),
},
SecurityGroupIds = new[]
{
exampleAwsSecurityGroup.Id,
},
VerifiedAccessGroupId = exampleAwsVerifiedaccessGroup.Id,
});
});
When a user connects, Verified Access evaluates their identity and device state, then forwards approved requests to the ALB. The endpointType property set to “load-balancer” routes traffic through the specified loadBalancerArn. The applicationDomain and domainCertificateArn properties configure the DNS name users access and the TLS certificate that secures the connection. The certificate’s CN must match the application domain.
Protect a specific network interface
Some applications run on EC2 instances with dedicated network interfaces. Verified Access can attach directly to a network interface rather than routing through a load balancer.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const example = new aws.verifiedaccess.Endpoint("example", {
applicationDomain: "example.com",
attachmentType: "vpc",
description: "example",
domainCertificateArn: exampleAwsAcmCertificate.arn,
endpointDomainPrefix: "example",
endpointType: "network-interface",
networkInterfaceOptions: {
networkInterfaceId: exampleAwsNetworkInterface.id,
port: 443,
protocol: "https",
},
securityGroupIds: [exampleAwsSecurityGroup.id],
verifiedAccessGroupId: exampleAwsVerifiedaccessGroup.id,
});
import pulumi
import pulumi_aws as aws
example = aws.verifiedaccess.Endpoint("example",
application_domain="example.com",
attachment_type="vpc",
description="example",
domain_certificate_arn=example_aws_acm_certificate["arn"],
endpoint_domain_prefix="example",
endpoint_type="network-interface",
network_interface_options={
"network_interface_id": example_aws_network_interface["id"],
"port": 443,
"protocol": "https",
},
security_group_ids=[example_aws_security_group["id"]],
verified_access_group_id=example_aws_verifiedaccess_group["id"])
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/verifiedaccess"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := verifiedaccess.NewEndpoint(ctx, "example", &verifiedaccess.EndpointArgs{
ApplicationDomain: pulumi.String("example.com"),
AttachmentType: pulumi.String("vpc"),
Description: pulumi.String("example"),
DomainCertificateArn: pulumi.Any(exampleAwsAcmCertificate.Arn),
EndpointDomainPrefix: pulumi.String("example"),
EndpointType: pulumi.String("network-interface"),
NetworkInterfaceOptions: &verifiedaccess.EndpointNetworkInterfaceOptionsArgs{
NetworkInterfaceId: pulumi.Any(exampleAwsNetworkInterface.Id),
Port: pulumi.Int(443),
Protocol: pulumi.String("https"),
},
SecurityGroupIds: pulumi.StringArray{
exampleAwsSecurityGroup.Id,
},
VerifiedAccessGroupId: pulumi.Any(exampleAwsVerifiedaccessGroup.Id),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var example = new Aws.VerifiedAccess.Endpoint("example", new()
{
ApplicationDomain = "example.com",
AttachmentType = "vpc",
Description = "example",
DomainCertificateArn = exampleAwsAcmCertificate.Arn,
EndpointDomainPrefix = "example",
EndpointType = "network-interface",
NetworkInterfaceOptions = new Aws.VerifiedAccess.Inputs.EndpointNetworkInterfaceOptionsArgs
{
NetworkInterfaceId = exampleAwsNetworkInterface.Id,
Port = 443,
Protocol = "https",
},
SecurityGroupIds = new[]
{
exampleAwsSecurityGroup.Id,
},
VerifiedAccessGroupId = exampleAwsVerifiedaccessGroup.Id,
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.verifiedaccess.Endpoint;
import com.pulumi.aws.verifiedaccess.EndpointArgs;
import com.pulumi.aws.verifiedaccess.inputs.EndpointNetworkInterfaceOptionsArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var example = new Endpoint("example", EndpointArgs.builder()
.applicationDomain("example.com")
.attachmentType("vpc")
.description("example")
.domainCertificateArn(exampleAwsAcmCertificate.arn())
.endpointDomainPrefix("example")
.endpointType("network-interface")
.networkInterfaceOptions(EndpointNetworkInterfaceOptionsArgs.builder()
.networkInterfaceId(exampleAwsNetworkInterface.id())
.port(443)
.protocol("https")
.build())
.securityGroupIds(exampleAwsSecurityGroup.id())
.verifiedAccessGroupId(exampleAwsVerifiedaccessGroup.id())
.build());
}
}
resources:
example:
type: aws:verifiedaccess:Endpoint
properties:
applicationDomain: example.com
attachmentType: vpc
description: example
domainCertificateArn: ${exampleAwsAcmCertificate.arn}
endpointDomainPrefix: example
endpointType: network-interface
networkInterfaceOptions:
networkInterfaceId: ${exampleAwsNetworkInterface.id}
port: 443
protocol: https
securityGroupIds:
- ${exampleAwsSecurityGroup.id}
verifiedAccessGroupId: ${exampleAwsVerifiedaccessGroup.id}
The endpointType property set to “network-interface” directs traffic to a specific networkInterfaceId. This configuration works for EC2 instances, network appliances, or any resource with a dedicated ENI. Like the ALB example, it requires applicationDomain and domainCertificateArn for TLS termination.
Control access to a CIDR block range
When protecting entire subnets or IP ranges, CIDR-based endpoints validate access to any resource within the specified address space.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const example = new aws.verifiedaccess.Endpoint("example", {
attachmentType: "vpc",
description: "example",
endpointType: "cidr",
cidrOptions: {
cidr: test[0].cidrBlock,
portRanges: [{
fromPort: 443,
toPort: 443,
}],
protocol: "tcp",
subnetIds: .map(subnet => (subnet.id)),
},
securityGroupIds: [testAwsSecurityGroup.id],
verifiedAccessGroupId: testAwsVerifiedaccessGroup.id,
});
import pulumi
import pulumi_aws as aws
example = aws.verifiedaccess.Endpoint("example",
attachment_type="vpc",
description="example",
endpoint_type="cidr",
cidr_options={
"cidr": test[0]["cidrBlock"],
"port_ranges": [{
"from_port": 443,
"to_port": 443,
}],
"protocol": "tcp",
"subnet_ids": [subnet["id"] for subnet in test],
},
security_group_ids=[test_aws_security_group["id"]],
verified_access_group_id=test_aws_verifiedaccess_group["id"])
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var example = new Aws.VerifiedAccess.Endpoint("example", new()
{
AttachmentType = "vpc",
Description = "example",
EndpointType = "cidr",
CidrOptions = new Aws.VerifiedAccess.Inputs.EndpointCidrOptionsArgs
{
Cidr = test[0].CidrBlock,
PortRanges = new[]
{
new Aws.VerifiedAccess.Inputs.EndpointCidrOptionsPortRangeArgs
{
FromPort = 443,
ToPort = 443,
},
},
Protocol = "tcp",
SubnetIds = .Select(subnet =>
{
return subnet.Id;
}).ToList(),
},
SecurityGroupIds = new[]
{
testAwsSecurityGroup.Id,
},
VerifiedAccessGroupId = testAwsVerifiedaccessGroup.Id,
});
});
The endpointType property set to “cidr” protects an entire CIDR block rather than a specific load balancer or interface. The cidrOptions property defines the IP range, port ranges, and protocol. Unlike load-balancer and network-interface endpoints, CIDR endpoints don’t require applicationDomain or domainCertificateArn because they operate at the network layer rather than terminating TLS.
Beyond these examples
These snippets focus on specific endpoint-level features: load balancer, network interface, and CIDR endpoint types, TLS certificate association, and port and protocol configuration. They’re intentionally minimal rather than full zero-trust access solutions.
The examples reference pre-existing infrastructure such as Verified Access groups, ALBs, network interfaces, or VPC subnets, ACM certificates for TLS termination, and security groups. They focus on configuring the endpoint rather than provisioning the surrounding infrastructure.
To keep things focused, common endpoint patterns are omitted, including:
- Policy documents for fine-grained authorization (policyDocument)
- Server-side encryption configuration (sseSpecification)
- Custom endpoint domain prefixes (endpointDomainPrefix)
- Resource tagging (tags)
These omissions are intentional: the goal is to illustrate how each endpoint type is wired, not provide drop-in zero-trust modules. See the Verified Access Endpoint resource reference for all available configuration options.
Let's configure AWS Verified Access Endpoints
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Endpoint Types & Configuration
load-balancer (for Application/Network Load Balancers), network-interface (for Elastic Network Interfaces), and cidr (for CIDR block-based access). Each type requires different configuration options (loadBalancerOptions, networkInterfaceOptions, or cidrOptions respectively).vpc attachment type is supported.applicationDomain is required for load-balancer and network-interface endpoint types (where users access via DNS), but not for cidr type endpoints.Immutability & Updates
attachmentType, endpointType, applicationDomain, domainCertificateArn, endpointDomainPrefix, and securityGroupIds.Certificates & DNS
load-balancer and network-interface endpoint types, you must provide a domainCertificateArn pointing to an ACM certificate. The certificate’s Common Name (CN) must match the DNS name your end users will use to reach your application.applicationDomain is the DNS name you configure for users to reach your application (required input for load-balancer/network-interface types). endpointDomain is a computed output: the DNS name that AWS generates for the endpoint.Security & Networking
securityGroupIds is immutable. You must specify the correct security group IDs during creation, as changes require replacing the endpoint.deviceValidationDomain is returned only if the endpoint has a device trust provider attached.