Using AWS IAM Identity Center for SSO to access shared services (OpenVPN, OpenSearch, Grafana, ArgoCD)

Table of Contents

Automat-it, as an AWS Well-Architected Partner, gains expertise in building high-quality solutions, implementing best practices, checking the state of workloads, and making improvements to fit business and customer needs.

Security Pillar is the most popular for our reviews, and one of the first questions we ask is, “How do you manage identities and permissions for people and machines?
Configuring a Single sign-on (SSO) is highly recommended as the best practice for any organization.

IAM Identity Center is the recommended service for managing your workforce’s access to AWS applications or multiple AWS accounts (or both). It is a flexible solution that can connect your identity source or help you create users in AWS. IAM Identity Center can be used alongside your existing AWS account access configurations.

This post will show how we configured SSO for AWS account access and other services (OpenVPN, OpenSearch, Grafana, and ArgoCD).

Just before we start looking at details, here is how the login page looks like in the end:

IAM Identity Center

You can enable an IAM Identity Center instance in a single, supported AWS Region of your choice. Choosing a Region requires an assessment of your priorities based on your use cases and company policies.

AWS Organizations is recommended, but not required, for use with the IAM Identity Center. You don’t have to if you haven’t set up an organization. In our case, we use AWS Organization.

If you’ve already set up AWS Organizations and will add the IAM Identity Center to your organization, ensure all AWS Organizations features are enabled. Enabling all features is the default when you create an organization.

Use your organization management account to enable the SSO, and it’s just a few clicks. When you enable IAM Identity Center, you will choose whether to enable the service with AWS Organizations.

After that, we can create users/groups and permissions sets for them and provide access to particular AWS accounts.

SSO for OpenVPN

We deploy OpenVPN Access Server from the Marketplace for many customers to provide a secure connection to private networks.

How can we configure SSO here?

First of all, we need to create a Customer managed Application in the IAM Identity Center

There are a lot of applications in the catalog, but OpenVPN is not there, so we create our own:

Choose SAML 2.0:

Add a name and description and download the metadata file. Later, you will need to upload it to the OpenVPN server.

Download the certificate, enter “profile” into Relay State, and set a Session Duration.

Application ACS URL is https://<openvpn-public-ip>/saml/acs

Application SAML audience is https://<openvpn-public-ip>/saml/metadata

Log in to the Admin panel of your OpenVPN Access Server. Select SAML as the Default Authentication System:

Go to the Authentication – SAML. Here you can find the SP Identity and SP ACS, which were entered in the previous step in the AWS IAM Identity Center

Here, you need to fill in the IAM Identity Center SAML metadata file and certificate, which were downloaded from the IAM Identity Center earlier:

Assign the required users/groups to be able to access the OpenVPN server:

Edit the Attribute mapping:

 

Subject: ${user:email}
name: email

OpenVPN successfully logs in and connects with the desktop client:

SSO for AWS Managed Grafana

This integration is super-easy. You need to select the AWS IAM Identity Center during the creation of Amazon Grafana Workspace:

Assign the required users/groups to be able to access the Grafana web UI:

You can do it from the Grafana console as well:

All users will be automatically synchronized with Grafana

SSO for Amazon OpenSearch Service

In this case, OpenSearch is used for log storage and analysis. It’s deployed in a private network and can be accessed by engineers only via OpenVPN.

This SSO configuration procedure looks similar to the above-mentioned OpenVPN. When you create an OpenSearch cluster, click “Enable SAML authentication” and import the metadata file you previously downloaded from the IAM Identity Center:

 

Set “Roles key” = Role and Session TTL

Once the cluster is created, copy the Service provider ASC URL

Application ACS URL:

https://test-cluster-jmkdoa.us-east-1.es.amazonaws.com/_dashboards/_opendistro/_security/saml/acs/idpinitiated

Application SAML audience:

https://test-cluster-jmkdoa.us-east-1.es.amazonaws.com

Edit the Attribute mapping:

 

Subject: ${user:email}    Format: emailAddress
Role: ${user:groups}      Format: unspecified

Assign the required users/groups to be able to access the OpenSearch dashboard:

SSO for ArgoCD

Argo CD is a declarative GitOps continuous delivery tool for Kubernetes. In this case, it was deployed into the EKS cluster using the Helm Chart. WebUI is exposed via internal load balancer, so can be accessed by engineers only via OpenVPN server.

The start is the same. We need to create a new Custom SAML application in the IAM Identity Center, take SAML metadata and certificate:

For automation purposes, we save the certificate in AWS Secrets Manager:

We also need to create a group in the IAM Identity Center in advance and take the Group ID:

We deploy ArgoCD as part of the infrastructure along with the EKS cluster itself. But for SSO configuration, we need to know which Helm Values we have to pass during the ArgoCD installation, whatever how we install it

dex config and rbac are interesting sections for us.

We need the SSO URL from the step where we created the SAML application in the AWS Identity Center, certificate, attribute mapping, and AWS Group ID:

configs:
      cm:
        admin.enabled: false
        url: "https://${data.kubernetes_service.this.status.0.load_balancer.0.ingress.0.hostname}"
        dex.config: |
          connectors:
            - type: saml
              id: aws
              name: "AWS"
              config:
                ssoURL: "${var.sso_url}"
                caData: "${var.ca_data}"
                entityIssuer: https://${data.kubernetes_service.this.status.0.load_balancer.0.ingress.0.hostname}/api/dex/callback
                redirectURI: https://${data.kubernetes_service.this.status.0.load_balancer.0.ingress.0.hostname}/api/dex/callback
                usernameAttr: email
                emailAttr: email
                groupsAttr: groups
      rbac:
        policy.default: role:readonly
        policy.csv: |
          p, role:readonly, applications, get, */*, allow
          p, role:readonly, certificates, get, *, allow
          p, role:readonly, clusters, get, *, allow
          p, role:readonly, repositories, get, *, allow
          p, role:readonly, projects, get, *, allow
          p, role:readonly, accounts, get, *, allow
          p, role:readonly, gpgkeys, get, *, allow
          p, role:admin, applications, create, */*, allow
          p, role:admin, applications, update, */*, allow
          p, role:admin, applications, delete, */*, allow
          p, role:admin, applications, sync, */*, allow
          p, role:admin, applications, override, */*, allow
          p, role:admin, applications, action/*, */*, allow
          p, role:admin, certificates, create, *, allow
          p, role:admin, certificates, update, *, allow
          p, role:admin, certificates, delete, *, allow
          p, role:admin, clusters, create, *, allow
          p, role:admin, clusters, update, *, allow
          p, role:admin, clusters, delete, *, allow
          p, role:admin, repositories, create, *, allow
          p, role:admin, repositories, update, *, allow
          p, role:admin, repositories, delete, *, allow
          p, role:admin, projects, create, *, allow
          p, role:admin, projects, update, *, allow
          p, role:admin, projects, delete, *, allow
          p, role:admin, accounts, update, *, allow
          p, role:admin, gpgkeys, create, *, allow
          p, role:admin, gpgkeys, delete, *, allow
          g, ${var.idp_group_id}, role:admin
          g, guest, role:readonly
        scopes: '[groups, email]'

Edit the Attribute mapping:

 

Subject: ${user:subject}    Format: persistent
groups: ${user:groups}      Format: unspecified
email: ${user:email}        Format: unspecified

Application ACS URL:

https://k8s-argo-***.elb.us-east-1.amazonaws.com/api/dex/callback

Application SAML audience:

https://k8s-argo-***.elb.us-east-1.amazonaws.com/api/dex/callback

This is the endpoint of the created internal load balancer as part of ArgoCD.

Now, ArgoCD is available from the central login page:

Conclusion

SSO is critical for any organization’s security. This post shows how we can integrate different services, such as OpenVPN, OpenSearch, Grafana, and ArgoCD, with the AWS IAM Identity Center for SSO and have SSO to different AWS accounts within the Organization. This approach allows managing users and permissions in one place and avoids static credentials.