Skip to main content

Polaris on AWS

This page explains how Polaris works on AWS and why it is built the way it is. Read Deploying Polaris first for the choices common to every cloud.

To get hands-on, start with the tutorial. To deploy and run your own workload, use the how-to guides, and to look up a region, a permission or a config key, use the AWS reference. The reference also lists what Polaris offers on AWS today and what is still to come.

The shape of a deployment​

A deployment is two confidential VMs in a VPC of their own, together with a KMS key that you own.

  • The workload VM runs your container, with the Polaris proxy in front of it and the Sentinel agent beside it.
  • The Policy Manager VM checks the evidence the workload VM sends and decides whether the workload keeps access to your key.

The Policy Manager runs on its own VM so that the machine judging the evidence is separate from the machine producing it. It is a confidential VM as well, and the workload VM's proxy checks that it runs on genuine confidential hardware before trusting any verdict from it.

On a Dedicated Host both VMs run on the host, in its Availability Zone. On shared tenancy AWS chooses the zone of each subnet, so the two VMs may sit in different zones. The workload VM sits in a public subnet and takes its public address from AWS when it launches, so the address changes whenever the VM is replaced or stopped and started. Plan DNS and client configuration around that, as described in Change a deployment.

What AWS's hardware proves​

AWS runs Polaris on AMD SEV-SNP, which encrypts the VM's memory and has the CPU sign a report describing the VM. The signature chains back to AMD, so it can be checked without trusting AWS. On shared tenancy the report is signed with a VLEK, a key AMD issues to AWS for this purpose, and the Policy Manager checks it against AMD's published keys on every cycle.

AWS hands the VM only the VLEK's certificate, without AMD's intermediate and root certificates above it. The Policy Manager gets those from AMD and keeps a copy. The Polaris SDK carries its own copies, so a client can run the same check itself on shared tenancy. See step 8 of the tutorial.

On shared tenancy the Policy Manager does not check AMD's certificate revocation list. The check rests on the chain from the VLEK up to AMD's root.

On a Dedicated Host, a physical server rented whole by your account, the report is signed with the chip's own VCEK. The Policy Manager fetches the VCEK's certificate from AMD's Key Distribution Service and keeps a copy, and it passes the certificate along when the workload VM checks it, so both directions of the check work while the workload VM stays offline. Dedicated Host support is in preview, as described in Run on a Dedicated Host.

The report includes a launch measurement, a hash of what the VM held when it started. On AWS that hash covers AWS's firmware and the number of virtual CPUs, while the operating system and everything that runs after boot are loaded later and fall outside it. A matching measurement therefore means "an SEV-SNP VM of this shape, on this AWS firmware", which is true of every VM of that shape in every AWS account. Polaris adds its own layers on top for image integrity, runtime behavior and kernel integrity, and those layers carry the evidence about what the VM actually runs. See Attestation & Trust Model for the layers.

On AWS the evidence about the software after boot comes from the Sentinel agent inside the workload VM: the kernel's measurements of every executable that runs, and what processes do and connect to. It is not yet anchored to a TPM, such as the NitroTPM that AWS's Nitro system provides, so it rests on the confidential VM that reports it rather than on a separate hardware root.

The report also has a field that names the physical chip. AWS sets it to zero on shared tenancy, so it carries no information there.

SEV-SNP is a launch setting

An instance becomes a confidential VM only when SEV-SNP is enabled as it launches, and an instance launched without it boots as an ordinary VM with no error from AWS. The Polaris tooling enables SEV-SNP for you. If you launch the Polaris image any other way, enable it yourself. An ordinary VM cannot produce a valid report, so verifying the deployment catches the mistake.

How the workload VM recognises its Policy Manager​

Since every VM of the same shape has the same launch measurement, Polaris gives each deployment a key pair of its own and uses it to tell this deployment's Policy Manager apart from any other VM.

The key pair is made before either VM boots. Its private half is encrypted so that only the Policy Manager's IAM role can decrypt it, and the workload VM holds the public half and checks the Policy Manager's signature against it. A passing check shows that the Policy Manager can act as this deployment's Policy Manager role. The software the Policy Manager runs is covered by its own attestation layers and is outside what this check shows.

After each deploy, the tooling adds a condition to the Policy Manager role's trust policy that names the Policy Manager's instance, so EC2 hands the role's credentials to that instance only. A replacement Policy Manager cannot assume the role until the tooling updates the condition, so the tooling relaxes it just before Terraform runs, in case the deploy replaces the Policy Manager, and sets it again straight after. Credentials that AWS has already issued to the Policy Manager stay valid wherever they are used until they expire. For these reasons, run each deployment in a dedicated AWS account and keep iam:PassRole on the Polaris roles to the people who deploy.

You can also pin the Policy Manager's launch measurement, and the workload VM then refuses any Policy Manager of a different shape. An AWS firmware update changes the measurement, so you capture a pinned value again after one. See Pin the Policy Manager's measurement.

How a node is named​

The Policy Manager names each workload VM aws:<account>/<instance-id> in its node registry, taken from the EC2 instance identity document. AWS signs that document, and the Policy Manager checks the signature before using it.

Everywhere else, the Policy Manager keys a workload VM on an ID it derives from the proxy's TLS key, such as snp-3645220f9c7e5aad. That is the cvm_id in watch, in the status, incident and history routes, and in the name of the grant on your key, polaris-<cvm_id>. The proxy makes a new TLS key each time it starts, so this ID changes when the proxy restarts, while the instance ID does not.

The document travels alongside the hardware report rather than inside it, so the name means "a genuine SEV-SNP VM presented a document AWS signed". Polaris limits what a borrowed document could do by allowing one key per node.

The Policy Manager checks AWS's 2048-bit RSA signature over the document, the PKCS#7 one AWS serves at /rsa2048, and no other. AWS also signs the document with a 1024-bit key, and a VM that sends only that signature gets no node name.

How your key is gated​

Your data is encrypted under a KMS key in your account, and Polaris governs access to that key while you keep it.

The Policy Manager keeps a KMS grant on your key for the workload VM's IAM role for as long as no enforcing layer fails. The grant allows Decrypt and GenerateDataKey, and the Policy Manager's role is the one that retires it. Layers in advise report findings without touching the grant, so a new deployment holds the grant while it learns, alerts included. When a layer that is enforcing fails, the Policy Manager retires the grant.

This is a real change in KMS, and you can confirm it from outside Polaris by listing the key's grants or reading CloudTrail. The grant leaves the key's grant list within seconds of the failing verdict, and it comes back with the next passing report, one report interval after the cause stops. KMS applies grant changes with eventual consistency, so a decrypt call can still succeed for a short time after the grant leaves the list, and AWS documents that this can take several minutes in some cases. Treat revocation as fast in practice and as bounded by KMS rather than by Polaris.

Revocation stops future decrypt calls. A data key your workload has already decrypted stays in its memory for as long as the workload holds it.

The grant names the workload VM's role and is limited to the deployment's encryption context, purpose=polaris-workload-data-v1 and deployment=<name>. KMS refuses a call under the grant that carries no context or another deployment's, so deployments can share a key without reading each other's data. Use the key policy in Your KMS key's policy to limit the grants the Policy Manager can make.

A KMS grant has no expiry of its own, and the grant lifetime and the silence timeout are both enforced by the Policy Manager. So each deployment also has a grant retirer, a Lambda function that runs under its own role and does not depend on the Policy Manager being up.

  • A stopped Policy Manager loses the workload's access within seconds. The instance stopping triggers the retirer, which retires this deployment's grants on your key.
  • A Policy Manager that hangs loses it within about 10 minutes. The Policy Manager writes a heartbeat every minute, and the retirer checks it every 5 minutes and retires the grants once it is more than 5 minutes old.
  • A restarted Policy Manager pulls the grant briefly. It starts with no current verdict, retires every Polaris grant it is not tracking, and grants access again on the workload VM's next passing report.

How a workload uses the key​

Your workload never holds an AWS credential and cannot reach the instance metadata service. It asks the Polaris proxy in its own VM, over two routes on the proxy's internal listener, to encrypt and decrypt. The proxy calls KMS under the workload VM's role, which only the grant lets use the key, so the next call after the grant is retired fails. The routes are in Use the gated key from your workload.

The VM's host fetches the role's credentials every five minutes and writes them where only the proxy and root on the host can read them. A non-root process on the host cannot fetch them from the metadata service, because the host firewall drops its traffic there. Credentials copied off the VM would still work from anywhere while the grant stands, which is why the reference gives a key policy statement that refuses the role's calls from outside the deployment's VPC.

The key outlives every deployment, because your data is encrypted under it. Polaris never creates or deletes your key, and changes it only by adding and retiring grants. The one key the tooling creates is the Policy Manager's identity key, which destroy schedules for deletion. A deployment's teardown revokes the grants made to that deployment's workload role. Anyone your key policy allows can always decrypt your data directly, with no Polaris component involved.

What your clients see when a check fails​

The proxy holds workload traffic when a layer you enforce fails, and serves it otherwise. Findings from layers in advise do not hold traffic. While traffic is held, new HTTP requests receive 503 with a Retry-After: 30 header and a message that ends in attestation pending, while requests already in progress run to completion.

Three moments are worth planning around.

  • At start-up. For up to two minutes after the proxy starts, it forwards requests while it waits for the Policy Manager's first verdict. A failing first verdict closes the gate at once.
  • When an enforcing layer fails. The proxy holds traffic from the report that carries the failing verdict, and it serves again with the next passing report, one report interval after the cause stops.
  • When the Policy Manager stops answering. The proxy keeps serving until five reports in a row go unanswered, about two and a half minutes at the default 30-second interval, and then holds traffic until the Policy Manager answers again.

A set of status routes stays reachable throughout, so your monitoring can tell these cases apart. See Monitor a deployment.

What stays closed​

  • Your workload never holds the VM's AWS credentials. Only the Polaris proxy signs with them. The host writes them where only the proxy's container can read them, the instance metadata service answers no container, and the host firewall drops other processes' traffic to it.
  • Outbound connections go where you allow them. The workload VM reaches ECR, S3, KMS, Secrets Manager and STS through private endpoints in the VPC, and other destinations over HTTPS to the address ranges you list. DNS lookups are the exception: they go to the VPC's AWS resolver, which security groups do not filter, so the workload can resolve any name.
  • Shell access is over SSH, when you open it. Polaris switches off the Session Manager agent. SSH opens only to the address ranges you list, and the tooling reads each VM's SSH host keys from its serial console through the AWS API and refuses to connect if they ever change.
  • Fr0ntierX has no access to your account. The deployment creates no cross-account role and no support access, and it sends no telemetry or usage metering.

The Policy Manager has no public address, and you reach it through the workload VM. It reaches the internet through a NAT gateway, mainly to fetch AMD's certificates. The AWS reference lists every destination.

Why patching means rebuilding​

The Polaris image keeps the packages it was built with, and automatic package updates are removed. Polaris measures what runs, and the runtime layer checks the digest of every executable against what the deployment learned from this exact image. An automatic update would change those files and lead Polaris to withdraw your key from a machine doing nothing wrong.

A security fix therefore arrives as a new image. You deploy it, both VMs are replaced, and Polaris learns the new image before you turn enforcement back on, at a time you choose. See Take a security fix.

Learning, then enforcing​

A new deployment starts in an advisory state with empty allowlists, and Polaris fills them by watching the healthy workload. Advisory layers report findings and leave your key alone.

Learning needs 20 clean report cycles, so at the default 30-second interval it takes at least 10 minutes, and longer when the workload keeps doing new things. While it learns, a layer can move between passing and alerting several times. A layer can also read clean for an hour and still meet a job that runs once a day. So the Policy Manager refuses to enforce a layer until it has been clean under advise for a day, with at least 90% of that day's reports received. A day covers only what ran in it, and a weekly job can still trip a layer the first time it runs after you enforce. See Move a layer to enforce.

The Policy Manager keeps which layers enforce, and everything it learned, on its state volume, and both survive a restart. It refuses to start on a record that was changed, deleted or rolled back, so a tampered state disk cannot quietly turn an enforcing deployment advisory. A deploy that changes the deployment's baseline wins over the record: the layers return to their deployed settings and Polaris learns again, since what it learned from the old image no longer applies.

What survives a replacement​

The Policy Manager keeps its state on a separate encrypted volume, including the certificates it issues to nodes, so that state survives the Policy Manager VM being replaced. A new workload VM learns again from the start.

What Polaris relies on in your account​

Polaris protects your workload from the cloud operator and from a compromised workload. Within your own AWS account, it relies on the people who can change IAM. Anyone who can pass the Polaris roles to an instance, or edit their trust policies, can act with those roles, and every such change appears in CloudTrail. A dedicated account, a short list of people with iam:PassRole, and an alert on changes to the Polaris roles keep that group small and visible.