A Visual Guide to Setting up AWS Verified Access

Chaim Sanders
6 min readDec 6, 2022

--

Every week, almost without fail, I come across one thing that confuses, entertains, or most commonly infuriates me. I’ve decided to keep a record of my adventures.

If you were following re:invent closely you’ve likely at least heard about AWS’ new Verified Access. This is Amazon’s entrance into the Zero Trust or Secure Service Edge space. Typical of AWS services, it provides a no-frills capability while also integrating directly into the AWS suite of products. Let’s look at how it works and how to configure it!

Background

AWS Verified Access effectively puts a reverse proxy in front of your load balancer/interface that acts as an OIDC Relaying Party (think SAML SP if you’re more familiar with that). The reverse proxy also has some other special features — if configured with JAMF or CrowdStrike it will use a browser extension (because writing multiple OS agents is hard) to relay device state to a third-party server for evaluation.

As seen above, AWS Verified Access requires an existing internal load balancer or network interface with a listening HTTP/HTTPS webserver on a subnet without public routing (most commonly provided by an Internet Gateway).

The Solution

For this example, my end user is going to use https://test.chaimsanders.com as the public endpoint. Please note that this tutorial assumes you’ve previously set up AWS IAM Identity Center, formerly AWS SSO. (Author’s Note: It is possible to run this without that but that will be a future blog post)

Creating Certificates

While AWS Verified Access supports use of ACM for managing and rotating public certificates, many folks will prefer to test with Let’s Encrypt given ACM’s cost. Uploading Let’s Encrypt certificates to ACM is free and it is also possible to setup ACM uploads from Let’s Encrypt programmatically to permanently use Let’s Encrypt certs for your Access Advisor instance at no cost.

One of the interesting limitations of Verified Access is that it doesn’t support wildcard certs. This in theory is slightly more secure but means you’ll have to generate a certificate for a specific domain/subdomain. For me this looked as follows:

certbot certonly --manual --preferred-challenges=dns -d test.chaimsanders.com

This will generate 3 necessary files (by default in /etc/letsencrypt/live/*).

  • cert.pem — This will be copied to the Certificate Body area
  • privkey.pem — This will be copied to the Private Key area
  • fullchain.pem — This will be copied to the Certificate Chain area

Setting Up the Load Balancer and Lambda Function

For my example we’re gonna use a load balancer (although any network interface can be used if it supports HTTP) and link it to a Python Lambda function (configured under the Lambda service) as our backend webserver (obviously this can be anything supported by an ALB).

I threw together a quick Hello World page just to demonstrate.

def lambda_handler(event, context)
return {
'headers': {
'Content-Type': 'text/html'
},oy
'statusCode': 200,
'body': "<html>hello world</html>"
}:

Next, I made the internal load balancer. These are configured under the EC2 service (again, keep in mind this MUST be on private subnets or it won’t show up — Verified Access will drop a network interface on this subnet to provide itself access). As this responds to HTTP/HTTPS it will need to be an Application Load Balancer

ALBs will require at least two subnets — as the warnings indicate, internal load balancers require these to be private.

I gave it a security group that allows access from my internal subnet on port 80. In this example I let the ALB listen on port 80 so I didn’t have to deal with additional TLS config, in a production deployment you’d give this a certificate for security purposes. Additionally, I configured the listener to point to our Lambda instance.

In the end, this was the summary of my ALB configuration:

Configuring Verified Access

Once that ALB is done allocating, we can finally start to configure all our needed aspects of Verified Access. Verified Access is available under the VPC service.

The first area I configured was a ‘Verified Access Trust Provider’. This service tells the Relaying Party what upstream OIDC server it will use and/or if it will have any Device Trust extensions enabled. For this tutorial I am not going to configure Device Trust and I’ll use the default AWS IAM Identity Center (Author’s Note: This is mostly to keep things simple, we’ll cover both of these in a future post).

The next area to configure is a ‘Verified Access Instance’. Largely these seem to exist to distribute ‘Trust Provider’ evaluation geographically, but the documentation is very brief on their actual purpose :shrug:.

Next, I’ll specify a ‘Verified Access Groups’. These allow administrators to define access policies for one or more applications (endpoints). These policies can be overwritten by the individual application as well, as we’ll see. Even though policies are optional, if you don’t fill them in it will fail closed and no access will be provided. So a simple policy can be used for testing:

permit(principal, action, resource)
when {
context.http_request.http_method != "INVALID_METHOD"
};

AWS has documentation on the Ceder policy language as it applies in this context, but at this point it has pretty limited capabilities.

With all those configurations completed I was finally ready setup a ‘Verified Access Endpoint’. This will link the Verified Access Group/Instance and the load balancer I allocated previously.

With all that information entered and the resource allocated there is one last step. You’ll need to go to your DNS management tool of choice and create a CNAME record for your domain with the value of the provided Endpoint Domain. For me that was a CNAME record for ‘test.chaimsanders.com’ with the value ‘test.edge-04e9b2d39f1b379f3.vai-00bb1f48234827a11.prod.verified-access.us-east-1.amazonaws.com’.

Testing Our Verified Access Setup

Since my instance of AWS IAM Identity Center was linked to Okta, when I navigate to https://test.chaimsanders.com i’m be redirected to login to Okta.

Even though its a long series of steps to get working, it’s not terribly complex. Happy Testing and stay tuned for more details!

--

--