Skip to content

Commit

Permalink
Update AWS Route53 documentation to better explain the authentication…
Browse files Browse the repository at this point in the history
… options

Signed-off-by: Richard Wall <[email protected]>
  • Loading branch information
wallrj committed Sep 11, 2024
1 parent 4b0b6fc commit 251cd75
Showing 1 changed file with 87 additions and 20 deletions.
107 changes: 87 additions & 20 deletions content/docs/configuration/acme/dns01/route53.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@ how cert-manager handles DNS01 challenges.
> (AWS) and that you already have a hosted zone in Route53.
>
> 📖 Read
> [Tutorial: Deploy cert-manager on Amazon Elastic Kubernetes (EKS) and use Let's Encrypt to sign a certificate for an HTTPS website](../../../tutorials/getting-started-aws-letsencrypt/README.md),
> which contains end-to-end instructions for those who are new to cert-manager and AWS.
> [Deploy cert-manager on AWS Elastic Kubernetes Service (EKS) and use Let's Encrypt to sign a certificate for an HTTPS website](../../../tutorials/getting-started-aws-letsencrypt/README.md),
> a tutorial which explains how to create an EKS cluster, install cert-manager, and configuring ACME ClusterIssuer using Route53 for DNS-01 challenges..
## Set up an IAM Role
## Set up an IAM Policy

cert-manager needs to be able to add records to Route53 in order to solve the
DNS01 challenge. To enable this, create a IAM policy with the following
permissions:
cert-manager needs permission to add TXT records to your Route53 zone in order to solve the DNS01 challenge.
It needs permission to delete the TXT records, after the challenge succeeds or fails.
It also needs permission to list the hosted zones, unless you use the `hostedZoneID` field.
To enable this, create an IAM policy with the following permissions in the AWS account of the Route53 zone:

```json
{
Expand Down Expand Up @@ -47,30 +48,96 @@ permissions:
}
```

> Note: The `route53:ListHostedZonesByName` statement can be removed if you
> ℹ️ The `route53:ListHostedZonesByName` statement can be removed if you
> specify the (optional) `hostedZoneID`. You can further tighten the policy by
> limiting the hosted zone that cert-manager has access to (e.g.
> `arn:aws:route53:::hostedzone/DIKER8JEXAMPLE`).
>
> 📖 Read about [actions supported by Amazon Route 53](https://docs.aws.amazon.com/Route53/latest/APIReference/API_Operations_Amazon_Route_53.html),
> in the [Amazon Route 53 API Reference](https://docs.aws.amazon.com/Route53/latest/APIReference/Welcome.html).
## Credentials

You have two options for the set up - either create a user or a role and attach
that policy from above. Using a role is considered best practice because you do
not have to store permanent credentials in a secret.
[Requests to the Route53 API must be signed using an access key ID and a secret access key](https://docs.aws.amazon.com/Route53/latest/APIReference/requests-authentication.html),
and there are several mechanisms for cert-manager to get the access key ID and secret access key,
some of which are now considered legacy.
The various mechanisms are described below in order of best practice.

### IAM Roles for Service Accounts (IRSA) with dedicated ServiceAccount

cert-manager authenticates to Route53 using temporary credentials obtained from STS,
by exchanging a temporary Kubernetes ServiceAccount token for a temporary AWS access key.

| ✔️ Advantages | ✖️ Disadvantages |
|------------------------------------------|------------------------------------------------------------|
| uses short-lived credentials | Additional Role and RoleBinding required |
| No key rotation necessary | Additional ServiceAccount required |
| No Kubernetes Secrets | Requires an AWS Identity Provider |
| Works with any Kubernetes cluster | Kubernetes cluster requires public OIDC discovery document |
| **Good isolation of Issuer permissions** | |

#### Mechanism

1. cert-manager connects to the Kubernetes API server and requests a [Kubernetes service account token](https://kubernetes.io/docs/concepts/security/service-accounts/#authenticating-credentials)
1. Kubernetes API server returns a signed JWT.
1. cert-manager connects to [AWS Security Token Service (STS)](https://docs.aws.amazon.com/STS/latest/APIReference/welcome.html)
invoking the [AssumeRoleWithWebIdentity Action](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html),
supplying the Kubernetes signed JWT and the Role ARN specified in the ClusterIssuer (or Issuer).
1. STS returns a [Temporary security credential](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html)
(a short lived AWS access key).
1. cert-manager connects to [AWS Route53](https://docs.aws.amazon.com/Route53/latest/APIReference/API_Operations.html)
invoking various actions to create TXT records to satisfy the ACME challenge.
It [signs the requests](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-signing.html) using the short lived access key.

#### Configuration

TODO

### IAM Roles for Service Accounts (IRSA) with mounted ServiceAccount token

cert-manager authenticates to Route53 using temporary credentials obtained from STS,
by exchanging a temporary Kubernetes ServiceAccount token for a temporary AWS access key.
The Kubernetes ServiceAccount token is mounted into the Pod of the cert-manager controller.

| ✔️ Advantages | ✖️ Disadvantages |
|----------------------------------|---------------------------------------------------|
| uses short-lived credentials | Requires an AWS Identity Provider |
| No key rotation necessary | **Poor isolation of Issuer permissions** |
| No Kubernetes Secrets | |
| **Works best with EKS clusters** | Requires a projected service account token volume |
| | (unless you use the EKS Pod Identity Webhook) |


#### Mechanism

1. Kubernetes API server regularly generates a signed JWT which is mounted into the cert-manager controller Pod,
at file path which is stored in the environment variable: `AWS_WEB_IDENTITY_TOKEN_FILE`.
1. cert-manager reads the signed JWT from the file system.
1. cert-manager connects to [AWS Security Token Service (STS)](https://docs.aws.amazon.com/STS/latest/APIReference/welcome.html)
invoking the [AssumeRoleWithWebIdentity Action](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html),
supplying the Kubernetes signed JWT and the Role ARN specified in the ClusterIssuer (or Issuer).
1. STS returns a [Temporary security credential](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html)
(a short lived AWS access key).
1. cert-manager connects to [AWS Route53](https://docs.aws.amazon.com/Route53/latest/APIReference/API_Operations.html)
invoking various actions to create TXT records to satisfy the ACME challenge.
It [signs the requests](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-signing.html) using the short lived access key.


#### Configuration

TODO

### Load credentials from EC2 Instance metadata service

TODO

cert-manager supports two ways of specifying credentials:
### Load User access key from dedicated Secret

- explicit by providing an `accessKeyID` or an `accessKeyIDSecretRef`, and a `secretAccessKeySecretRef`
- or implicit (using [metadata
service](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html)
or [environment variables or credentials
file](https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials).
TODO

cert-manager also supports specifying a `role` to enable cross-account access
and/or limit the access of cert-manager. Integration with
[`kiam`](https://github.com/uswitch/kiam) and
[`kube2iam`](https://github.com/jtblin/kube2iam) should work out of the box.
### Load User access key from mounted Secret

TODO

## Cross Account Access

Expand Down

0 comments on commit 251cd75

Please sign in to comment.