<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>The Risky Pipeline</title>
    <description>DevOps-related code, projects, architectural diagrams, and other quips.</description>
    <link>https://adamlechnos.com/</link>
    <atom:link href="https://adamlechnos.com/sitemap.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Thu, 23 Jul 2026 17:47:41 +0000</pubDate>
    <lastBuildDate>Thu, 23 Jul 2026 17:47:41 +0000</lastBuildDate>
    <generator>Jekyll v3.10.0</generator>
    
      <item>
        <title>Managing Configurations for Prometheus and Grafana Helm Charts</title>
        <description>&lt;h3 id=&quot;diagram&quot;&gt;Diagram&lt;/h3&gt;

&lt;h4 id=&quot;managing-prometheus-and-grafana-via-helm-drawio-viewer&quot;&gt;&lt;a href=&quot;https://app.diagrams.net/?tags=%7B%7D&amp;amp;lightbox=1&amp;amp;highlight=0000ff&amp;amp;edit=_blank&amp;amp;layers=1&amp;amp;nav=1&amp;amp;title=DevOps-Observability-Prometheus_Grafana_Helm.drawio#Uhttps%3A%2F%2Fraw.githubusercontent.com%2FAdam-Lechnos%2Fdiagrams-charts%2Fmain%2Fdevops%2FDevOps-Observability-Prometheus_Grafana_Helm.drawio&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Managing Prometheus and Grafana via Helm (draw.io viewer)&lt;/a&gt;&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;https://github-content-cache.adamlechnos.com/Adam-Lechnos/diagrams-charts/blob/main/devops/DevOps-Observability-Prometheus_Grafana_Helm.drawio.svg?raw=true&quot; alt=&quot;Managing Prometheus and Grafana via Helm&quot; /&gt;
&lt;em&gt;The Prometheus Operator manages the CRDs. The Values.yaml and CRDs impacts each object’s configuration&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This blog post is in specific reference to the &lt;a href=&quot;https://artifacthub.io/packages/helm/prometheus-community/kube-prometheus-stack&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Kube Prometheus Stack&lt;/a&gt; as part of the Prometheus Community, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;prometheus-community/kube-prometheus-stack&lt;/code&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When using the Helm Charts managed by the &lt;a href=&quot;https://github.com/prometheus-community&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Prometheus Monitoring Community&lt;/a&gt; repo, certain considerations should be made when managing the Prometheus configuration options such as Alerting Rules and Scrape Configs. This post will attempt to break-down best practices using the Kubernetes &lt;a href=&quot;https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Custom Resource Definitions&lt;/a&gt; (CRDs) created by the helm chart deployment.&lt;/p&gt;

&lt;h3 id=&quot;service-discovery-versus-static-configs&quot;&gt;Service Discovery Versus Static Configs&lt;/h3&gt;
&lt;p&gt;When using the Prometheus Monitoring Community’s Kube Prometheus Stack, Service Discovery for Kubernetes is configured. Discovery is dynamic upon the creation and destruction of objects within the cluster. Objects in Kubernetes are therefore ready for monitoring in Prometheus during their lifecycle which is accomplished using the Kubernetes API server. Service Discovery configs are used in lieu of Static Configs for dynamic metrics gathering. Refer to the &lt;a href=&quot;https://prometheus.io/docs/prometheus/latest/configuration/configuration/#kubernetes_sd_config&quot;&gt;Kubernetes Service Discovery configuration&lt;/a&gt; for more details.&lt;/p&gt;

&lt;p&gt;When creating &lt;a href=&quot;https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config&quot;&gt;Scrape Configs&lt;/a&gt;, along with other Prometheus configuration options, using CRDs is the best approach when applying the Kube Prometheus Stack helm chart. The chart includes the Prometheus Controller Manager and its CRDs.&lt;/p&gt;

&lt;p&gt;Using the Service Monitor CRD automatically configures the &lt;a href=&quot;https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;relabel_config&lt;/code&gt;&lt;/a&gt; based on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;spec.selector&lt;/code&gt; within the manifest. The relabel config enables service discovery of targets for the specified job being created.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;
&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;apiVersion&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;v1&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;apiVersion&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;monitoring.coreos.com/v1&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;ServiceMonitor&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;ibkr-dash&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;release&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;prometheus&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;ibkr-dash&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;endpoints&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;interval&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;30s&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;metrics&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;namespaceSelector&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;matchNames&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;default&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;selector&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;matchLabels&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;app.kubernetes.io/managed-by&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Helm&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Will resolve to the following Configuration:&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;job_name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;serviceMonitor/default/ibkr-dash/0&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;honor_timestamps&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;track_timestamps_staleness&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;false&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;scrape_interval&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;30s&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;scrape_timeout&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;10s&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;scrape_protocols&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;OpenMetricsText1.0.0&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;OpenMetricsText0.0.1&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;PrometheusText0.0.4&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;metrics_path&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;/metrics&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;scheme&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;http&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;enable_compression&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;follow_redirects&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;enable_http2&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;http_headers&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;null&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;relabel_configs&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;source_labels&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;job&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;separator&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;regex&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;(.*)&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;target_label&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;__tmp_prometheus_job_name&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;replacement&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;$1&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;replace&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;source_labels&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;__meta_kubernetes_service_label_app_kubernetes_io_managed_by&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;nv&quot;&gt;__meta_kubernetes_service_labelpresent_app_kubernetes_io_managed_by&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;separator&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;regex&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;(Helm);true&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;replacement&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;$1&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;keep&lt;/span&gt;
&lt;span class=&quot;nn&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;kubernetes_sd_configs&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;role&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;endpoints&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;kubeconfig_file&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;follow_redirects&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;enable_http2&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;http_headers&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;null&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;namespaces&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;own_namespace&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;false&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;names&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;default&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;The above YAML has been condensed as indicated by the ellipses (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;...&lt;/code&gt;)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Notice that the resolved scrape config includes the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kubernetes_sd_configs&lt;/code&gt; for automated service discovery of endpoints created for &lt;a href=&quot;https://github.com/Adam-Lechnos/IBKR-Dashboard-K8s-Helm&quot;&gt;IBKR-Dash&lt;/a&gt; app within the default namespace. You may review the resolved configuration with the Prometheus UI by selecting Status -&amp;gt; Configuration. The application will also be populated within the Status -&amp;gt; Service Discovery view.&lt;/p&gt;

&lt;p&gt;More details about Service Monitor CRDs and why CRDs in general should be used when configuring Prometheus will be discussed further in this bog post.&lt;/p&gt;

&lt;h3 id=&quot;why-crds&quot;&gt;Why CRDs?&lt;/h3&gt;

&lt;p&gt;Making changes the the CRDs objects or creating new CRDs as defined by the helm chart enables a more clean and consistent approach to managing the configuration options for Prometheus and Grafana. Changes or additions to the CRD will perform an automated config reload against the Prometheus or Grafana objects in Kubernetes. In addition, future updates the the helm charts will prevent your custom values from being overwritten.&lt;/p&gt;

&lt;p&gt;This is in contrast to making changes by first pulling in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Values.yaml&lt;/code&gt;, editing then updating the helm charts using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-f&lt;/code&gt; flag. Using this method requires a manual reload by calling the service endpoints for the Prometheus deployment using CURL.
These CRDs are defined and managed by the &lt;a href=&quot;https://artifacthub.io/packages/olm/community-operators/prometheus&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Prometheus Operator&lt;/a&gt; built into the aforementioned helm chart.&lt;/p&gt;

&lt;p&gt;You may determine the reload endpoint by executing the following command against your Kubernetes cluster:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kubectl get sts &amp;lt;helm release&amp;gt;-prometheus-kube-prometheus-prometheus -n &amp;lt;namespace&amp;gt; -o yaml | grep reload-url&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;available-prometheus-crds&quot;&gt;Available Prometheus CRDs&lt;/h3&gt;

&lt;p&gt;To check for available CRD object which may be editing or created, execute the following command:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kubectl get crds -n &amp;lt;namespace&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each of the listed CRDs may then be called against the Kubernetes API like any other Kubernetes Object, such as a Deployments or StatefulSets. For example, for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;alertmanagers.monitoring.coreos.com&lt;/code&gt; CRD, you may list its existing objects by executing&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kubectl get alertmanagerconfigs -n &amp;lt;namespace&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;New resources created as defined by each of the CRDs must contain the configured key/value CRD label selector when populating the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;metadata.labels&lt;/code&gt; object. This enables Prometheus Service Discovery to discover the endpoints as referenced by these new resources. For example, when creating a new ServiceMonitor object for scraping a custom metrics endpoint, the endpoints referenced by the new object are not discoverable by prometheus unless the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;metadata.labels&lt;/code&gt; also matches the underlying CRD config.&lt;/p&gt;

&lt;p&gt;I will now delve into the key CRDs to create/update when managing the Helm Chart Configs for Prometheus and Grafana.&lt;/p&gt;

&lt;h3 id=&quot;alerting-rules&quot;&gt;Alerting Rules&lt;/h3&gt;

&lt;p&gt;The alerting rules are managed by the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;prometheusrules.monitoring.coreos.com&lt;/code&gt; CRD which define alert conditions for Prometheus. Learn more at the official &lt;a href=&quot;https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/&quot;&gt;Prometheus Documentation - Alerting Rules&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create a yaml manifest as follows to add a new alert rule:&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;apiVersion&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;monitoring.coreos.com/v1&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;PrometheusRule&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;release&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;prometheus&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;prometheus-example-rules&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;groups&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;./example.rules&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;rules&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;down&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;expr&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;up==0&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;0m&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;severity&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;critical&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;annotations&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;summary&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;prometheus&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;metadata.labels&lt;/code&gt; section must contain the key/value for what is configured for the underlying CRD. Check the existing CRD by running &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kubectl get prometheuses &amp;lt;helm release&amp;gt;-kube-prometheus-prometheus -n &amp;lt;namespace&amp;gt; -o yaml | grep -i matchlabels -A5&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The output will show the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;matchLabels:&lt;/code&gt; selector.&lt;/p&gt;

&lt;h3 id=&quot;scrape-configs&quot;&gt;Scrape Configs&lt;/h3&gt;

&lt;p&gt;Managed by the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;servicemonitor.monitoring.coreos.com&lt;/code&gt; CRD which specifies a set of targets and parameters describing how to scrape them. One scrape config specified a single job in prometheus. Learn more at the official &lt;a href=&quot;https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config&quot;&gt;Prometheus Documentation - Configuration/Scrape Config&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; When creating a scrape config, ensure a Kubernetes Service object exists exposing the service against the Pod/ReplicaSet/StatefulSet/daemonSet/Deployment.&lt;/p&gt;

&lt;p&gt;Create a yaml manifest as follows to add a new scrape config:&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;apiVersion&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;monitoring.coreos.com/v1&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;ServiceMonitor&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;servicemonitor-app&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;servicemonitor-app&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;release&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;prometheus&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;endpoints&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;http-metrics&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;/url/paths&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;interval&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;30s&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;namespaceSelector&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;matchNames&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;service-monitor-namespace&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;selector&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;matchLabels&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;instance&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;service&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;spec.namespaceSelector&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;spec.selector&lt;/code&gt; work together to ensure the ServiceMonitor selects the Kubernetes objects containing the custom metrics URL path such as Deployments, Pods, or StatefulSets.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;spec.endpoints&lt;/code&gt; section must reference a port’s name inside of a Service which exposes its underlying objects such as NodePort or ClusterIP.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;metadata.labels&lt;/code&gt; section must contain the key/value for what is configured for the underlying CRD. Check the existing CRD by running &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kubectl get servicemonitors &amp;lt;helm release&amp;gt;-kube-prometheus-prometheus -n monitoring -o yaml | grep -i matchLabels -A&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The output will show the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;matchLabels:&lt;/code&gt; selector.&lt;/p&gt;

&lt;h4 id=&quot;exporters&quot;&gt;Exporters&lt;/h4&gt;
&lt;p&gt;Scrape Configs are also required when adding or writing a &lt;a href=&quot;https://prometheus.io/docs/instrumenting/exporters/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Prometheus Exporter&lt;/a&gt; such as for &lt;a href=&quot;https://prometheus.io/docs/instrumenting/exporters/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Redis&lt;/a&gt;.These exporters act as a translation layer between the application and Prometheus, exposing an additional &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/metrics&lt;/code&gt; endpoint, sometimes using a sidecar container. These exporters also exist as &lt;a href=&quot;https://hub.docker.com/search?q=exporter&amp;amp;categories=Integration%20%26%20Delivery%2CMonitoring%20%26%20Observability&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Docker Images&lt;/a&gt; in Docker Hub.&lt;/p&gt;

&lt;p&gt;It is recommended to add an Exporter, if not already built into the Helm chart maintained for the application in question, by first searching for an existing Exporter within &lt;a href=&quot;https://artifacthub.io/packages/search?category=4&amp;amp;ts_query_web=prometheus+exporter&amp;amp;sort=relevance&amp;amp;page=1&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Artifact Hub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://artifacthub.io/packages/helm/bitnami/redis&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Redis Helm Chart&lt;/a&gt; for example contains a sidecar container for exposing Redis application metrics.&lt;/p&gt;

&lt;p&gt;When installing an add-on Exporter via Helm, its &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Values.yaml&lt;/code&gt; should be updated to match the key/value label as specified in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;metadata.labels&lt;/code&gt; above, in addition to the correct Service Name and Port as determined by the Service created to expose the application.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;You may use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;helm show values &amp;lt;repo/helm-chart&amp;gt; &amp;gt; values.yaml&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;helm install (or upgrade) &amp;lt;release&amp;gt; -f values.yaml&lt;/code&gt; method to accomplish this. See the chart’s documentation for more details.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;serviceMonitor&lt;/code&gt; section is what instructs the helm chart to spin-up a new ServiceMonitor CRD with the correct &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;metadata.labels&lt;/code&gt; directive in lieu of the manual steps defined above. If a comparable &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;serviceMonitor&lt;/code&gt; directive does not exist, manual steps must be taken to create each of the ServiceMonitor as defined above. In addition, if a Service is not created which exposes the Exporter pod, create one manually.&lt;/p&gt;

&lt;p&gt;Example Exporter Match Label Config Snippet:&lt;/p&gt;
&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;mongodb&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;uri&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;mongodb://mongodb-service:27017&quot;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# points to the existing Service for MongoDB&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;serviceMonitor&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;additionalLabels&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;release&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;prometheus&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# must match what is configured for the ServiceMonitor CRD. &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Check the Service created by the Exporter’s helm chart via port forwarding or creating an additional NodePort, then attempt to browse to the exposed scrape URL path, usually &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/metrics&lt;/code&gt;. You should also see the new ServiceMonitor listed as a Target in the Prometheus UI with its detected endpoints.&lt;/p&gt;

&lt;h3 id=&quot;alert-manager-rules&quot;&gt;Alert Manager Rules&lt;/h3&gt;

&lt;p&gt;Managed by the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;alertmanager.monitoring.coreos.com&lt;/code&gt; CRD which handles alerts sent by the client application. It takes care of grouping and routing alerts to the correct receiver. Learn more at the official &lt;a href=&quot;https://prometheus.io/docs/alerting/latest/alertmanager/&quot;&gt;Prometheus Documentation - AlertManger&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Create a yaml as follows to add a new alert manager rule:&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;apiVersion&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;monitoring.coreos.com/v1&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;AlertManager&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;servicemonitor-app&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;servicemonitor-app&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;release&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;prometheus&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;route&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;groupBy&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;alertname&quot;&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;groupWait&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;30s&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;groupInterval&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;5m&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;repeatInterval&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;12h&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;receiver&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;webhook&quot;&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;routes&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;matchers&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;job&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;kubernetes&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;receiver&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;infra&quot;&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;groupBy&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;severity&quot;&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;metadata.labels&lt;/code&gt; section must contain the key/value for what is configured for the underlying CRD. Check the existing CRD by running &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kubectl get alertmanagers &amp;lt;helm release&amp;gt;-kube-prometheus-alertmanager -n &amp;lt;namespace&amp;gt; -o yaml | grep -i selector&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;alertmanagerConfigSelector&lt;/code&gt; value is empty, it must first be specified by the following steps:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Execute &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;helm show values prometheus-community/kube-prometheus-stack &amp;gt; values.yaml&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Edit the values.yaml by searching &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;alertmanagerConfigSelector&lt;/code&gt;. Remove the value &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{}&lt;/code&gt; and replace with:
    &lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; &lt;span class=&quot;na&quot;&gt;alertmanagerConfigSelector&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;matchLabels&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;resource&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;prometheus&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;Execute &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;helm upgrade &amp;lt;helm release&amp;gt; prometheus-community/kube-prometheus-stack -f values.yaml&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;using-helm-values&quot;&gt;Using Helm Values&lt;/h3&gt;

&lt;p&gt;You may also edit the aforementioned config values by editing the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;values.yaml&lt;/code&gt;. This is not recommended as further updates to the helm-chart may override these values.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Execute &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;helm show values prometheus-community/kube-prometheus-stack &amp;gt; values.yaml&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Edit the values.yaml for the following configuration options (examples to uncomment are provided):
    &lt;ul&gt;
      &lt;li&gt;Scrape Config - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;additionalScrapeConfigs&lt;/code&gt; &lt;a href=&quot;https://github.com/prometheus-community/helm-charts/blob/main/charts/kube-prometheus-stack/values.yaml#L3812&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;(example)&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;Alerting Rules - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;additionalPrometheusRulesMap&lt;/code&gt; &lt;a href=&quot;https://github.com/prometheus-community/helm-charts/blob/main/charts/kube-prometheus-stack/values.yaml#L194&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;(example)&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;Alert Manager Config - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;alertManagerConfiguration&lt;/code&gt; &lt;a href=&quot;https://github.com/prometheus-community/helm-charts/blob/main/charts/kube-prometheus-stack/values.yaml#L726&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;(example)&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Execute &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;helm upgrade &amp;lt;helm release&amp;gt; prometheus-community/kube-prometheus-stack -f values.yaml&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Fri, 21 Jul 2023 12:00:00 +0000</pubDate>
        <link>https://adamlechnos.com/devops/kubernetes/helm/observability/prometheus/grafana/2023/07/21/managing-prometheus-grafana-helm-config.html</link>
        <guid isPermaLink="true">https://adamlechnos.com/devops/kubernetes/helm/observability/prometheus/grafana/2023/07/21/managing-prometheus-grafana-helm-config.html</guid>
        
        
        <category>devops</category>
        
        <category>kubernetes</category>
        
        <category>helm</category>
        
        <category>observability</category>
        
        <category>prometheus</category>
        
        <category>grafana</category>
        
      </item>
    
      <item>
        <title>AWS CDK - Breaking Down AWS Cognito OAuth &amp; OIDC Workflows</title>
        <description>&lt;h3 id=&quot;diagram&quot;&gt;Diagram&lt;/h3&gt;

&lt;h4 id=&quot;amazon-cognito-oauth--oidc-workflow-drawio-viewer&quot;&gt;&lt;a href=&quot;https://viewer.diagrams.net/?tags=%7B%7D&amp;amp;highlight=0000ff&amp;amp;edit=_blank&amp;amp;layers=1&amp;amp;nav=1&amp;amp;title=OAuth20-Sequence-Diagram.drawio#Uhttps%3A%2F%2Fraw.githubusercontent.com%2FAdam-Lechnos%2Fdiagrams-charts%2Fmain%2Fdevops%2FOAuth20-Sequence-Diagram.drawio&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Amazon Cognito OAuth &amp;amp; OIDC Workflow (draw.io viewer)&lt;/a&gt;&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;https://github-content-cache.adamlechnos.com/Adam-Lechnos/diagrams-charts/blob/main/devops/OAuth20-Sequence-Diagram.drawio.svg?raw=true&quot; alt=&quot;Amazon Cognito OAuth &amp;amp; OIDC Workflow&quot; /&gt;&lt;/p&gt;

&lt;p&gt;In my previous blog post, &lt;a href=&quot;/aws/devops/cdk/typescript/2023/02/22/aws-cdk-cognito-use.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;“AWS CDK - Using Amazon Cognito Authentication and Authorization”&lt;/a&gt;, I go-over implementing Cognito Authentication &amp;amp; Authorization workflow into your application via the AWS CDK. I attempt here, to dive deeper into the workflow components as they relate to AWS Cognito in alignment with OAuth standards. For more context, reading the previous post or series of posts within the subject matter will shed more light into this deep-dive.&lt;/p&gt;

&lt;h4 id=&quot;aws-cognito-with-cdk-post-series&quot;&gt;AWS Cognito with CDK Post Series&lt;/h4&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.adamlechnos.com/aws/devops/cdk/typescript/2023/02/20/aws-cdk-cognito.html&quot;&gt;AWS CDK - Understanding Amazon Cognito Authentication and Authorization&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.adamlechnos.com/aws/devops/cdk/typescript/2023/02/21/aws-cdk-cognito-testing.html&quot;&gt;AWS CDK - Testing Amazon Cognito Authentication and Authorization&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.adamlechnos.com/aws/devops/cdk/typescript/2023/02/22/aws-cdk-cognito-use.html&quot;&gt;AWS CDK - Using Amazon Cognito Authentication and Authorization&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;breaking-it-down&quot;&gt;Breaking It Down&lt;/h3&gt;

&lt;h4 id=&quot;components-from-left-to-right&quot;&gt;Components (from left to right)&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;Web Application - from the previous example was a React App hosted within an S3 bucket&lt;/li&gt;
  &lt;li&gt;Resource Server - Each Resource Server may contain a list of defined Custom Scopes. Authorization with an Access Code must be returned to the &lt;a href=&quot;https://docs.aws.amazon.com/cognito/latest/developerguide/token-endpoint.html&quot;&gt;Token Endpoint&lt;/a&gt; when using Authorization Code Grant to receive the Custom Scopes. Custom Scopes get injected into the Access Token based on the associated App Client. Multiple Resource Servers may defined.&lt;/li&gt;
  &lt;li&gt;Authorization Server - Cognito User Pool, where users, User Groups, User Groups default roles, App Clients, and Resource Servers are defined. Federated Identity may also be configured here.
    &lt;ul&gt;
      &lt;li&gt;App Client - Custom Scopes are attached from the Resource Server to each App Client. Multiple App Clients may be defined each with their own set of Resource Server created Custom Scopes.&lt;/li&gt;
      &lt;li&gt;Federated Identity Providers (IdP) may be OAuth, OIDC, SAML, and other popular social and cloud integrations such as ‘Sign-in with Amazon’, ‘Sign-in with Google’ and Facebook.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;AWS Credentials - Cognito Identity Pool which gets associated with an App Client. The Identity Pool associated with the App Client gets used. Role mappings are defined based on either the Rules or Token method. Refer to the &lt;a href=&quot;/aws/devops/cdk/typescript/2023/02/22/aws-cdk-cognito-use.html&quot;&gt;previous post&lt;/a&gt; for more details. Default IAM Roles are configured for Authenticated and Unauthenticated (Guest) access, providing a baseline set of roles the Web App may use. Role mapping may either be used with or overwrite the default IAM role base on the Role Mapping Rule utilized.&lt;/li&gt;
  &lt;li&gt;API Gateway - A Cognito Authorizer may be defined for the API, which then gets utilized be each API method. The API methods may specify Custom Scopes to ensure more fined-grained permissions. The API method can check for these custom scopes before access to the API is granted. Custom Scopes are defined in the Resource Server and attached to the App Client within an Identity Pool before they get injected into the the Access Token for authorization. The Base64 encoded JWT token must be specified.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;the-flow&quot;&gt;The Flow&lt;/h4&gt;

&lt;ol&gt;
  &lt;li&gt;Authenticate - Based on how the associated Identity Pool is configured, upon successful Authentication to the Hosted UI, the following gets generated:
    &lt;ol&gt;
      &lt;li&gt;Access Token (JWT format), ID Token (JWT format according to Open ID Connect), and AWS Credentials.&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;OAuth flow - Based on how the Authentication flow is configured within the App Client, upon successful authentication in step 1, the following flow occurs:
    &lt;ol&gt;
      &lt;li&gt;Implicit Grant - Requests and Returns an Access Token to the Web App via the browser (or user agent which is not depicted in the diagram)&lt;/li&gt;
      &lt;li&gt;Authorization Grant - Requests an Authorization Code to the App Clients token endpoint and returns an Access Code. Use the Access Code to request an Access Token. Custom Scopes are injected into the Access Token via the Resource Server. This exchange occurs outside of the browser on the server side whereby the server side performs the subsequent requests to the Resource Server.
        &lt;ol&gt;
          &lt;li&gt;This flow will not work with single page applications such as those written in React where no server side channel exist.&lt;/li&gt;
        &lt;/ol&gt;
      &lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;The multiple grants returned to the client as follows:
    &lt;ol&gt;
      &lt;li&gt;Access Token in JWT format - Used for accessing API resources defined within the API Gateway.&lt;/li&gt;
      &lt;li&gt;ID Token in JWT format - Open ID Connect JWT containing the Cognito Roles and Groups, which enable IAM assumed roles to the listed role ARNs, and &lt;a href=&quot;https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims&quot;&gt;standard claims&lt;/a&gt; such as ‘sub’ and ‘name’. The details provided enable personalized user experience within the web application. More details about ID TOkens from a prior &lt;a href=&quot;/aws/devops/cdk/typescript/2023/02/20/aws-cdk-cognito.html#id-tokens&quot;&gt;blog post&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;AWS Credentials - Contains an AWS Access Key, Secret Access Key, and Session Token, for use by the Web Application for access to various AWS resources. For example, permissions to an S3 bucket for uploading an image which can than be returned as a profile photo. The assumed role as contingent upon the Identity Pool’s default assigned role and/or Role Mappings which then dictate the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cognito:preferred_role&lt;/code&gt; value within the token. Refer to &lt;a href=&quot;https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-user-groups.html#assigning-precedence-values-to-groups&quot;&gt;Assigning precedence values to groups&lt;/a&gt; for more details.&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h4 id=&quot;breaking-down-oauth-scopes-a-bit-further&quot;&gt;Breaking Down OAuth Scopes A Bit Further&lt;/h4&gt;
&lt;p&gt;I wanted to add some additional context that may have been lacking in previous blog posts regarding scopes. Here is how I break down with references to additional reading:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A great example of custom scopes may be explored via &lt;a href=&quot;https://developers.google.com/oauthplayground/&quot;&gt;Google’s OAuth 2.0 Playground&lt;/a&gt;. Using these third party defined scopes is what enables access permissions to those APIs, such as the aforementioned Google APIs.&lt;/li&gt;
  &lt;li&gt;Standard scopes will also get injected. Cognito based User Pools inject the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;aws.cognito.signin.user.admin&lt;/code&gt; scope, which enables Cognito Users access read and write their attributes. Other standard scopes include:
    &lt;ul&gt;
      &lt;li&gt;openid - The minimum scope for OpenID Connect queries which authorizes the ID token the unique-identifier &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sub&lt;/code&gt;, and the ability to request other scopes&lt;/li&gt;
      &lt;li&gt;profile - Authorizes all user attributes that the app client can read&lt;/li&gt;
      &lt;li&gt;email - Authorizes the user attributes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;email&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;email_verified&lt;/code&gt; with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;email_verified&lt;/code&gt; sent back from Cognito if the value is explicitly set.&lt;/li&gt;
      &lt;li&gt;phone - Authorizes the user attributes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;phone_number&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;phone_number_verified&lt;/code&gt;.&lt;/li&gt;
      &lt;li&gt;Refer to the &lt;a href=&quot;https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-define-resource-servers.html#cognito-user-pools-define-resource-servers-about-scopes&quot;&gt;Developer Guide&lt;/a&gt; for Amazon Cognito Scopes for more details.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h5 id=&quot;example-oauth-access-token&quot;&gt;Example OAuth Access Token&lt;/h5&gt;
&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
   &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;sub&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
   &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;device_key&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
   &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;cognito:groups&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;testgroup&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
   &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
   &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;iss&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;https://cognito-idp.us-west-2.amazonaws.com/us-west-2_example&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
   &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;version&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
   &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;client_id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;xxxxxxxxxxxxexample&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
   &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;origin_jti&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
   &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;event_id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
   &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;token_use&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;access&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
   &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;scope&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;phone openid profile resourceserver.1/appclient2 email&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
   &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;auth_time&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1676313851&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
   &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;exp&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1676317451&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
   &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;iat&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1676313851&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
   &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;jti&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
   &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;username&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;my-test-user&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;breaking-down-openid-connect-a-bit-further&quot;&gt;Breaking Down OpenID Connect A Bit Further&lt;/h4&gt;
&lt;p&gt;I also wanted to add a bit more clarification regarding OpenID Connect (OIDC) ID Tokens. OpenID Connect will use the same Authorization Server as OAuth, however, for OpenID Connect, the Authorization Server will return information regarding the authenticating user. In case if you have not figured out the difference between OpenID Connect and OAuth, OpenID Connect is an Authentication protocol as opposed to OAuth being an Authorization protocol. OpenID Connect is more interested in solving Authentication and the mechanism by which we acquire details specific to the end-user, such as profile related email, name, phone number, etc.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;OpenID Connect makes use of &lt;a href=&quot;https://docs.aws.amazon.com/cognito/latest/developerguide/userinfo-endpoint.html&quot;&gt;UserInfo endpoint&lt;/a&gt;. When you specify the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;profile&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;openid&lt;/code&gt; scopes in OAuth, you are granting the bearer permissions to use the profile and other related OpenID connect information against this endpoint.&lt;/li&gt;
  &lt;li&gt;Typically, the app makes a call from the back channel and not the browser. For single page application written in client side code such as React, this will however occur between the client and Authorization server.
    &lt;ul&gt;
      &lt;li&gt;For Cognito, the UserInfo endpoint is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/oauth2/userInfo&lt;/code&gt;.&lt;/li&gt;
      &lt;li&gt;Amazon Cognito returns the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;email_verified&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;phone_number_verified&lt;/code&gt; claims within the ID Token.&lt;/li&gt;
      &lt;li&gt;Recall, the standard claims that are issued by OpenID Connect are presented within the &lt;a href=&quot;https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims&quot;&gt;official spec&lt;/a&gt;.
        &lt;ul&gt;
          &lt;li&gt;Some of these claims are: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sub&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;name&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;given_name&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;family_name&lt;/code&gt;.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;Also recall, we were scoped by the OAuth Access token which granted the application access to these claims. Cognito User Pool users only require the  &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;aws.cognito.signin.user.admin&lt;/code&gt; scope.&lt;/li&gt;
      &lt;li&gt;The user attributed are presented by the userInfo endpoint when presented with an OAuth Access Token. The Open ID Connect Token responds with user attributed based on the scopes of the OAuth token.&lt;/li&gt;
      &lt;li&gt;The OAuth third-party identity provider (IdP) also hosts a userInfo endpoint. When the user authenticated with that IdP, Cognito will exchange an authorization code with the IdP token endpoint. The user pool then passes the IdP access token to the userInfo endpoint for authorized retrieval of the user attributes from that IdP.&lt;/li&gt;
      &lt;li&gt;Read more details about the UserInfo endpoint from the &lt;a href=&quot;https://docs.aws.amazon.com/cognito/latest/developerguide/userinfo-endpoint.html&quot;&gt;Developer Guide&lt;/a&gt; for Cognito.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h5 id=&quot;example-oidc-id-token&quot;&gt;Example OIDC ID Token&lt;/h5&gt;
&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;sub&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;cognito:groups&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;test-group-a&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;test-group-b&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;test-group-c&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;email_verified&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;cognito:preferred_role&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;arn:aws:iam::111122223333:role/my-test-role&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;iss&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;https://cognito-idp.us-west-2.amazonaws.com/us-west-2_example&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;cognito:username&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;my-test-user&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;middle_name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Jane&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;nonce&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;abcdefg&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;origin_jti&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;cognito:roles&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;arn:aws:iam::111122223333:role/my-test-role&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;aud&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;xxxxxxxxxxxxexample&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;identities&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;userId&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;amzn1.account.EXAMPLE&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;providerName&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;LoginWithAmazon&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;providerType&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;LoginWithAmazon&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;issuer&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;primary&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;true&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;dateCreated&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;1642699117273&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;event_id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;64f513be-32db-42b0-b78e-b02127b4f463&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;token_use&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;auth_time&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1676312777&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;exp&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1676316377&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;iat&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1676312777&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;jti&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;email&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;my-test-user@example.com&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
        <pubDate>Sun, 05 Mar 2023 12:00:00 +0000</pubDate>
        <link>https://adamlechnos.com/aws/devops/cdk/typescript/2023/03/05/aws-cdk-cognito-workflow.html</link>
        <guid isPermaLink="true">https://adamlechnos.com/aws/devops/cdk/typescript/2023/03/05/aws-cdk-cognito-workflow.html</guid>
        
        
        <category>aws</category>
        
        <category>devops</category>
        
        <category>cdk</category>
        
        <category>typescript</category>
        
      </item>
    
      <item>
        <title>AWS CDK - Using Amazon Cognito Authentication and Authorization</title>
        <description>&lt;h3 id=&quot;diagram&quot;&gt;Diagram&lt;/h3&gt;

&lt;h4 id=&quot;amazon-cognito-client-workflow-drawio-viewer&quot;&gt;&lt;a href=&quot;https://viewer.diagrams.net/?tags=%7B%7D&amp;amp;highlight=0000ff&amp;amp;edit=_blank&amp;amp;layers=1&amp;amp;nav=1&amp;amp;title=Devops-IaC-AWS_CDK_Cognito-App.drawio#R7V1bc5vIEv41rjp7quLiKsmPWCgOWwJZEdpEednCCCN0Q0dCluDXn%2B6eQRcG20oiZe0NcVzAMMz09eumgfGV2pxt75beYmTHw2B6pUjD7ZVqXimKItU12GBLylpk6abBWsJlNORt%2B4ZelAV5R966jobB6qhjEsfTJFocN%2FrxfB74yVGbt1zGm%2BNuj%2FH0eNaFFwZCQ8%2F3pmLrl2iYjHirLEn7E5%2BCKBzxqRs6PzHz8s68YTXyhvHmoEltXanNZRwnbG%2B2bQZTlF4uF3bdx2fO7ghbBvPklAss27z%2FYm%2FcR03ZRLPFR82Svn2QdTbMkzddc445tUmai2AZr%2BfDAEeRrtTbzShKgt7C8%2FHsBrQObaNkNoUjGXaH3mpEffHgMZpOm%2FE0XsLxPJ7DFbci1ZyRp2CZBNuDJs7FXRDPgmSZQhd%2BtiHX2CXcphSNm9RmryBoZG2jA92oqsoNgxtFuBt7LzfY4aL7HjEKQgNtL3A3mpGB3QbDKPEepkFztfq8npJFX%2F8X2vl5c%2Bgl3pVqsEPl4%2BopvFJutyBWpXn%2FyVG%2BpbeK9%2BUvtTu70e571sYyjdAed%2FE3sj6Nkoc7Pbvv%2FRkPP33edKLG01Adqu25n7VnN%2Bm3tJHaprFpqziOBePCiFLwZTu9jxb1b7Pp6sGMx874Y6vb%2F9Z8dDdPvvpZf7jrU8%2Fb0fAuDL%2BZUuS6Lak9tjLLbKXtsbFx7nBrZU5k5FtGV09ixz2jeL68XyS90o8f907sl7fPF4kdaYpjhontGmtnPB233dbazroK9E%2FsVNvapr%2FuuIPEaWpaxwxD7G%2BPrcTuaWqnKW3b44Fsp1LWHvclm%2BgcbGALcgg1J90drx2zFdpN2GYh9DV0uAaubW2cSEuhDcfLnKwP5ycZ0uCMQ5CjvbbHA6nd03Qns0Pomznjv0zoq3eahtYeT7ZOiry1Nu1xNyUeXWsNupQGGfKryZ2eAfNMdBrLnKiW2YdtF8buwtZO2mN%2F4zQNoKm1BZqA90no4HVmCHyHmmUOoC2EXxjXDVXgRwfZqQ6N2wLekP5%2BSPSbsGVjbYB3lFvI5ZYwuXVDJjeD5MbmRbkZTE6pweWWH2sS6GxjNeEaotUAPkA%2FrqGATPbzZl3kQ4dxcFyN6cNS4HqUW7KT2xhlY4GMUAYT0LElwXhIg873ud3aG9KBO0lI1j2JdAY8ybCVYHyg08iAJxVkyewE6IB%2BcL6vMd5Dre2S7IA2ewu2gvJDXSooD5Ih2QDYAtiHPfa1YCYlND%2FJ1tCHkbaxzW9j6Js6TA6SjfowuzB%2FX%2B40Yd6xD7YyUGAODejRHZdkotlkS3YItBGNMB7IW5McnMvtAp8TCfwF5qX%2BktMkfSV7fwM6mN2qbddGmatAu2yTrAcof902%2BwnXO%2FkD0IJ63sDcuJUc02c26JK%2FSB3St8H9wkJ9SWQrzG915%2BsiabsToNsHHv8cwzUbsGe0KTjf36It2eCDDvLNfFlj8hzANRajJUXZ9TM2hwE%2BYQEPwK%2FbYjyAnbNzLZRHCnpi%2BgMeHdfG8WDfAh67Ou533D7sTxSUD8hKIrswLZIT7sPcGpMt2ogN4%2Fpbtg9%2BBeN2UMYm8ET6t2D%2BvkJ%2B5top6JvsHeSAcpEHYO%2BgPxh%2FQL6Nfsts2lbQ7h2XsIB0ZRMNIdK4QZ3kekC7xPMwBuFNx22hzW4ZrqHt2DBnF8eRQWZA%2F0Smc%2BQPhH0ys%2F2BHEykLcwPtHwEG%2FQlhqEwP%2BnHllC29hj1gHjGbNNxQzgON4xuC30acUJj2xDtVCXMBZ%2B2yc4t5tNmS8Ntx%2B2ibWWgZ7Drvoz6JV6wrUf%2BsmVjTfBcBj6gkJ1mfkbjjNHvUNch%2BQH6IvCJOlIY5nahv7YhvQN2oY3hPucv4fwxOTK7JPwG%2BWQoe%2BAxQR%2FHto5pMLsCTOBz5jaRMD5h7jFhE5P%2FmPAEbJrwXncIW42MeHTRj4F30lMr4zJh47lgd2OyTaRdRUyD69MOk8uWxaFQ6aBMx8iLAfI1OK9Eu8Z01SIM7XxCPwN7H9tgG5YMeIf2jHOoJC%2BUfTZAuhA7aA4aB%2FpCH53kQPgCugaabIbDW4bDloK4ArpDPUod0pm9JdqzAefb53JpyczmWqhL4McOCT%2FI52wN4zP4UIrxG3xD6SBuuwaTTTaQWa5B8Y7wzyG%2FQruxU6YrogvGtQizmH3ZyFfaZniN%2BIb6wZhBNB3wkRI%2BZhMaC%2FjBfir5VmYwnwFbBR%2FOmG0hf3%2BBn3Q1xCeH%2BOwibyqj15cRU1js8yl2OIRrocx8xd909sew7apMdzDX2FeYjlspiw0%2B2Bv6bl9l%2BObLxG9EtrDG2A1%2BzGwz69O8hDlkGxMZ%2B%2BS2BjJlNke2PgE%2F6XI8ANwfh9s25ROtkPzEJFzXnfHn2gPoFXjOSCeYb6SUx2AMwbFlJus%2B452weqKRHFls21KMhHjL9NdK2PiDkI2P8kc5oj4JfxnmZS3m2%2BSfPOZkqFuf4z3KTiJZshhGx0yWTchvoT%2FkVWSrvB%2FPPQ76RShHZkcsTtsSx2CZxcOJBDrHeA%2F6pliUdu4oT5Mpp0nR5qn%2FlnAuIx%2FVHRprIFHcSZlPYO7XIbkbuA%2F2CDIkPslWNEavdWBvfe3ALoEWG%2FWudggrbaZHd4S60Vl8B1%2BaAW04tot20uL550BieZRPPkQ%2BjViB82VsPna%2BS9jEYiDmekS3wvIGm8V6hnWaw20P6IB5DEbLGGPBgNuZnWE8AflQTEN%2BiTYXcy60Tw1tBDEsdVzCHAnmwHkYjjNc4zkj%2BbdqYz%2FKb%2FBcS4KxNxRvM8BK8BWixx1kfJ%2FFDsAStGkH71UwTzL9hOUTEssnIH9k8cRiuSXpqs%2FvGRDvKZ9gNmSiHba2zG8xn4C5030u7bjcT3AeoM3%2BYpN%2FAE%2FSHre6gBV5zoz5lYX5HPTjOsiYLwE9KrvGlnlOo%2FAclZ03MfZQjs98CuOj20X5ok%2BlTIdWSvkC5QndDcMX3O%2FLeU5COD1mOqX7Dpf8TGN5n09zOBnLV3iewfLJHO%2BYX0J8ADuE%2BR3Cg89jyjkoV4CchXIU8hFmo1mX5ysGy1ewjfmQkuc37Pq%2ByuIu49nOc5dcRpCzEMYQr12VctQe5kDsnspm8UeGe4GaFTXw7rV5kw1nPuydqfKQX8IrDzVVKDw0SuoOu2LR2esO2pmrNxcq2OT8c7HpotgUrVYiN%2FVSclMFuRlfetBgzBbT6DEVqzmTIPFHXIaLOJonRJF%2BC%2F%2BBxib71aFrE1uuFb2ksaytLjbKYjfYyGUzFBvL2upioyx2w6Oc6uPGsra6LlJcvFouuVouXA3%2F1dt4nUyjedDcFXBRxo%2FxPMkN8UpR4ecjqvfIQKHdNFVNa0L7KlnGk%2BDgzCP9OyxI4rBos5HvTdveQzC9j1dREsVzOPcQJ0k8O%2BhgTKMQTyQxeojHj3zwgWBZcBmglJetZSU%2F5paDU3qrBWPrMdoiHbd5ZXC2DbFmfu1tVtr1MljF66UfWD7ScwuHbO%2B4l8fN8yxeeaM2jryyLgleWW%2BITpm3nd0nFdEnZ14GQlCknlp55DvxyLphyHLtt%2FHIlXoeZ6zpBWfU%2FllnFB8LfQ48EFrRDYG95Fj6gmaKCpxFwyFeXpqLHGcr58g9VO1IsLJWFyRbk0qeFV0q9agJku0lHggI2j5G%2BGDo3Ym4fnNsu2pJVlwiYeVSEq4LEu6vQEyKdB%2FH0yqQvJNA8puldn4czqMkvkxqp9RE0Pul4aQhuKQ1BPaiJK3csnLL39UttVrtn3XLG8EtBT%2F8rvLROZIJvX4ko1pNzISVm5J0QtYvlU%2Fkr6IdiKmTjCijYFWjXrB8ivxfnrod2n3RL7RzaaPxqjbkX5o%2By7KgjF2ZwLi3rpTaFEX%2BANqphbh35yXBxqtKeu8lwLTqsl6%2F%2FW0CjLeI%2Fg65iZ7HZRvKkcvWZdFl9ZIgo18qyMhVYe%2Ff4JdVYe%2BH3LGRl9V37iiW2Wslz77ytvO743PPvtre7GHoVf74TvyxZdbxufLv4o9TZp3nuQ%2BrneCTJc%2Fx87bz%2B6T4HD8PkcV0tslvSItuWmpKlzaAEn2qB7fMBYs1zFqjgZkddB5Gwd7Kz%2FimQaHar5bcr%2BT3iUfJz6U%2BDMmL3ALaNqfxeihosRRfBWwt4qqAqcd4KmBVEacEjDpGSwFQi6grQPMxegsAWkRZAYpfxMdnrOfALMtunV%2FDKoCcxIO5lnwM0kSwbD0FTCGsz3TqLVbRw%2B6qZeCvl6voKfgcrNjg0nMwF8LN%2B4LIL4M3Ovs37P7to2H87ZHbC9BeGgy4AF5232nwSCOCVKJ52KYjU30p3hyBxxl8U9OOUbcUdEt8s3GxWkJe7jpwzuYUTeuEJOjANDgSso%2F7BNg9hMsjdXK1FUBSl%2FAH2qcFmBYqRt%2BJ46W%2BJIB70XTjx8fID66HARW4rmeeDwZKIjqPTRybhFrXCGMKZlFW7qvfXOuXMosT3qoL5kMDvy5F2U291SrySb%2FeMhGbDyzguIAHclumX%2FHgWpLkvGFADepNPW8wt4f9zfTw6D5YRsA1wdaLfspyrBOcAXgIg%2BSljqxfMDz6cFZU8Wshl7ctg6mXAIIeUVumUz7DPXrfQcQvWlABLBjf%2FKK9YQjjqIV3FIVyMpOLMBCoG4uLu248gj9Pr14AQb1gr2zAvfXuJPoTBi0%2BfpOv4fguQMJeef0A9UxQ86OF7CWGRm8fM49zHLPUaF%2F2yyK87L7%2B5rNcHX5gXQY7kIVI0nGZLP%2BE9yfNMS925VcAfq6CpKDi8yj1hC%2B3z4xSxwilnxWfXoWd%2BpuCnd2ryTnu3Pwg7shFANMugzvCPDfS99El1X4BUIkPJBUEKmOdjPB1Ad9LAuR5DndOUkjolUBGVXKb%2FLiEVAjusvK7ZemlV4BegTieOv8CgMtd%2BgwAp9byROonLf2DrBdKkRfENPHluMtg2o%2FDUP788Y3ikKYUsuJTcUh4bAQ21Kih26u1hpp7%2F6VRKSf%2FVFSqa%2BrlUUkVHzlrhEo%2B3BKtrsS3AED3oHpw2mVAbzl505WIUP%2BJEY%2F%2B%2FOLuQUx6pDZ6jC0tguUsAjuO56s%2F3i5i5Q57BsTSG9p5crAPhRz7Q2GEC%2BKX%2BOrpZfDrjeRkjbeNhfK5crLaZXKyulJO8LMYXeiv%2F4qbx1yoBzatIvq1tv7Im%2BNiRUX4IjR8EfvylmH0dOQctf%2BtcTWsW3xv6gMHMwN6cDzbd8gH4kC7T%2FMOXitdUKonCTj7Rz47iIMIyGl6uze%2BOaz8NMp%2BkK7lXSw%2F751vvfAI5Swo%2B2n7eaT1sun9pGXOb9edeeex%2FUEMx4Lufvaj16NVzJ7Fx%2B%2Boc%2BqF6lKDD%2FHqW43SGZ5MlUpRLzX4%2FJFIvExGcRjPvWlr31oIQvs%2B7RhLzCSscZAkKX%2FQ4q3pMeApL4gelidLyVXEkFTaTz0xJJ1s7T8lZNEyq3XhqnXhqnXhqnXhqnXhqnXhqnXhqnXhqnXhqnXhqnXhqnXhqnXhqnXhqnXh3um6cFqtWN6pX4uvsdUUsb5TfF3pbJWH2vsq76gnlne0N1XeKfl6rSrvVOWdqrxTlXeq8k5V3qnKO1V5pyrvVOWdqrxTlXeq8k5V3qnKO%2B%2BzvKPXjlfBegPlHa2qPFSVh6ryUFUeqspDVXmoKg9V5aGqPFSVh6ryUFUeqspDVXmoKg%2F%2FlspDrVYrVB4a%2F2zdQVxJRnzPZP%2BBq7g0W%2BEz1m2UfD3YP%2FiIFY7237DiwdEnrF%2F5cLtPX3cHz3z4evRBFx7ce0kSLOfUokgnv7xSvibAiS%2BvvK2lA%2BrFb9JuCkOc%2BrlsQy4OVPhm7ZnPZc%2F1PaC4aIixWAhm%2Beb%2FjJKWO3L%2BR1u0El%2B%2F0FL75eYqfvnbjsNo3oxnC3DskmXy3ryMde3mVRnv%2FlrrrxFyyd8zWCcjvpjE%2B5NwrVAr%2F8et%2BPuWZDg1YsmHEevFeHVC5PnR1RxOilgvRaLXV7t50xFr95fmvnuxm5tixDptgYfXIxYcLmNcomDfHdfRtOMhriPQ%2Bj8%3D&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Amazon Cognito Client Workflow (draw.io viewer)&lt;/a&gt;&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;https://github-content-cache.adamlechnos.com/Adam-Lechnos/diagrams-charts/blob/main/devops/Devops-IaC-AWS_CDK_Cognito-App.drawio.svg?raw=true&quot; alt=&quot;Amazon Cognito Client Workflow&quot; /&gt;&lt;/p&gt;

&lt;p&gt;In my previous blog post, &lt;a href=&quot;/aws/devops/cdk/typescript/2023/02/21/aws-cdk-cognito-testing.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;“AWS CDK - Testing Amazon Cognito Authentication and Authorization”&lt;/a&gt;, I go-over testing the Auth Service stack, ensuring we receive back proper JWT tokens. I will now illustrate how to make use of the Auth Service stack within a hypothetical React application.&lt;/p&gt;

&lt;h3 id=&quot;components&quot;&gt;Components&lt;/h3&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Component&lt;/th&gt;
      &lt;th&gt;File Name&lt;/th&gt;
      &lt;th&gt;Description&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Authentication Service&lt;/td&gt;
      &lt;td&gt;AuthService.ts&lt;/td&gt;
      &lt;td&gt;Perform user challenge and authentication and authorization, returning JWT Tokens and AWS Credentials.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Login Component&lt;/td&gt;
      &lt;td&gt;LoginComponent.tsx&lt;/td&gt;
      &lt;td&gt;A very simple react component, which will perform the authentication, using the AuthService.ts service file.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Frontend Router&lt;/td&gt;
      &lt;td&gt;App.tsx&lt;/td&gt;
      &lt;td&gt;A very simple React frontend web application which will present a router, with ‘/login’ making a call to LoginComponent.tsx.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h3 id=&quot;overview&quot;&gt;Overview&lt;/h3&gt;
&lt;p&gt;The components are stored and bundled into an S3 Bucket and served as static content. Hypothetically, in addition to the Authentication Service, APIs called via API Gateway can be used to trigger Lambda functions, which can make use of the custom scopes as injected by a Cognito Identity Pool client and/or, the ID Token used as an Authorization header to the API, whereby API Gateway can desingate Cognito as an Authorizer to check for access. We may also parse group memberships within the token to determine whether certain API methods are allowed or not.&lt;/p&gt;

&lt;h3 id=&quot;breaking-it-down&quot;&gt;Breaking It Down&lt;/h3&gt;

&lt;h4 id=&quot;authentication-service&quot;&gt;Authentication Service&lt;/h4&gt;
&lt;p&gt;&lt;a href=&quot;https://gist.github.com/Adam-Lechnos/fc1a9ead7491b8435be9fe1777c36b98&quot; target=&quot;_blank&quot;&gt;Full Code -&amp;gt; GitHub Gist&lt;/a&gt;&lt;/p&gt;

&lt;!-- &lt;script src=&quot;https://gist.github.com/fc1a9ead7491b8435be9fe1777c36b98.js&quot;&gt; &lt;/script&gt; --&gt;

&lt;p&gt;The authentication service code has been discussed at length, from the previous two blog posts, we perform a deep dive into creating a testing the auth service stack. The code here is identical to what we &lt;a href=&quot;/aws/devops/cdk/typescript/2023/02/21/aws-cdk-cognito-testing.html&quot;&gt;previously&lt;/a&gt; covered.&lt;/p&gt;

&lt;p&gt;Some additional changes made to the AuthService file are as follows:&lt;/p&gt;

&lt;div class=&quot;language-typescript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;generateTemporaryCredentials&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cognitoIdentityPool&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;`cognito-idp.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;awsRegion&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.amazonaws.com/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;AuthStack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;SpaceUserPoolId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cognitoIdentity&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;CognitoIdentityClient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;credentials&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;fromCognitoIdentityPool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;clientConfig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;na&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;awsRegion&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;identityPoolId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;AuthStack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;SpaceIdentityPoolId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;logins&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;cognitoIdentityPool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;jwtToken&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;credentials&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cognitoIdentity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;credentials&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;credentials&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;The function above will use Cognito for access to the temporary AWS Credentials by supplying the JWT Auth Token. When the Web Application wants to perform a task on behalf of the user, such as uploading a photo to an S3 bucket, these credentials may be used.
    &lt;ul&gt;
      &lt;li&gt;The Assumed IAM Role for the Credentials will be the Authenticated default for Cognito. Any additional Cognito groups with designated IAM roles will also provide those permissions as well.
        &lt;ul&gt;
          &lt;li&gt;This is useful for delineating group permissions according to membership type, such as premium vs non-premium members.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;login-component&quot;&gt;Login Component&lt;/h4&gt;
&lt;p&gt;&lt;a href=&quot;https://gist.github.com/Adam-Lechnos/d8f8dc6d244b49fe3c6969ced5151743&quot; target=&quot;_blank&quot;&gt;Full Code -&amp;gt; GitHub Gist&lt;/a&gt;
&lt;!-- &lt;script src=&quot;https://gist.github.com/d8f8dc6d244b49fe3c6969ced5151743.js&quot;&gt; &lt;/script&gt; --&gt;&lt;/p&gt;

&lt;p&gt;Here we break down the code used for performing the login and ensuring the user authenticated. We make extensive use of &lt;a href=&quot;https://react.dev/reference/react/hooks#state-hooks&quot;&gt;State Hooks&lt;/a&gt;, which provide a clean way to initialize and update states across our web app.&lt;/p&gt;

&lt;div class=&quot;language-typescript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;LoginProps&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;authService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;AuthService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;setUserNameCb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;userName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;LoginComponent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;authService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;setUserNameCb&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;LoginProps&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;userName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;setUserName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;password&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;setPassword&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;errorMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;setErrorMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;loginSuccess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;setLoginSuccess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;boolean&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;A function labeled,&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LoginComponent&lt;/code&gt; is created with one argument of type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LoginProps&lt;/code&gt;. We defined the ‘type’ above, via the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;type LoginProps&lt;/code&gt; line.
    &lt;ul&gt;
      &lt;li&gt;Hence, this one argument will require a type which contains two components, ‘authService’ of type ‘AuthService’, and ‘setUserNameCb’ which is a callback function that takes a string without a return.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;We then initialize four State Hooks, each empty (and boolean as false) accessible via &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;userName&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;password&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;errorMessage&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;loginSuccess&lt;/code&gt;.
    &lt;ul&gt;
      &lt;li&gt;We can now set and use these variables by calling their ‘setIndex’ for setting the state, and referencing each variable where they each apply.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-typescript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;handleSubmit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;SyntheticEvent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;preventDefault&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;userName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;password&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;loginResponse&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;authService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;login&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;userName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;password&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;userName2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;authService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getUserName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;userName2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;setUserNameCb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;userName2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;loginResponse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;setLoginSuccess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;setErrorMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;invalid credentials&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;setErrorMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;UserName and password required!&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;handleSubmit&lt;/code&gt; will take in one ‘event’ argument, a SyntheticEvent type which will be explained further below. This will grab the end-user action and perform the following:
    &lt;ul&gt;
      &lt;li&gt;If the user provided a username and password within the login form, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;loginResponse&lt;/code&gt; variable will perform a call to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;authService.login&lt;/code&gt; method, which was supplied by the ‘LoginProps’ type argument.&lt;/li&gt;
      &lt;li&gt;The method is supplied with the username and password, now being handed off to the Authentication Service component, will use Cognito to authenticate the user, then store the JWT tokens and make available the AWS Credentials.&lt;/li&gt;
      &lt;li&gt;The ‘username2’ variable will contain the username if the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;authService.getUserName()&lt;/code&gt; succeeds. If set, set as the argument to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setUserNameCb&lt;/code&gt; callback supplied to the ‘LoginProps’ type argument.&lt;/li&gt;
      &lt;li&gt;If &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LoginResponse&lt;/code&gt; was populated from the Auth Service login function, the State Hook  for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;loginSuccess&lt;/code&gt; variable gets called, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setLoginSuccess&lt;/code&gt;, setting it to ‘true’.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-typescript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;role&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;loginSuccess&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Navigate&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/profile&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;sr&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;}
&lt;/span&gt;      &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;h2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Please&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;login&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/h2&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;
&lt;/span&gt;      &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;form&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;onSubmit&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;handleSubmit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)}&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;label&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/label&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;
&lt;/span&gt;        &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;input&lt;/span&gt;
          &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;userName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
          &lt;span class=&quot;nx&quot;&gt;onChange&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;setUserName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)}&lt;/span&gt;
        &lt;span class=&quot;sr&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;
&lt;/span&gt;        &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;br&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;label&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Password&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/label&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;
&lt;/span&gt;        &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;input&lt;/span&gt;
          &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;password&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
          &lt;span class=&quot;nx&quot;&gt;onChange&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;setPassword&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)}&lt;/span&gt;
          &lt;span class=&quot;kd&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;password&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;br&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;submit&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Login&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/form&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;
&lt;/span&gt;      &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;br&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;renderLoginResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()}&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/div&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;
&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;The Login Component returns the React frontend component for logging in, the form for supplying the username and password, and a Submit button to set the variables for username and password via the Set Hooks, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setUsername&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setPassword&lt;/code&gt;.
    &lt;ul&gt;
      &lt;li&gt;Notice the event being supplied to the ‘handleSubmit’ function ‘event’ parameter as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;e&lt;/code&gt;, which carries over each of their respective &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;value&lt;/code&gt; vars supplied by the form to an anonymous function, which is supplied as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;e.target.value&lt;/code&gt; to each of the State Hooks’ ‘setIndexes’, such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setUserName(e.target.value)&lt;/code&gt;.&lt;/li&gt;
      &lt;li&gt;CLicking ‘Submit’ triggers the ‘setIndex’ calls to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;handleSubmit&lt;/code&gt; function.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;application-router&quot;&gt;Application Router&lt;/h4&gt;
&lt;p&gt;&lt;a href=&quot;https://gist.github.com/Adam-Lechnos/5e2049715eb7ffac7162af4303017e65&quot; target=&quot;_blank&quot;&gt;Full Code -&amp;gt; GitHub Gist&lt;/a&gt;
&lt;!-- &lt;script src=&quot;https://gist.github.com/5e2049715eb7ffac7162af4303017e65.js&quot;&gt; &lt;/script&gt; --&gt;&lt;/p&gt;

&lt;p&gt;Finally, the Application Router presents the code required for rendering a component based on the URL path.&lt;/p&gt;

&lt;div class=&quot;language-typescript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;authService&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;AuthService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;dataService&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;DataService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;authService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;userName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;setUserName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;undefined&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;undefined&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

  &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;router&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;createBrowserRouter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;NavBar&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;userName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;userName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;
&lt;/span&gt;          &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Outlet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;
&lt;/span&gt;      &lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;children&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Hello&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;world&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&amp;lt;&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/div&amp;gt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;,
&lt;/span&gt;        &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/login&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;LoginComponent&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;authService&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;authService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;setUserNameCb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;setUserName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;,
&lt;/span&gt;        &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/profile&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Profile&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/div&amp;gt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;,
&lt;/span&gt;        &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/createSpace&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;CreateSpace&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;dataService&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;dataService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;,
&lt;/span&gt;        &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/spaces&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Spaces&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;dataService&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;dataService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;,
&lt;/span&gt;        &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Here, we have a router which will perform a component depending on where the user is redirected. Their would be a navbar at the entry point, which then routes to each of the provided &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;path&lt;/code&gt; values. Based on the ‘path’, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;element&lt;/code&gt; is dynamically rendered.&lt;/li&gt;
  &lt;li&gt;For &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;path: &quot;/login&quot;&lt;/code&gt;, the LoginComponent service is called as follows: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LoginComponent authService={authService} setUserNameCb={setUserName}&lt;/code&gt;
    &lt;ul&gt;
      &lt;li&gt;Notice the argument adheres to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LoginProps&lt;/code&gt; type declared in the LoginComponents above, with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;authService&lt;/code&gt; being the imported &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AuthService()&lt;/code&gt; function assigned to the variable at the top of the code, along with,&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setUserNameCb&lt;/code&gt;, which is a callback function, called back by the LoginComponent when its username form field is set. The callback triggers the ‘setIndex’ for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;userName&lt;/code&gt; State Hook: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;const [userName, setUserName] = useState&amp;lt;string | undefined&amp;gt;(undefined)&lt;/code&gt;.&lt;/li&gt;
      &lt;li&gt;Recall the LoginComponent’s function decleration, which declared the paramters as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;function LoginComponent({ authService, setUserNameCb }: LoginProps)&lt;/code&gt;.
        &lt;ul&gt;
          &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setUserNameCb&lt;/code&gt; in LoginComponent is the triggers the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setUserName&lt;/code&gt; ‘setIndex’ in App.tsx, as it’s called back.&lt;/li&gt;
          &lt;li&gt;LoginProps type declared ‘setUserNameCb’ as an anonymous function, returning void as: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setUserNameCb: (userName: string) =&amp;gt; void&lt;/code&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;sub&gt;&lt;em&gt;&lt;a href=&quot;https://www.udemy.com/course/aws-typescript-cdk-serverless-react/?couponCode=ST15MT31224#instructor-1&quot;&gt;Original code snippets by Alex Dan via Udemy&lt;/a&gt;&lt;/em&gt;&lt;sub&gt;&lt;/sub&gt;&lt;/sub&gt;&lt;/p&gt;
</description>
        <pubDate>Wed, 22 Feb 2023 12:00:00 +0000</pubDate>
        <link>https://adamlechnos.com/aws/devops/cdk/typescript/2023/02/22/aws-cdk-cognito-use.html</link>
        <guid isPermaLink="true">https://adamlechnos.com/aws/devops/cdk/typescript/2023/02/22/aws-cdk-cognito-use.html</guid>
        
        
        <category>aws</category>
        
        <category>devops</category>
        
        <category>cdk</category>
        
        <category>typescript</category>
        
      </item>
    
      <item>
        <title>AWS CDK - Testing Amazon Cognito Authentication and Authorization</title>
        <description>&lt;h3 id=&quot;diagram&quot;&gt;Diagram&lt;/h3&gt;

&lt;h4 id=&quot;amazon-cognito-client-workflow-drawio-viewer&quot;&gt;&lt;a href=&quot;https://viewer.diagrams.net/?tags=%7B%7D&amp;amp;highlight=0000ff&amp;amp;edit=_blank&amp;amp;layers=1&amp;amp;nav=1&amp;amp;title=Devops-IaC-AWS_CDK_Cognito.drawio#Uhttps%3A%2F%2Fraw.githubusercontent.com%2FAdam-Lechnos%2Fdiagrams-charts%2Fmain%2Fdevops%2FDevops-IaC-AWS_CDK_Cognito.drawio&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Amazon Cognito Client Workflow (draw.io viewer)&lt;/a&gt;&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;https://github-content-cache.adamlechnos.com/Adam-Lechnos/diagrams-charts/blob/main/devops/Devops-IaC-AWS_CDK_Cognito.drawio.svg?raw=true&quot; alt=&quot;Amazon Cognito Client Workflow&quot; /&gt;&lt;/p&gt;

&lt;p&gt;In my previous blog post, &lt;a href=&quot;/aws/devops/cdk/typescript/2023/02/20/aws-cdk-cognito.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;“AWS CDK - Understanding Amazon Cognito Authentication and Authorization”&lt;/a&gt;, I go-over creating an Auth Stack, whereby a web service may provide protected access to APIs and AWS resources, depending on client authentication and access scopes. This article will delve into testing the Auth Stack, using TypeScript calls to the built-in CDK modules and constructs.&lt;/p&gt;

&lt;h3 id=&quot;creating-an-authservice-test&quot;&gt;Creating an AuthService Test&lt;/h3&gt;

&lt;h4 id=&quot;authservicets-exported-functions&quot;&gt;AuthService.ts exported functions&lt;/h4&gt;

&lt;!-- Refer to the full example [GitHub Gist](https://gist.github.com/Adam-Lechnos/ffdf98d046af91d1c6fe2138ce94017b) --&gt;
&lt;script src=&quot;https://gist.github.com/ffdf98d046af91d1c6fe2138ce94017b.js&quot;&gt; &lt;/script&gt;

&lt;div class=&quot;language-typescript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;Amplify&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;configure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;Auth&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;Cognito&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;userPoolId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;us-east-1_8j6R6jKCY&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;userPoolClientId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;66h766je9tqbba2fbip9j60hqb&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;identityPoolId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;us-east-1:3ae853a4-e0a7-4b8f-a6d2-263b1e2da9f2&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
  &lt;li&gt;Using AWS Amplify module, configure Cognito User Pool, User Pool Client, and User Pool ID.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-typescript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;AuthService&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;login&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;username&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;password&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;signIn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;username&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;password&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;authFlowType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;USER_PASSWORD_AUTH&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}}))&lt;/span&gt; 
          &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;SignInOutput&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
  &lt;li&gt;Create the login method against the exported &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AuthService&lt;/code&gt;, taking in two argument, Cognito Username and Password. The return result will be the username and password applied to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;signIn&lt;/code&gt; of the Amplify module, with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{authFlowType: &apos;USER_PASSWORD_AUTH&apos;}&lt;/code&gt; set as the sign-in options.&lt;/li&gt;
&lt;/ul&gt;

&lt;h5 id=&quot;analyzing-the-signin-typescript-type-is-as-follows&quot;&gt;Analyzing the ‘signIn’ TypeScript type is as follows:&lt;/h5&gt;

&lt;div class=&quot;language-typescript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;declare&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;signIn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;SignInInput&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Promise&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;SignInOutput&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;SignInInput&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;AuthSignInInput&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;SignInOptions&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;AuthSignInInput&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ServiceOptions&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;AuthServiceOptions&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;AuthServiceOptions&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;username&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nl&quot;&gt;password&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?:&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nl&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ServiceOptions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;SignInOptions&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;AuthServiceOptions&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;authFlowType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;AuthFlowType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nl&quot;&gt;clientMetadata&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ClientMetadata&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;AuthFlowType&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;USER_SRP_AUTH&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;CUSTOM_WITH_SRP&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;CUSTOM_WITHOUT_SRP&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;USER_PASSWORD_AUTH&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
  &lt;li&gt;The method takes a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AuthSignInInput&lt;/code&gt; type, with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;options?&lt;/code&gt; value taking a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ServiceOption&lt;/code&gt; type. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ServiceOption&lt;/code&gt; type extends &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AuthServiceOptions&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AuthServiceOptions&lt;/code&gt; Type presents the following valid options for ‘signIn’ when used with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;signInOptions&lt;/code&gt; type: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&apos;USER_SRP_AUTH&apos; | &apos;CUSTOM_WITH_SRP&apos; | &apos;CUSTOM_WITHOUT_SRP&apos; | &apos;USER_PASSWORD_AUTH&apos;&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;For this test, we are using a ‘USER_PASSWORD_AUTH’.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;authtestts-call-to-the-exported-authservicets-functions&quot;&gt;auth.test.ts call to the exported AuthService.ts functions.&lt;/h4&gt;

&lt;!-- Refer to the full example [GitHub Gist](https://gist.github.com/Adam-Lechnos/9a5154ca155b473af230adfd114fe41e) --&gt;
&lt;script src=&quot;https://gist.github.com/9a5154ca155b473af230adfd114fe41e.js&quot;&gt; &lt;/script&gt;

&lt;div class=&quot;language-typescript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;testAuth&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;service&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;AuthService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;login&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;user-bob&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;bobs-password&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;idToken&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;fetchAuthSession&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;tokens&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;accessToken&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;fetchAuthSession&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;tokens&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;creds&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;fetchAuthSession&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;credentials&lt;/span&gt;

    &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;idToken&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;--------SEPARATOR--------&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;accessToken&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;listBuckets&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;creds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
  &lt;li&gt;The previously created &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AuthService()&lt;/code&gt; object is instantiated and assigned to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;service&lt;/code&gt; variable. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;login&lt;/code&gt; function assigned to ‘AuthService’ is supplied with the Cognito Username and Password arguments, prepended with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;await&lt;/code&gt;, since ‘login’ returns a &lt;a href=&quot;https://www.codecademy.com/resources/docs/typescript/promises&quot;&gt;Promise&lt;/a&gt; via &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SignInOutPut&lt;/code&gt;.
    &lt;ul&gt;
      &lt;li&gt;Recall this from the ‘signIn’ function, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;export declare function signIn(input: SignInInput): Promise&amp;lt;SignInOutput&amp;gt;&lt;/code&gt;. When we created the ‘AuthService’ class, we assigned it to ‘async’, meaning, we are leveraging the use of Async/Await in TypeScript for the Promise returned.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;We then parse out the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;idToken&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;accessToken&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;creds&lt;/code&gt;, printing all three to the console. These values are taken from the returned &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fetchAuthSession&lt;/code&gt; Promise, which is also apart of the Amplify module.&lt;/li&gt;
&lt;/ul&gt;

&lt;h5 id=&quot;analyzing-fetchauthsession-a-bit-further&quot;&gt;Analyzing ‘fetchAuthSession’ a bit further&lt;/h5&gt;

&lt;div class=&quot;language-typescript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;declare&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;fetchAuthSession&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;FetchAuthSessionOptions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Promise&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;AuthSession&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;AuthSession&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;tokens&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;AuthTokens&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nl&quot;&gt;credentials&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;AWSCredentials&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nl&quot;&gt;identityId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?:&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nl&quot;&gt;userSub&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?:&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;AuthTokens&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;idToken&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;JWT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nl&quot;&gt;accessToken&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;JWT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;AWSCredentials&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;accessKeyId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nl&quot;&gt;secretAccessKey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nl&quot;&gt;sessionToken&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?:&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nl&quot;&gt;expiration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;JWT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;JwtPayload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nl&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;kr&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;JwtPayloadStandardFields&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nl&quot;&gt;exp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?:&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nl&quot;&gt;iss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?:&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nl&quot;&gt;aud&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?:&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[];&lt;/span&gt;
    &lt;span class=&quot;nl&quot;&gt;nbf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?:&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nl&quot;&gt;iat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?:&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nl&quot;&gt;scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?:&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nl&quot;&gt;jti&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?:&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nl&quot;&gt;sub&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?:&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
  &lt;li&gt;We can see, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AuthSession&lt;/code&gt; is a Promise, hence, also called with Async/Await. The returned type supplies us with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tokens?&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;credentials?&lt;/code&gt;, etc., each with their own declared type. Hence, we are able to return &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tokens&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;credentials&lt;/code&gt; from ‘fecthAuthSession’.&lt;/li&gt;
  &lt;li&gt;Diving a bit deeper, the return types of ‘tokens’ is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AuthTokens&lt;/code&gt;, which contain both &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;idToken&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;accessToken&lt;/code&gt;, each of which are returned as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;JWT&lt;/code&gt; types, since both types are formatted as JWT (JSON Web Tokens).&lt;/li&gt;
  &lt;li&gt;‘credentials’ returns &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AWSCredentials&lt;/code&gt; type, which contains &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;accessKeyId&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;secretAccessKey&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sessionToken&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;expiration&lt;/code&gt; strings.&lt;/li&gt;
  &lt;li&gt;Also, the JWT type is provided for analysis here as well, which returns the ‘payload’ as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;JwtPayload&lt;/code&gt;, also shown. ‘JwtPayload may be returns as a string using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;toString()&lt;/code&gt;’.&lt;/li&gt;
  &lt;li&gt;Going yet a bit deeper, ‘JwtPayload’ returns &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;JwtPayloadStandardFields&lt;/code&gt; fields, adhering to the JWT standard.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;bringing-it-all-together&quot;&gt;Bringing It All Together&lt;/h4&gt;
&lt;p&gt;Executing the test via the CDK CLI should print to console the ID Token, Access Token, and AWS Credentials.
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ts-node auth.test.ts &lt;/code&gt;&lt;/p&gt;

&lt;h5 id=&quot;example-output&quot;&gt;Example Output&lt;/h5&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;--------ID Token--------
{
  toString: [Function: toString],
  payload: {
    sub: &apos;d488e438-b0d1-7011-bc2c-604a199fcdd5&apos;,
    &apos;cognito:groups&apos;: [ &apos;admins&apos; ],
    email_verified: true,
    iss: &apos;https://cognito-idp.us-east-1.amazonaws.com/us-east-1_8j6R6jKCY&apos;,
    &apos;cognito:username&apos;: &apos;user&apos;,
    origin_jti: &apos;79d0f26f-bd39-4dfd6-9f97-0b68c10d5b73&apos;,
    &apos;cognito:roles&apos;: [
      &apos;arn:aws:iam::820127509812:role/AuthStack-CognitoAdminRole4C10FBA4-EiDTHoEf1anR&apos;
    ],
    aud: &apos;66h766je9tqbba2fbip9j60hqb&apos;,
    event_id: &apos;8626e824-ddbb-410a-af39-56ec4c820657&apos;,
    token_use: &apos;id&apos;,
    auth_time: 1708633895,
    exp: 1708637495,
    iat: 1708633895,
    jti: &apos;c9ddfe55-ec2b-4e27-a291-564e52de9aef&apos;,
    email: &apos;user@user.com&apos;
  }
}
--------Access Token--------
{
  toString: [Function: toString],
  payload: {
    sub: &apos;d488e438-b0d1-7011-bc2c-604a199fcdd5&apos;,
    &apos;cognito:groups&apos;: [ &apos;admins&apos; ],
    iss: &apos;https://cognito-idp.us-east-1.amazonaws.com/us-east-1_8j6R6jKCY&apos;,
    client_id: &apos;66h766je9tqbba2fbipdfdfddf0hqb&apos;,
    origin_jti: &apos;79d0f26f-bd39-4dfd6-9f97-0b68c10d5b73&apos;,
    event_id: &apos;8626e824-ddbb-410a-af39-56ec4c820657&apos;,
    token_use: &apos;access&apos;,
    scope: &apos;aws.cognito.signin.user.admin&apos;,
    auth_time: 1708633895,
    exp: 1708637495,
    iat: 1708633895,
    jti: &apos;c4a365e7-21d9-463d-bfcc-3534866be4c2&apos;,
    username: &apos;user&apos;
  }
}
--------AWS Credentials--------
{
  accessKeyId: &apos;ASDFRWSDVFU2AZSFREWDS&apos;,
  secretAccessKey: &apos;examplesecretaccesskey&apos;,
  sessionToken: &apos;examplesessiontoken-examplesessiontoken&apos;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
  &lt;li&gt;Notice the ID Token, which indicates the assumed roles for the session as
    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &apos;cognito:roles&apos;: [
  &apos;arn:aws:iam::820127509812:role/AuthStack-CognitoAdminRole4C10FBA4-EiDTHoEf1anR&apos;
],
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;This is the default mapped Authenticated Role. If you were a member of multiple Cogito User Pool Group, each of the group IAM roles would be listed here in addition to the group names, also indicated within the ID Token as:
    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; &apos;cognito:groups&apos;: [ &apos;admins&apos; ],
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;testing-the-oauth-token-endpoint-for-custom-scopes&quot;&gt;Testing The OAuth Token Endpoint for Custom Scopes&lt;/h4&gt;
&lt;p&gt;When using resource servers for creating auth flows with different scopes, the API Gateway can use these scopes within the Access Token to determine the access granted to the authenticated user.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Custom scopes added via Resource Servers are then defined within each respective Cognito User Pool Client, each mapping to a Resource Server based on its assigned Custom Scopes.&lt;/li&gt;
  &lt;li&gt;Each client provides a separate hosted UI, presented to the end-user for authenticating to the application. Depending on how the auth flow is configured, either an Access and ID token are returned or an Authorization Code which is then exchanged for Access and ID tokens.
    &lt;ul&gt;
      &lt;li&gt;The former is an Implicit grant, which exposes the tokens within the URL, while the latter uses Authorization code grant flow, which is more secure.&lt;/li&gt;
      &lt;li&gt;Authorization code flow requires a back-channel or server side which will not work with a single page app such as those written in React.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h5 id=&quot;breaking-it-down&quot;&gt;Breaking It Down&lt;/h5&gt;
&lt;ul&gt;
  &lt;li&gt;Within the AWS Console, click on the appropriate Hosted UI, by first going to the Cognito User Pool, App Integration Tab, then click on the App Client to test under ‘App Client and Analytics’.&lt;/li&gt;
  &lt;li&gt;This is where the Auth flows, scopes, callback URLs, and timeout options are assigned.&lt;/li&gt;
  &lt;li&gt;Click View Hosted UI, and authenticate. If only a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;code=&lt;/code&gt; response is generated within the URL, then an Authorization code grant is being used. Test the returned Authorization Code as follows:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href=&quot;https://github-content-cache.adamlechnos.com/Adam-Lechnos/screenshots/blob/main/devops/Devops-AWS-CDK-Cognito-Test-Screenshot-2023-02-22-175035.png?raw=true&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Example Screenshot&lt;/a&gt;
&lt;img src=&quot;https://github-content-cache.adamlechnos.com/Adam-Lechnos/screenshots/blob/main/devops/Devops-AWS-CDK-Cognito-Test-Screenshot-2023-02-22-175035.png?raw=true&quot; alt=&quot;Example Screenshot&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The following is an example CURL request/response to/from the token endpoint&lt;/p&gt;

&lt;p&gt;Request&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl --location --request POST &apos;https://example-est.auth.us-east-1.amazoncognito.com/oauth2/token&apos; \
--header &apos;Content-Type: application/x-www-form-urlencoded&apos; \
--data-urlencode &apos;client_id=5j9701eo7qmhf91oth5eks6kii&apos; \
--data-urlencode &apos;code=79927d32-ba18-4cff-8254-b7d43d1347a2&apos; \
--data-urlencode &apos;grant_type=authorization_code&apos; \
--data-urlencode &apos;redirect_uri=https://example.com&apos;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Response&lt;/p&gt;
&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;id_token&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;eyJraWQiOiI3SFRmUHF3OTdVRHQwdTQ0cFoyVVZQMFVCVUV5d0toWlNmYVNsc0pTdWl3PSIsImFsZyI6IlJTMjU2In0.eyJhdF9oYXNoIjoibzBNVDBnWVEwbVdua3EwdnA2dHk4ZyIsInN1YiI6ImQ0ODhlNDM4LWIwZDEtNzAxMS1iYzJjLTYwNGExOTlmY2RkNSIsImNvZ25pdG86Z3JvdXBzIjpbImFkbWlucyJdLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiaXNzIjoiaHR0cHM6XC9cL2NvZ25pdG8taWRwLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tXC91cy1lYXN0LTFfOGo2UjZqS0NZIiwiY29nbml0bzp1c2VybmFtZSI6ImFsZWNobm9zIiwib3JpZ2luX2p0aSI6IjYyMGEwMTY2LTRhNGItNDA0Ny1iNGQzLWFmN2U5MWE1NTQ0NyIsImNvZ25pdG86cm9sZXMiOlsiYXJuOmF3czppYW06OjgyMDEyNzUwOTgxMjpyb2xlXC9BdXRoU3RhY2stQ29nbml0b0FkbWluUm9sZTRDMTBGQkE0LUVpRFRIb0VmMWFuUiJdLCJhdWQiOiI1ajk3MDFlbzdxbWhmOTFvdGg1ZWtzNmtpaSIsInRva2VuX3VzZSI6ImlkIiwiYXV0aF90aW1lIjoxNzA4NjMxOTg0LCJleHAiOjE3MDg2MzU1ODQsImlhdCI6MTcwODYzMTk4NSwianRpIjoiYzJmMzMwZWQtYmE0Zi00YzNmLWJhY2ItMDQyNDA3ZGE2NTZmIiwiZW1haWwiOiJhZGFtLmxlY2hub3NAZ21haWwuY29tIn0.veWBGSGEUL8Gz9zHLHa0oWm6L_w3Y76-GtXG_oYnDrmgVAHU7e2RYCE7YEYRN2Mh1sZVLEXZdbQIgO-BNjQqbfLQwIeyDz4o0hAakUMYwuBvk1f9WfntTuszCS8jCZvK2ERZ8r9utcpKndjqVWt2RzGmYaSgJXa5xdCZXfSS77y3KhRvLKY-4AI-pnuthheRHFUzxZHkDhM0YXjL3lKSpjI3697bDBa5K-qRMTVNO37uVAno_AUJ1bb0C7iqwWAC0DN9D6QyGetY0coh4ex9IxmoHiti7D9pZKAyriufa5P6VAk-QNJpPWJ1b0rkT4dIZ_4vG2Ydh63hvUPN99NO_g&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;access_token&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;eyJraWQiOiIyRDRPSlk2ZTY4OGt0aU94eXBSNWRvWEtEc3lHYmFCR01WWmJmYm1oN0dvPSIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiJkNDg4ZTQzOC1iMGQxLTcwMTEtYmMyYy02MDRhMTk5ZmNkZDUiLCJjb2duaXRvOmdyb3VwcyI6WyJhZG1pbnMiXSwiaXNzIjoiaHR0cHM6XC9cL2NvZ25pdG8taWRwLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tXC91cy1lYXN0LTFfOGo2UjZqS0NZIiwidmVyc2lvbiI6MiwiY2xpZW50X2lkIjoiNWo5NzAxZW83cW1oZjkxb3RoNWVrczZraWkiLCJvcmlnaW5fanRpIjoiNjIwYTAxNjYtNGE0Yi00MDQ3LWI0ZDMtYWY3ZTkxYTU1NDQ3IiwidG9rZW5fdXNlIjoiYWNjZXNzIiwic2NvcGUiOiJhd3MuY29nbml0by5zaWduaW4udXNlci5hZG1pbiBvcGVuaWQgdXNlcnNcL3JlYWQiLCJhdXRoX3RpbWUiOjE3MDg2MzE5ODQsImV4cCI6MTcwODYzNTU4NCwiaWF0IjoxNzA4NjMxOTg1LCJqdGkiOiI1YjI1YTRhYS0zZGZjLTRiZWUtOGIyMS0zMjA4NTRlY2QyOGUiLCJ1c2VybmFtZSI6ImFsZWNobm9zIn0.EWCEwDk46i8fOU4IVnlwgM7XNz_i-jtYcpyOYE8q4YGFC7giK5lWgzgIcD9_zHzUF6bVc6iv1uqtQDEXZlOU7pofMhUWBykqnDUC0Q57X4bP3giDigIYmfj77zJLxlWhwRvim28hZfJg9Sz_RIBcf13lo4D8bZvTE5HVEEI-tztuA4B-1dDY65po2zMHqwBEWF9FYaQC2edm5lyQEtTFleHVawBVbQWIU3Ud16TznAy9WEp2q_QgsNSFKuF-2LnQuO27MfyFWFGza8gDMrBwxVJ1l9bjrJuLH300QqQWLdaX7FTupOZHtvUxeND3K4Hc0-ZTu-nvpGUYOAxemfyyIQ&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;refresh_token&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;eyJjdHkiOiJKV1QiLCJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiUlNBLU9BRVAifQ.RMAy1jPNXxpGdPIr1TUukG685KbV5JgokWkBtnWDFOOlcFSRGWS-uNkglPdJJv4g1r4nk7jxYY8J8HnYmomzlt7OD0FdSnvrCEr61SbDZz5FZ9jhzdl-p2_fEoi_fUydpwG_JUliFucvutwDcBd1W2Ul900b24m1nHSrq_NL8r9uFJcVrkFDWLKQ9fxipSYZyU37LePN-qrxX78pQS2vIIe8tVvrG6CuK4GjdRDUvz10tpDFHdTFH75Bn0GHr5xoXXCuTg7CkuyipVYapYeI_AwJIEYBfLzlUjl99hrfkxDUVqlpyqgj9Jq_NOsXwt-sd73ZbPoBGAurAIw2Yw6mxg.WUaX_U7nlacSnml-.CctUJfNf4hngQr4QktmuTWTT5myYN03GzwVWgktiQpGHccW5jgK9QSQmKIG5v33qHoG5KOpm7xyKU9YsehJjpZHj8yq_NMMEamk7DCv4UR7ooXBJS2Hf6KL7Y-2sFxD6Eec7P37t1HtP5QOB1P5CNZgxW069hQpKj6uyOmOqvrso88Jtk18HjRw0SZY1r2jzdey-PRsoinukv2_JWaH2A35QFuApVwurov3DWl7kNKXkQldOROkYC1xrOidXxVTfirschCxSTcNWf481Jh9BF-W_eYcnyAJU0RAFQjZdLEdEUBTl2uH3jTVfGl9qdq32oXmd_EoeugBCW2zUbgekJbRlfmMWt42bZ67qz6ZAZ-cgijp16g1f01pXKV-vKdXIvjOm6IZin9whMwoK4i6zFjfAZLlYPRP2N-lZCRW8d7YeOz7S00OISy5qHF6DpDhm6sWFe0VBmyaYjZKzZob99DXyXBVLJukn1_R2MD5nJNRzCUvJCni3RZ4vEOW8lUK2RwcGjPiLgMH9EalVcALsIq0zV_SsSHUzgXeuvFz6sP-ygIkogrfLKGnGg5ssMpsL6rAlmSskz39veMmWDRxzx20daQXr_vpRHVmk5_Lg6alX7l3uMNGUOpvLEJssRsDWf99kuyXYWA0aqNr80RiJS67TXX0DrmhKtipvnd_cb3G5xcvVsu5xc37g9UnA57Bzvi1ulB9XlcgfrpKZxgPUTV0OtWvVvUDIoi06aOCOMeQgcMBRKoS6T8Qrplg8OzCGmg5cNPgap8foPfD9qgY5DWDlMgtmtohmH_Sg8dFTAdE0fmWhFXmWw5ErVlg4Ea0FtOl5ix8DqOQx0hT_ClhGW-aiXUHoVy7uZHK2Fa385aBoxrk-DtxO5r0ROUjnVwGTVUdUPBFWAb905nTs1K5cvWgkwdRp-wq4NFhwcDy8T1h5Dss3kouIx53JiZv5E4gsroynF7fOL_4vxlt0dM-ykWBB1sN988cTvqUNunWM3vofNWnaEg-_YP7xbOFas78HKqqm4-2UNlM0bYY8E8D6TDf9KtPbZb0Pt2HuJYv6z9JiAmS24Og7Bce1DiEOlGafLrSMgkHp84TumRXWOLurJtVIW2MajM06k3xvAQYdP4rcb4zgss_Pegtq-6AWgNpJ7TvT14NLjm2GXahu2x6gr4EG8Tr3LRDJwOAkxxNwogv2RfBqI8YrjQzDZ_-jzwhhdOvvik3FswYoeLv-UGy333K4gYYEu9SuPsvV5ag.Uy9EJjNpUCosi7jYTiIdew&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;expires_in&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;token_type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Bearer&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;JWT.io deencoded Access Token&lt;/p&gt;
&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;sub&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;d488e438-b0d1-7011-bc2c-604a199fcdd5&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;cognito:groups&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;admins&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;iss&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;https://cognito-idp.us-east-1.amazonaws.com/us-east-1_8j6R6jKCY&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;version&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;client_id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;5j9701eo7qmhf91oth5eks6kii&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;origin_jti&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;620a0166-4a4b-4047-b4d3-af7e91a55447&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;token_use&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;access&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;scope&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;aws.cognito.signin.user.admin openid users/read&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;auth_time&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1708631984&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;exp&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1708635584&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;iat&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1708631985&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;jti&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;5b25a4aa-3dfc-4bee-8b21-320854ecd28e&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;username&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;username&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;The de-encoded Base64 Access Token indicates the scope values which were also attached to the resource server, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;scope&quot;: &quot;aws.cognito.signin.user.admin openid users/read&quot;&lt;/code&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;For Implicit grants, the ID and Access Tokens are returned directly within the URL.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;sub&gt;&lt;em&gt;&lt;a href=&quot;https://www.udemy.com/course/aws-typescript-cdk-serverless-react/?couponCode=ST15MT31224#instructor-1&quot;&gt;Original code snippets by Alex Dan via Udemy&lt;/a&gt;&lt;/em&gt;&lt;sub&gt;&lt;/sub&gt;&lt;/sub&gt;&lt;/p&gt;
</description>
        <pubDate>Tue, 21 Feb 2023 12:00:00 +0000</pubDate>
        <link>https://adamlechnos.com/aws/devops/cdk/typescript/2023/02/21/aws-cdk-cognito-testing.html</link>
        <guid isPermaLink="true">https://adamlechnos.com/aws/devops/cdk/typescript/2023/02/21/aws-cdk-cognito-testing.html</guid>
        
        
        <category>aws</category>
        
        <category>devops</category>
        
        <category>cdk</category>
        
        <category>typescript</category>
        
      </item>
    
      <item>
        <title>AWS CDK - Understanding Amazon Cognito Authentication and Authorization</title>
        <description>&lt;h3 id=&quot;diagram&quot;&gt;Diagram&lt;/h3&gt;

&lt;h4 id=&quot;amazon-cognito-client-workflow-drawio-viewer&quot;&gt;&lt;a href=&quot;https://viewer.diagrams.net/?tags=%7B%7D&amp;amp;highlight=0000ff&amp;amp;edit=_blank&amp;amp;layers=1&amp;amp;nav=1&amp;amp;title=Devops-IaC-AWS_CDK_Cognito.drawio#Uhttps%3A%2F%2Fraw.githubusercontent.com%2FAdam-Lechnos%2Fdiagrams-charts%2Fmain%2Fdevops%2FDevops-IaC-AWS_CDK_Cognito.drawio&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Amazon Cognito Client Workflow (draw.io viewer)&lt;/a&gt;&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;https://github-content-cache.adamlechnos.com/Adam-Lechnos/diagrams-charts/blob/main/devops/Devops-IaC-AWS_CDK_Cognito.drawio.svg?raw=true&quot; alt=&quot;Amazon Cognito Client Workflow&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;the-moving-pieces&quot;&gt;The Moving Pieces&lt;/h3&gt;
&lt;p&gt;Components of Amazon Cognito which are part of the authentication and authorization flow:&lt;/p&gt;

&lt;h4 id=&quot;cognito-user-pools---authentication-authorization-and-resource-servers&quot;&gt;Cognito User Pools - Authentication, Authorization, and Resource Servers&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;Refer to my blog post, &lt;a href=&quot;/aws/devops/cdk/typescript/2023/03/05/aws-cdk-cognito-workflow.html&quot;&gt;AWS CDK - Breaking Down AWS Cognito OAuth &amp;amp; OIDC Workflow&lt;/a&gt; for more details about what Authentication, Authorization, and Resource Servers are.&lt;/li&gt;
  &lt;li&gt;Contains a directory of users &amp;amp; groups or, may be delegated to a Federated Identity Provider for sign-in experience, such as Google, Facebook, Amazon, Apple, SAML, or OIDC (OpenID Connect).&lt;/li&gt;
  &lt;li&gt;Groups created within the User Pool are associated with IAM (&lt;a href=&quot;https://aws.amazon.com/iam/&quot;&gt;AWS Identity and Access Management&lt;/a&gt;) roles, assumed by the user for performing tasks within AWS, such as reading S3 Buckets.
    &lt;ul&gt;
      &lt;li&gt;Each group may have a separate IAM Role configured, for allowing delineated permissions amongst disparate &lt;a href=&quot;https://docs.aws.amazon.com/cognito/latest/developerguide/managing-users.html?icmpid=docs_cognito_console_help_panel&quot;&gt;managed group members&lt;/a&gt;.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;App integration settings, where app clients are defined and its token expiration, authentication flows, OAUTH 2.0 grant types, and OpenID Connect Scopes and Identity Providers are defined.
    &lt;ul&gt;
      &lt;li&gt;Authentication flow options: ALLOW_ADMIN_USER_PASSWORD_AUTH, ALLOW_USER_PASSWORD_AUTH, ALLOW_REFRESH_TOKEN_AUTH, ALLOW_USER_PASSWORD_AUTH, and ALLOW_USER_SRP_AUTH.&lt;/li&gt;
      &lt;li&gt;OAuth 2.0 grant type options:
        &lt;ul&gt;
          &lt;li&gt;Authorization code grant - provides an authorization code as the response to be exchanges on a back-channel or server side for a Access Token. The exchange would include a client ID and Client Secret.&lt;/li&gt;
          &lt;li&gt;Implicit grant - specifies that the client should get the access token (and optionally, ID token, based on scopes) directly. (exposes the OAuth (Access) token within the URL)&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;OpenID Connect Scopes - at least one scope is required to specify the attributes the app client can retrieve for access. Scopes include:
        &lt;ul&gt;
          &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;aws.cognito.sigin.user.admin&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;openid&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;email&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;phone&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;profile&lt;/code&gt; (the last three options also require OpenID to be selected)&lt;/li&gt;
          &lt;li&gt;These scopes authorize the access token for retrieval of user attributes from the &lt;a href=&quot;https://docs.aws.amazon.com/cognito/latest/developerguide/userinfo-endpoint.html&quot;&gt;userInfo endpoint&lt;/a&gt; for OpenID Connect.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;Identity providers - which are made available to the client. Some or all of your user pool external Identity Providers may be selected to authenticate your users.
        &lt;ul&gt;
          &lt;li&gt;Selecting at least &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Cognito user pool&lt;/code&gt; enables authentication via the Cognito User Pool, which enables access to its Federated Identity Providers, or, its own internal set of users.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;Adding at least a &lt;a href=&quot;https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-assign-domain.html?icmpid=docs_cognito_console_help_panel&quot;&gt;Configured User Pool Domain&lt;/a&gt; within the App Integration tab provides a Hosted UI for the user sign-in experience.&lt;/li&gt;
      &lt;li&gt;The client is where the Authentication flow session duration, refresh token expiration, access token expiration, ID token expiration, and other advanced authentication settings are specified.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;cognito-identity-pools---aws-resource-access-via-iam-assumed-roles&quot;&gt;Cognito Identity Pools - AWS Resource Access via IAM Assumed Roles&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;Grants users access to AWS resources, and are associated with Identity Pools as the Identity Provider. External Identity Providers may be selected here as well, bypassing the use of Amazon Cognito User Pools.&lt;/li&gt;
  &lt;li&gt;Default Authenticated and Unauthenticated (Guest Access) roles may be specified, whereby the ID pool is the trusted resource assuming the role on behalf of the user.&lt;/li&gt;
  &lt;li&gt;Custom roles may be added then mapped via the user pool and its assigned groups (Admin group members will be assigned the Admin IAM role for example).
    &lt;ul&gt;
      &lt;li&gt;This mapping would be used either in conjunction or in lieu of the IAM roles associated with groups created within the Cognito User Pools, depending on how the role mappings are configured.
        &lt;ul&gt;
          &lt;li&gt;Rule based role mappings will match claim values, whereas Token based role mappings will perform a lookup of the IAM Role associated with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cognito:role&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cognito:preferred_role&lt;/code&gt; claims injected into the ID Token from the Cognito Identity Pool.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;Using a Federated Identity Provider within the User Pool would require mapping the custom roles via the claim values to IAM Roles. Rule based role mappings are required. (more on this below)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;The ARN of the assigned user’s role get injected into the &lt;a href=&quot;https://auth0.com/docs/secure/tokens/id-tokens/id-token-structure&quot;&gt;ID Token&lt;/a&gt; as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;cognito:role&quot;: [&amp;lt;list of role ARNs&amp;gt;]&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;In addition, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;cognito:preferred_role&quot;:&quot;&amp;lt;role ARN&amp;gt;&quot;&lt;/code&gt; gets injected in the ID Token, based on the role with the best (lowest) precedence value. If there is only one role, this will be the value.
    &lt;ul&gt;
      &lt;li&gt;i.e., if authenticated, but no group is assigned within the user pool, use the default role associated with the Authenticated settings.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;aws-amplify---authentication-mechanism&quot;&gt;AWS Amplify - Authentication Mechanism&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;Configure Cognito as the authentication provider&lt;/li&gt;
  &lt;li&gt;Present authentication frontend&lt;/li&gt;
  &lt;li&gt;Fetch ID Token upon authentication and pass it around where required&lt;/li&gt;
  &lt;li&gt;May use its own Federated Provider such as Google, Apple, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;technical-terms&quot;&gt;Technical Terms&lt;/h3&gt;
&lt;p&gt;In Cognito, both &lt;em&gt;ID Tokens&lt;/em&gt; and &lt;em&gt;Access Tokens&lt;/em&gt; include a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cognito:groups&lt;/code&gt; claims that contains user group memberships in the Cognito User Pool. Cognito returns both ID Tokens and Access Tokens.&lt;/p&gt;

&lt;h4 id=&quot;identity-provider-idp&quot;&gt;Identity Provider (IdP)&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;Provides a database of user identities and their details, such as name, email, etc., and may be provided via a federated external provider, such as Google, Facebook, Amazon, Apple, or any OpenID Connect or SAML provider.&lt;/li&gt;
  &lt;li&gt;Refer to AWS’ developer guide for more info on &lt;a href=&quot;https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-identity-provider.html&quot;&gt;Cognito User Pool Identity Providers&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;json-web-token-jwt&quot;&gt;JSON Web Token (JWT)&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;A formatted JSON nested object structure, used by both OAuth and OpenID Connect (more on these terms below) for passing data between web components, ensuring data integrity of the contained payload.&lt;/li&gt;
  &lt;li&gt;JWT does not encrypt the data (and will generally depend on TLS for data confidentiality).&lt;/li&gt;
  &lt;li&gt;JWTs are Signed by the issuer’s private key and verified using the issuer’s corresponding public key, for the data integrity component.&lt;/li&gt;
  &lt;li&gt;Refer to the official &lt;a href=&quot;https://jwt.io&quot;&gt;JWT website&lt;/a&gt; for more details.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;id-tokens&quot;&gt;ID Tokens&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;According to &lt;a href=&quot;https://auth0.com/docs/secure/tokens/id-tokens/id-token-structure&quot;&gt;OpenID Connect (OIDC)&lt;/a&gt;, in JWT format, provides proof of the user’s successful authentication.&lt;/li&gt;
  &lt;li&gt;Payloads contain claims about the user properties for the target/receiving application.
    &lt;ul&gt;
      &lt;li&gt;Claims may be the following keys: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;aud&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;name&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;email&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;expiration&lt;/code&gt;, and &lt;a href=&quot;https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims&quot;&gt;others&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;For Amazon Cognito, claims will also contains:
        &lt;ul&gt;
          &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cogntio:groups&lt;/code&gt;, an array of the names of user pool groups that have your user as a member. Groups can generate a request for a preferred IAM role from and Identity pool.&lt;/li&gt;
          &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cognito:preferred_role&lt;/code&gt;, the ARN of IAM role associated with the user’s highest priority user pool group.&lt;/li&gt;
          &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cognito:username&lt;/code&gt;, the user name of the user within the user pool group&lt;/li&gt;
          &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cognito:roles&lt;/code&gt;, an array of the names of the IAM roles associated with the user’s groups. Each user pool group can have an IAM role associated with it.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;Also refer to AWS’ developer guide around &lt;a href=&quot;https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-the-id-token.html&quot;&gt;ID Tokens&lt;/a&gt; for more info.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Claims are used by the application to help with the user experience, in lieu of using cookies.&lt;/li&gt;
&lt;/ul&gt;

&lt;h5 id=&quot;example-id-token-payload&quot;&gt;Example ID Token Payload&lt;/h5&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt;header&amp;gt;.{
    &quot;sub&quot;: &quot;aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee&quot;,
    &quot;cognito:groups&quot;: [
        &quot;test-group-a&quot;,
        &quot;test-group-b&quot;,
        &quot;test-group-c&quot;
    ],
    &quot;email_verified&quot;: true,
    &quot;cognito:preferred_role&quot;: &quot;arn:aws:iam::111122223333:role/my-test-role&quot;,
    &quot;iss&quot;: &quot;https://cognito-idp.us-west-2.amazonaws.com/us-west-2_example&quot;,
    &quot;cognito:username&quot;: &quot;my-test-user&quot;,
    &quot;middle_name&quot;: &quot;Jane&quot;,
    &quot;nonce&quot;: &quot;abcdefg&quot;,
    &quot;origin_jti&quot;: &quot;aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee&quot;,
    &quot;cognito:roles&quot;: [
        &quot;arn:aws:iam::111122223333:role/my-test-role&quot;
    ],
    &quot;aud&quot;: &quot;xxxxxxxxxxxxexample&quot;,
    &quot;identities&quot;: [
        {
            &quot;userId&quot;: &quot;amzn1.account.EXAMPLE&quot;,
            &quot;providerName&quot;: &quot;LoginWithAmazon&quot;,
            &quot;providerType&quot;: &quot;LoginWithAmazon&quot;,
            &quot;issuer&quot;: null,
            &quot;primary&quot;: &quot;true&quot;,
            &quot;dateCreated&quot;: &quot;1642699117273&quot;
        }
    ],
    &quot;event_id&quot;: &quot;64f513be-32db-42b0-b78e-b02127b4f463&quot;,
    &quot;token_use&quot;: &quot;id&quot;,
    &quot;auth_time&quot;: 1676312777,
    &quot;exp&quot;: 1676316377,
    &quot;iat&quot;: 1676312777,
    &quot;jti&quot;: &quot;aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee&quot;,
    &quot;email&quot;: &quot;my-test-user@example.com&quot;
}
.&amp;lt;token signature&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;access-tokens&quot;&gt;Access Tokens&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;Contains claims about the authenticated user, a list of the user’s groups, and a list of scopes, via the &lt;a href=&quot;https://www.rfc-editor.org/rfc/rfc6749#section-3.3&quot;&gt;OAuth 2.0 Scope&lt;/a&gt; specification, in JWT format.&lt;/li&gt;
  &lt;li&gt;Access token provider authorization, granting a client application access specific resources and allow specific actions on behalf of the user, as granted by the access token.
    &lt;ul&gt;
      &lt;li&gt;For example, authorizing LinkedIn to access X’s (Twitter’s) APIs for cross posting.&lt;/li&gt;
      &lt;li&gt;Refer to AWS’s developer guide for more info regarding &lt;a href=&quot;https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-the-access-token.html&quot;&gt;Access Tokens&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Access Tokens will contain the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scope&lt;/code&gt; key, a list of OAuth 2.0 scopes that define what access the token provides. For Amazon Cognito API sign-in, only &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;aws.cognito.signin.user.admin&lt;/code&gt; is contained within the scope.&lt;/li&gt;
  &lt;li&gt;Amazon Cognito Access Tokens will also contain &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cognito:groups&lt;/code&gt;, an array of the names of user pool groups that have you as a member, similar to the OIDC Access Token mentioned above.&lt;/li&gt;
&lt;/ul&gt;

&lt;h5 id=&quot;example-access-token&quot;&gt;Example Access Token&lt;/h5&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt;header&amp;gt;.
{
   &quot;sub&quot;:&quot;aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee&quot;,
   &quot;device_key&quot;: &quot;aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee&quot;,
   &quot;cognito:groups&quot;:[
      &quot;testgroup&quot;
   ],
   &quot;iss&quot;:&quot;https://cognito-idp.us-west-2.amazonaws.com/us-west-2_example&quot;,
   &quot;version&quot;:2,
   &quot;client_id&quot;:&quot;xxxxxxxxxxxxexample&quot;,
   &quot;origin_jti&quot;:&quot;aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee&quot;,
   &quot;event_id&quot;:&quot;aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee&quot;,
   &quot;token_use&quot;:&quot;access&quot;,
   &quot;scope&quot;:&quot;phone openid profile resourceserver.1/appclient2 email&quot;,
   &quot;auth_time&quot;:1676313851,
   &quot;exp&quot;:1676317451,
   &quot;iat&quot;:1676313851,
   &quot;jti&quot;:&quot;aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee&quot;,
   &quot;username&quot;:&quot;my-test-user&quot;
}
.&amp;lt;token signature&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;sample-cdk-code&quot;&gt;Sample CDK Code&lt;/h4&gt;
&lt;p&gt;Imagine if we were creating resources using CDK, and wanted to then create an Authentication Stack in order to provide authentication and authorization mechanisms for accessing these resources in AWS. Perhaps we would like to employ a token header for API access, and based on the token, claims about the user will be used in order to determine appropriate permissions. Suppose we would only grant &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PUT&lt;/code&gt; access to Admin users, but &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GET&lt;/code&gt; is always available to all users. Suppose also&lt;/p&gt;

&lt;h5 id=&quot;breaking-down-the-cdk-constructs&quot;&gt;Breaking Down The CDK Constructs&lt;/h5&gt;
&lt;p&gt;Refer to the &lt;a href=&quot;https://gist.github.com/Adam-Lechnos/52b57ccebb82360c606b82d694f74d05&quot;&gt;GitHub Gist&lt;/a&gt;, containing the complete CDK for the hypothetical Authentication Stack, written in TypeScript. Here is the breakdown:
&lt;!-- &lt;script src=&quot;https://gist.github.com/52b57ccebb82360c606b82d694f74d05.js&quot;&gt; &lt;/script&gt; --&gt;&lt;/p&gt;

&lt;h5 id=&quot;create-user-pool&quot;&gt;Create User Pool&lt;/h5&gt;
&lt;div class=&quot;language-typescript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;createUserPool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(){&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;userPool&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;UserPool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;UserPool&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;selfSignUpEnabled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;signInAliases&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;username&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;CfnOutput&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;UserPoolId&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;userPool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;userPoolId&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
  &lt;li&gt;Creates a new User Pool named UserPool, with user sign-up enabled with only username and email address.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CfnOutput&lt;/code&gt; provides output to console during CDK Deploy, whereby the UserPoolID is displayed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h5 id=&quot;create-user-pool-client&quot;&gt;Create User Pool Client&lt;/h5&gt;
&lt;div class=&quot;language-typescript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;createUserPoolClient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(){&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;userPoolClient&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;userPool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addClient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;UserPoolClient&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;authFlows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;adminUserPassword&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;custom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;userPassword&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;userSrp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;CfnOutput&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;UserPoolClientId&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;userPoolClient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;userPoolClientId&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
  &lt;li&gt;Creates a new User Pool Client, which are specified under the App Integration tab of the User Pool, providing the app client name, authentication flow, session duration, and hosted UI settings.&lt;/li&gt;
  &lt;li&gt;Here we name the client UserPoolClient and attach it to the User Pool.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CfnOutput&lt;/code&gt; will output to console, the User Pool Client ID, during CDK Deploy.&lt;/li&gt;
&lt;/ul&gt;

&lt;h5 id=&quot;create-user-pool-groups&quot;&gt;Create User Pool Groups&lt;/h5&gt;
&lt;div class=&quot;language-typescript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;createUserGroup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(){&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cfnUserPoolGroup&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cognito&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;CfnUserPoolGroup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;UserPoolGroup&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;userPoolId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;userPool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;userPoolId&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;createAdminGroup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(){&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;CfnUserPoolGroup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;Admins&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;userPoolId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;userPool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;userPoolId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;groupName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;admins&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;roleArn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;adminRole&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;roleArn&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
  &lt;li&gt;Creates two user pool groups, attached to the User Pool, UserPoolGroup and Admins. The createAdminGroup function also contains added property values for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;groupName&lt;/code&gt;, which will provide a cleaner group name, ‘admins’, and roleArn, which maps the group to the ‘adminRole’, created below.&lt;/li&gt;
&lt;/ul&gt;

&lt;h5 id=&quot;create-identity-pool&quot;&gt;Create Identity Pool&lt;/h5&gt;
&lt;div class=&quot;language-typescript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;createIdentityPool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(){&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;identityPool&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;CfnIdentityPool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;IdentityPool&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;allowUnauthenticatedIdentities&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;cognitoIdentityProviders&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[{&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;clientId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;userPoolClient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;userPoolClientId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;providerName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;userPool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;userPoolProviderName&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}]&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;CfnOutput&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;IdentityPoolId&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;identityPool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ref&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;identityPool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;identityPoolName&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
  &lt;li&gt;Created an Identity Pool named IdentityPool, allowing Unauthenticated Users, and specifying Cognito User Pool as the Identity Provider referencing the User Pool Client via &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;clientId&lt;/code&gt; and User Pool Identity Provider as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;providerName&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Here, the User Pool Client options and User Pool Identity Provider come together for integration with the Identity Pool.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CfnOutput&lt;/code&gt; print to console the Identity Pool ARN.&lt;/li&gt;
&lt;/ul&gt;

&lt;h5 id=&quot;create-iam-roles&quot;&gt;Create IAM Roles&lt;/h5&gt;
&lt;div class=&quot;language-typescript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;createRoles&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(){&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;authenticatedRole&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Role&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;CognitoDefaultAuthenticatedRole&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;assumedBy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;FederatedPrincipal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;cognito-identity.amazonaws.com&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;StringEquals&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;cognito-identity.amazonaws.com:aud&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;identityPool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ref&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
            &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;ForAnyValue:StringLike&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;cognito-identity.amazonaws.com:amr&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;authenticated&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
        &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;sts:AssumeRoleWithWebIdentity&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;       
        &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;unauthenticatedRole&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Role&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;CognitoDefaultUnauthenticatedRole&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;assumedBy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;FederatedPrincipal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;cognito-identity.amazonaws.com&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;StringEquals&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;cognito-identity.amazonaws.com:aud&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;identityPool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ref&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
            &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;ForAnyValue:StringLike&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;cognito-identity.amazonaws.com:amr&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;unauthenticated&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
        &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;sts:AssumeRoleWithWebIdentity&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;       
        &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;adminRole&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Role&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;CognitoAdminRole&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;assumedBy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;FederatedPrincipal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;cognito-identity.amazonaws.com&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;StringEquals&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;cognito-identity.amazonaws.com:aud&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;identityPool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ref&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
            &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;ForAnyValue:StringLike&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;cognito-identity.amazonaws.com:amr&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;authenticated&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
        &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;sts:AssumeRoleWithWebIdentity&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;       
        &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;adminRole&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addToPolicy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;PolicyStatement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;effect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Effect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ALLOW&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;actions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;s3:ListAllMyBuckets&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;resources&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}))&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;CfnOutput&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;AdminRoleArn&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;adminRole&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;roleArn&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
  &lt;li&gt;Creates three IAM Roles, CognitoDefaultAuthenticatedRole, CognitoDefaultUnauthenticatedRole, and CognitoAdminRole, with the last containing a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PolicyStatement&lt;/code&gt; via the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;addToPolicy&lt;/code&gt; method, to allow the listing of all S3 Buckets within the AWS Account.&lt;/li&gt;
  &lt;li&gt;All three roles make user of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;assumedBy&lt;/code&gt; property, by creating a new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FederatedPrincipal&lt;/code&gt; object, each role contains a JSON object of ‘Trusted entities’, allowing each role to be assumed by the Identity Pool created above.
    &lt;ul&gt;
      &lt;li&gt;CognitoDefaultAuthenticatedRole performs a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StringEquals&lt;/code&gt; for Cognito Authenticated Users, allowing only users Authenticated by Cognito to assume this role, with the following line under &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ForAnyValue:StringLike&lt;/code&gt;: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&apos;cognito-identity.amazonaws.com:amr&apos;: &apos;authenticated&apos;&lt;/code&gt;.
        &lt;ul&gt;
          &lt;li&gt;Authenticated User will inherit the policy associated with this role. Currently, no policy statement has been set.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;CognitoDefaultUnauthenticatedRole is the same as the role above, however, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ForAnyValue:StringLike&lt;/code&gt;: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&apos;cognito-identity.amazonaws.com:amr&apos;: &apos;unauthenticated&apos;&lt;/code&gt; for assumption of the role by unauthenticated users.&lt;/li&gt;
      &lt;li&gt;CognitoAdminRole contains the same JSON as CognitoDefaultAuthenticatedRole, for use by Admin users. This role will only work for Authenticated Users, but contain the permissions as listed within the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;addToPolicy&lt;/code&gt; method.
        &lt;ul&gt;
          &lt;li&gt;In addition to the AWS permissions provided by the policy statement, API Gateway will receive the Access Token supplid by the Authorization header. Downstream, a Lambda function may parse the event claims’ &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&apos;cognito:groups:&apos;&lt;/code&gt; key, and based on it value, allow the coded permissions.
            &lt;ul&gt;
              &lt;li&gt;For example, a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hasAdminGroup&lt;/code&gt; function may be created, whereby the event body is supplied, and if any values in the list match ‘admin’, will allow certain API methods. Perhaps only the Delete method would contain the following code:&lt;/li&gt;
              &lt;li&gt;
                &lt;div class=&quot;language-typescript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;hasAdminGroup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)){&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;statusCode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;401&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;stringify&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;Not authorized!&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;                &lt;/div&gt;
              &lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h6 id=&quot;identity-pool-role-attachments--mappings&quot;&gt;Identity Pool Role Attachments &amp;amp; Mappings&lt;/h6&gt;
&lt;div class=&quot;language-typescript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;attachRoles&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(){&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;CfnIdentityPoolRoleAttachment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;RolesAttachment&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;identityPoolId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;identityPool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;roles&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;authenticated&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;authenticatedRole&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;roleArn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;unauthenticated&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;unauthenticatedRole&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;roleArn&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;roleMappings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;adminsMapping&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;Token&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;na&quot;&gt;ambiguousRoleResolution&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;AuthenticatedRole&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;na&quot;&gt;identityProvider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;userPool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;userPoolProviderName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;userPoolClient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;userPoolClientId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;`&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
  &lt;li&gt;The IAM Roles will be attached to the Identity Pool, whereby the Identity Pool is specified using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;this.identityPool.ref&lt;/code&gt;, and the default authenticated and unauthenticated roles via &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&apos;authenticated&apos;: this.authenticatedRole.roleArn&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&apos;unauthenticated&apos;: this.unauthenticatedRole.roleArn&lt;/code&gt; lines.&lt;/li&gt;
  &lt;li&gt;Role mapping are specified within the nested JSON &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;roleMappings:&lt;/code&gt; object. In the above example, the name is specified as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;adminsMapping&lt;/code&gt;, which is of type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Token&lt;/code&gt;, with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ambiguousRoleResolution&lt;/code&gt; set to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AuthenticatedRole&lt;/code&gt;. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;identityProvider&lt;/code&gt; contains the User Pool Provider name from the userPool object, concatenated with a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:&lt;/code&gt; and the User Pool Client ID.
    &lt;ul&gt;
      &lt;li&gt;Setting Type to ‘Token’ will use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cognito:roles&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cognito:preferred_role&lt;/code&gt; from the ID Token claims supplied by the Cognito Identity Provider. The IAM roles are mapped via the user group memberships within the Cognito Identity Provider, as listed within the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&apos;cognito:groups:&apos;&lt;/code&gt; claim.&lt;/li&gt;
      &lt;li&gt;Setting Type to ‘Rules’ will attempt to match claims from the ID Token to map a role. In this case the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;roleMappings&lt;/code&gt; JSON would be as follows:
        &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  roleMappings: {
      adminsMapping: {
          type: &apos;Rules&apos;,
          ambiguousRoleResolution: &apos;AuthenticatedRole&apos;,
          identityProvider: `${this.userPool.userPoolProviderName}:${this.userPoolClient.userPoolClientId}`,
          rulesConfiguration: {
            rules: [{
              claim: &apos;claim&apos;,
              matchType: &apos;matchType&apos;,
              roleArn: &apos;roleArn&apos;,
              value: &apos;value&apos;,
            }]
          }
      }
  }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;        &lt;/div&gt;
      &lt;/li&gt;
      &lt;li&gt;In addition, the IAM policy attached to the Authenticated role will also be applied but not listed within any of the claims, granted permissions as provided across all mapped roles and the authenticated roles.&lt;/li&gt;
      &lt;li&gt;Unauthenticated users will receive permissions against the Unauthenticated Role. APIs may still choose to allow access to certain to methods omitting a check against the Access Token.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h6 id=&quot;disparate-app-client-api-method-access&quot;&gt;Disparate App Client API Method Access&lt;/h6&gt;
&lt;p&gt;&lt;em&gt;Authorization Scopes&lt;/em&gt; are used to determine the granted permissions for an app. Authorization Scopes are supplied to each API Method, by providing the Authorization value as the Cognito User Pool. A domain for the user pool must be configured, at which point, Amazon Cognito automatically provisions an OAuth 2.0 authorization server and hosted web UI with sign-up and sign-in pages that the web app can present to users. Authentication to the sign-in pages creates and ID Token and Access Token, which  then may be used to access the API resource.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A Resource Server is an OAuth 2.0 API server, such as the API Gateway and its methods pointing to a Lambda function handler. It validates that access tokens from the user pool contain the scopes that authorize the requested method and path in the API that protects it.&lt;/li&gt;
  &lt;li&gt;Access tokens are the OAuth 2.0 JWT tokens which contain claims, including custom claims, recall from the &lt;a href=&quot;#breaking-down-the-cdk-constructs&quot;&gt;Breaking Down The CDK Constructs&lt;/a&gt; section above. You also learned that ‘aws.cognito.signin.user.admin’ was added by default to the claims within the Access token. It authorizes the bearer of an access token to query and update all information about a user pool user with, for example, the GetUser and UpdateUserAttributes API operations.
    &lt;ul&gt;
      &lt;li&gt;GetUser: Gets the user attributes and metadata for a user. More details within the API Reference for &lt;a href=&quot;https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_GetUser.html&quot;&gt;Amazon Cognito User Pools&lt;/a&gt;.&lt;/li&gt;
      &lt;li&gt;UpdateUserAttributes: Allows users to update one or more of their attributes with their own credentials. More details within the API Reference for &lt;a href=&quot;https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_UpdateUserAttributes.html&quot;&gt;Amazon Cognito User Pools&lt;/a&gt;.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Additional &lt;em&gt;Custom Scope&lt;/em&gt; are required in order to parse them from the API Authorizer to grant each method’s API access.
    &lt;ul&gt;
      &lt;li&gt;For example, ‘read’ would be parsed by the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GET&lt;/code&gt; resource to allow access to this API method.&lt;/li&gt;
      &lt;li&gt;Custom scopes are added to the Cognito User Pool, App Integration, Resource servers, within the AWS Management Console.&lt;/li&gt;
      &lt;li&gt;The created custom scopes are then added within the Identity Pool associated with the User Pool.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://repost.aws/knowledge-center/cognito-custom-scopes-api-gateway&quot;&gt;Read more about Cognito Custom Scopes for API Gateway&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://repost.aws/knowledge-center/cognito-custom-scopes-api-gateway&quot;&gt;Read more details about OAuth 2.0 scopes and API Authorization with resource server&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h6 id=&quot;adding-a-resource-server&quot;&gt;Adding a Resource Server&lt;/h6&gt;
&lt;div class=&quot;language-typescript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;createResourceServers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(){&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;readOnlyScope&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cognito&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ResourceServerScope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;scopeName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;scopeDescription&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;Read-only access&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;fullAccessScope&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cognito&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ResourceServerScope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;scopeName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;scopeDescription&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;Full access&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;userServer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;userPool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addResourceServer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;ResourceServer&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;identifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;users&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;scopes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;readOnlyScope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;fullAccessScope&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
      
      &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;readOnlyClient&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;userPool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addClient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;read-only-client&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;oAuth&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;scopes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cognito&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;OAuthScope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;resourceServer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;userServer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;readOnlyScope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
      
      &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;fullAccessClient&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;userPool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addClient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;full-access-client&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;oAuth&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;scopes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cognito&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;OAuthScope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;resourceServer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;userServer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;fullAccessScope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
  &lt;li&gt;Created two different resource servers named ‘read-only-client’ and ‘full-access-client’. The resource servers create two different access scopes, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scopeName: &apos;read&apos;, scopeDescription: &apos;Read-only access&apos;&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scopeName: &apos;*&apos;, scopeDescription: &apos;Full access&apos;&lt;/code&gt;, added to their respective resource servers. Each resource servers is accessed by its client ID, generated upon creation. The resource servers are then accessed by the hosted UI and client ID. In response will be either an ID and Access Token or Authorization Code, depending on the Authorization Flow. Authorization Codes are then redeemed for ID &amp;amp; Access Tokens, using the &lt;a href=&quot;https://docs.aws.amazon.com/cognito/latest/developerguide/token-endpoint.html&quot;&gt;Token Endpoint&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The following is an example CURL request/response to/from the token endpoint for the Authorization Code flow using an Access Code. This is for illustrative purposes and would not work for a single page app written in React.&lt;/p&gt;

&lt;p&gt;Request&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl --location --request POST &apos;https://example-est.auth.us-east-1.amazoncognito.com/oauth2/token&apos; \
--header &apos;Content-Type: application/x-www-form-urlencoded&apos; \
--data-urlencode &apos;client_id=5j9701eo7qmhf91oth5eks6kii&apos; \
--data-urlencode &apos;code=79927d32-ba18-4cff-8254-b7d43d1347a2&apos; \
--data-urlencode &apos;grant_type=authorization_code&apos; \
--data-urlencode &apos;redirect_uri=https://example.com&apos;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Response&lt;/p&gt;
&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;id_token&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;eyJraWQiOiI3SFRmUHF3OTdVRHQwdTQ0cFoyVVZQMFVCVUV5d0toWlNmYVNsc0pTdWl3PSIsImFsZyI6IlJTMjU2In0.eyJhdF9oYXNoIjoibzBNVDBnWVEwbVdua3EwdnA2dHk4ZyIsInN1YiI6ImQ0ODhlNDM4LWIwZDEtNzAxMS1iYzJjLTYwNGExOTlmY2RkNSIsImNvZ25pdG86Z3JvdXBzIjpbImFkbWlucyJdLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiaXNzIjoiaHR0cHM6XC9cL2NvZ25pdG8taWRwLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tXC91cy1lYXN0LTFfOGo2UjZqS0NZIiwiY29nbml0bzp1c2VybmFtZSI6ImFsZWNobm9zIiwib3JpZ2luX2p0aSI6IjYyMGEwMTY2LTRhNGItNDA0Ny1iNGQzLWFmN2U5MWE1NTQ0NyIsImNvZ25pdG86cm9sZXMiOlsiYXJuOmF3czppYW06OjgyMDEyNzUwOTgxMjpyb2xlXC9BdXRoU3RhY2stQ29nbml0b0FkbWluUm9sZTRDMTBGQkE0LUVpRFRIb0VmMWFuUiJdLCJhdWQiOiI1ajk3MDFlbzdxbWhmOTFvdGg1ZWtzNmtpaSIsInRva2VuX3VzZSI6ImlkIiwiYXV0aF90aW1lIjoxNzA4NjMxOTg0LCJleHAiOjE3MDg2MzU1ODQsImlhdCI6MTcwODYzMTk4NSwianRpIjoiYzJmMzMwZWQtYmE0Zi00YzNmLWJhY2ItMDQyNDA3ZGE2NTZmIiwiZW1haWwiOiJhZGFtLmxlY2hub3NAZ21haWwuY29tIn0.veWBGSGEUL8Gz9zHLHa0oWm6L_w3Y76-GtXG_oYnDrmgVAHU7e2RYCE7YEYRN2Mh1sZVLEXZdbQIgO-BNjQqbfLQwIeyDz4o0hAakUMYwuBvk1f9WfntTuszCS8jCZvK2ERZ8r9utcpKndjqVWt2RzGmYaSgJXa5xdCZXfSS77y3KhRvLKY-4AI-pnuthheRHFUzxZHkDhM0YXjL3lKSpjI3697bDBa5K-qRMTVNO37uVAno_AUJ1bb0C7iqwWAC0DN9D6QyGetY0coh4ex9IxmoHiti7D9pZKAyriufa5P6VAk-QNJpPWJ1b0rkT4dIZ_4vG2Ydh63hvUPN99NO_g&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;access_token&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;eyJraWQiOiIyRDRPSlk2ZTY4OGt0aU94eXBSNWRvWEtEc3lHYmFCR01WWmJmYm1oN0dvPSIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiJkNDg4ZTQzOC1iMGQxLTcwMTEtYmMyYy02MDRhMTk5ZmNkZDUiLCJjb2duaXRvOmdyb3VwcyI6WyJhZG1pbnMiXSwiaXNzIjoiaHR0cHM6XC9cL2NvZ25pdG8taWRwLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tXC91cy1lYXN0LTFfOGo2UjZqS0NZIiwidmVyc2lvbiI6MiwiY2xpZW50X2lkIjoiNWo5NzAxZW83cW1oZjkxb3RoNWVrczZraWkiLCJvcmlnaW5fanRpIjoiNjIwYTAxNjYtNGE0Yi00MDQ3LWI0ZDMtYWY3ZTkxYTU1NDQ3IiwidG9rZW5fdXNlIjoiYWNjZXNzIiwic2NvcGUiOiJhd3MuY29nbml0by5zaWduaW4udXNlci5hZG1pbiBvcGVuaWQgdXNlcnNcL3JlYWQiLCJhdXRoX3RpbWUiOjE3MDg2MzE5ODQsImV4cCI6MTcwODYzNTU4NCwiaWF0IjoxNzA4NjMxOTg1LCJqdGkiOiI1YjI1YTRhYS0zZGZjLTRiZWUtOGIyMS0zMjA4NTRlY2QyOGUiLCJ1c2VybmFtZSI6ImFsZWNobm9zIn0.EWCEwDk46i8fOU4IVnlwgM7XNz_i-jtYcpyOYE8q4YGFC7giK5lWgzgIcD9_zHzUF6bVc6iv1uqtQDEXZlOU7pofMhUWBykqnDUC0Q57X4bP3giDigIYmfj77zJLxlWhwRvim28hZfJg9Sz_RIBcf13lo4D8bZvTE5HVEEI-tztuA4B-1dDY65po2zMHqwBEWF9FYaQC2edm5lyQEtTFleHVawBVbQWIU3Ud16TznAy9WEp2q_QgsNSFKuF-2LnQuO27MfyFWFGza8gDMrBwxVJ1l9bjrJuLH300QqQWLdaX7FTupOZHtvUxeND3K4Hc0-ZTu-nvpGUYOAxemfyyIQ&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;refresh_token&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;eyJjdHkiOiJKV1QiLCJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiUlNBLU9BRVAifQ.RMAy1jPNXxpGdPIr1TUukG685KbV5JgokWkBtnWDFOOlcFSRGWS-uNkglPdJJv4g1r4nk7jxYY8J8HnYmomzlt7OD0FdSnvrCEr61SbDZz5FZ9jhzdl-p2_fEoi_fUydpwG_JUliFucvutwDcBd1W2Ul900b24m1nHSrq_NL8r9uFJcVrkFDWLKQ9fxipSYZyU37LePN-qrxX78pQS2vIIe8tVvrG6CuK4GjdRDUvz10tpDFHdTFH75Bn0GHr5xoXXCuTg7CkuyipVYapYeI_AwJIEYBfLzlUjl99hrfkxDUVqlpyqgj9Jq_NOsXwt-sd73ZbPoBGAurAIw2Yw6mxg.WUaX_U7nlacSnml-.CctUJfNf4hngQr4QktmuTWTT5myYN03GzwVWgktiQpGHccW5jgK9QSQmKIG5v33qHoG5KOpm7xyKU9YsehJjpZHj8yq_NMMEamk7DCv4UR7ooXBJS2Hf6KL7Y-2sFxD6Eec7P37t1HtP5QOB1P5CNZgxW069hQpKj6uyOmOqvrso88Jtk18HjRw0SZY1r2jzdey-PRsoinukv2_JWaH2A35QFuApVwurov3DWl7kNKXkQldOROkYC1xrOidXxVTfirschCxSTcNWf481Jh9BF-W_eYcnyAJU0RAFQjZdLEdEUBTl2uH3jTVfGl9qdq32oXmd_EoeugBCW2zUbgekJbRlfmMWt42bZ67qz6ZAZ-cgijp16g1f01pXKV-vKdXIvjOm6IZin9whMwoK4i6zFjfAZLlYPRP2N-lZCRW8d7YeOz7S00OISy5qHF6DpDhm6sWFe0VBmyaYjZKzZob99DXyXBVLJukn1_R2MD5nJNRzCUvJCni3RZ4vEOW8lUK2RwcGjPiLgMH9EalVcALsIq0zV_SsSHUzgXeuvFz6sP-ygIkogrfLKGnGg5ssMpsL6rAlmSskz39veMmWDRxzx20daQXr_vpRHVmk5_Lg6alX7l3uMNGUOpvLEJssRsDWf99kuyXYWA0aqNr80RiJS67TXX0DrmhKtipvnd_cb3G5xcvVsu5xc37g9UnA57Bzvi1ulB9XlcgfrpKZxgPUTV0OtWvVvUDIoi06aOCOMeQgcMBRKoS6T8Qrplg8OzCGmg5cNPgap8foPfD9qgY5DWDlMgtmtohmH_Sg8dFTAdE0fmWhFXmWw5ErVlg4Ea0FtOl5ix8DqOQx0hT_ClhGW-aiXUHoVy7uZHK2Fa385aBoxrk-DtxO5r0ROUjnVwGTVUdUPBFWAb905nTs1K5cvWgkwdRp-wq4NFhwcDy8T1h5Dss3kouIx53JiZv5E4gsroynF7fOL_4vxlt0dM-ykWBB1sN988cTvqUNunWM3vofNWnaEg-_YP7xbOFas78HKqqm4-2UNlM0bYY8E8D6TDf9KtPbZb0Pt2HuJYv6z9JiAmS24Og7Bce1DiEOlGafLrSMgkHp84TumRXWOLurJtVIW2MajM06k3xvAQYdP4rcb4zgss_Pegtq-6AWgNpJ7TvT14NLjm2GXahu2x6gr4EG8Tr3LRDJwOAkxxNwogv2RfBqI8YrjQzDZ_-jzwhhdOvvik3FswYoeLv-UGy333K4gYYEu9SuPsvV5ag.Uy9EJjNpUCosi7jYTiIdew&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;expires_in&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3600&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;token_type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Bearer&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;JWT.io deencoded Access Token&lt;/p&gt;
&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;sub&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;d488e438-b0d1-7011-bc2c-604a199fcdd5&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;cognito:groups&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;admins&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;iss&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;https://cognito-idp.us-east-1.amazonaws.com/us-east-1_8j6R6jKCY&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;version&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;client_id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;5j9701eo7qmhf91oth5eks6kii&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;origin_jti&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;620a0166-4a4b-4047-b4d3-af7e91a55447&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;token_use&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;access&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;scope&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;aws.cognito.signin.user.admin openid users/read&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;auth_time&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1708631984&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;exp&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1708635584&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;iat&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1708631985&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;jti&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;5b25a4aa-3dfc-4bee-8b21-320854ecd28e&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;username&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;username&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
  &lt;li&gt;The de-encoded Base64 Access Token indicates the scope values which were also attached to the resource server, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;scope&quot;: &quot;aws.cognito.signin.user.admin openid users/read&quot;&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The next post will go-over testing the CDK’s Authorization Stack, by writing some test code in TypeScript.&lt;/p&gt;

&lt;p&gt;&lt;sub&gt;&lt;em&gt;&lt;a href=&quot;https://www.udemy.com/course/aws-typescript-cdk-serverless-react/?couponCode=ST15MT31224#instructor-1&quot;&gt;Original code snippets by Alex Dan via Udemy&lt;/a&gt;&lt;/em&gt;&lt;sub&gt;&lt;/sub&gt;&lt;/sub&gt;&lt;/p&gt;
</description>
        <pubDate>Mon, 20 Feb 2023 12:00:00 +0000</pubDate>
        <link>https://adamlechnos.com/aws/devops/cdk/typescript/2023/02/20/aws-cdk-cognito.html</link>
        <guid isPermaLink="true">https://adamlechnos.com/aws/devops/cdk/typescript/2023/02/20/aws-cdk-cognito.html</guid>
        
        
        <category>aws</category>
        
        <category>devops</category>
        
        <category>cdk</category>
        
        <category>typescript</category>
        
      </item>
    
      <item>
        <title>AWS Cloud Development Kit (CDK) - Understanding the Node/Tree Relationship</title>
        <description>&lt;h3 id=&quot;diagram&quot;&gt;Diagram&lt;/h3&gt;

&lt;h4 id=&quot;aws-cloud-development-kit-treenode-diagram-drawio-viewer&quot;&gt;&lt;a href=&quot;https://viewer.diagrams.net/index.html?tags=%7B%7D&amp;amp;highlight=0000ff&amp;amp;edit=_blank&amp;amp;layers=1&amp;amp;nav=1&amp;amp;title=Devops-IaC-AWS_CDK_Tree_Node.drawio#R7V1td5u4Ev41Ptn7ITkI8frRSZttz%2B22ab29290v9xBQbFqMKMZNvL9%2BJUA2krBNAwgHb89pYoR4ycw8o9EzI3kCb5ZPv6ZesvgNByia6FrwNIGvJroOLNMlv2jLpmhxbKdomKdhUHbaNczCv1HZqJWt6zBAK65jhnGUhQnf6OM4Rn7GtXlpih%2F5bg844p%2BaeHMkNcx8L5Jb%2FwiDbFG2Ak3bnXiDwvmifLRjlieWHutcNqwWXoAfK03w9QTepBhnxafl0w2KqPCYXIrrbvec3b5YiuKsyQXvf7xHePl59eXznamHH%2BGbr98%2FXzp6cZsfXrQu%2F%2BIbHK%2BydE1kWbx2tmGySPE6DhC9nTaB14%2BLMEOzxPPp2UeifdK2yJYROQLk40MUJv%2BrfH7DPodRdIMjnOb3hIGJnMAg7eSZ%2BBuqnHH0e2hZ9AocZ7PyLUpZ%2FkBphp72CgJsxUvskvzRKEs3pEt5ganB4pLSJC29NMnHnYKd8kGLimqZIr3SpObbO%2B%2BkTj6Ugv8JJbhQEjUKiBWWhzjNFniOYy96vWu95pWx6%2FMO46QU9VeUZZsSUt46w7yCJIHf3rruLfk7rou3oa9wWMLkjfE69dEh%2B4L1qkhR5GXhD%2F4BdYItL73DIXn0ToWGoEJT0E3mpXOUlVcJ6tm%2BxvM15sDzg40hyty2BoaNMV7YGOOEjXF%2BsDEt47Rg4zhDwIZIK918oddfmezwz%2Bq5V0%2FlzYujTXmkBm5m0bEw%2F96Hs2maeptKh4TibbUftoalcyZkAyHSE%2Fs78FB%2F8qF4g26xbZ4ftg1dUIxuD4xt919siyKxmmK7kzH3Z7Ft6QexKvfXjEP9e8K2dX7YNkUnqhDbH%2FHH5Sb%2BPjVmt%2B6vb2fw%2F7%2F9Hl0CSQf3a%2F8byki7lh9rMXokP6%2Fz1l8muhVlpVxyfoSJzPq%2BppQDwRjUNN8nwqs0WXP6O1uEK3Y9edfiFsWpiX5Dn7e95Jq9w%2B4eeQf7On%2B79C7FyerqamK%2F%2Bo8aS%2FGQ8%2BDXWYrlO%2Bj%2Bod5SahyLZDx7LcViXNCGDddyhActlcOAbCrhMiGOvXgWMYbgG%2BXCUrwkvy68x9UlabmMwvsLJTp6ePDJvzodQQu6MBB0tE8hP4Nmx7Y5HTlM9hUdbfWhRkcvKgzvcEDWG47HwGw5HrdSj8yLtnGoXpLs9aec8yY4vJomyS%2Bn7CzbhcwQcEAELEEwGBCNQWikEwAibAjEYpKjOjB22VymNBTdVBDoyrRuEWPNMs%2F%2FVhtn5WdaBVuHfAMNpS4qD7oYrV8wLT6I0g15gDY0lX4B6mfqF4ymfmGPRnv2C4KdqHALMm298OIgQmmdX3hTOdWvY6g%2B6aJoQ08ZogZYTrtG6y6A3sRd6Crdhf2S3IUS6q0pq64PwqoDwBM8hqPAk8gkeeE03nnL%2B8C7Xcd%2BFuK4X%2FLmgn9Y6TnY4eg9h8lPQGrZGkMpE%2FCiSPsO%2FQNo6iCA3dJBtNOPDFoy5JK%2Ff6QIMVyLQwjQTAkhrlKA2JICxp9%2B0AQ3JetAaWYRDlKjdgJOalt1ejSKcYeIYkwhDlaRDtymSDiHSCdC43SIIjWhyXMNpekdwxoCi11iqhNGUY7oNYPXFHAEFfRc36bLWYNRA8M1BY6WDVpDIQOeayitNybz22bVuplri2sVhP4OONS9p1FNJv97m4aXhCGbc4%2FVP1gOr0YoD5xKJxJseDg%2F99CYims7036WexDgDu0jNXAHu%2FfkHWQSgKH32luNlguAPBUAWQX%2FYAgGkqTPBMF2UwQ7QyBYhOSR8V1YhwKVjO8yi%2FQJlXIfKXqBgF4oU91K0WsNTSI5mlHF76V2BYwjGM6P7lAaEhGgdKIwfcaWpR6FfNvC9XaFco4Eq9GTs7z30p2BuVlrED5oB6sqpCoj5B5AUWVUlKTl%2F5Rhym06jHYxisrjnlC2AGzFBJV7fmAFgshrCk7VZlK0c9SBdmJaMM%2B1%2FJ6VPxz1gOYgVTmurXOGcowpBBowDl3QUxmPnAHrmyssqoDVOIgBMgk6vz5ncKqQ%2Bafz8w9NMwnmMJkEEe%2FHyEKgGQPQhaacTCgAPGay0LX4dODgbCHLPZ4fiJvy%2FaY1DIhFTB4d5U370AU9gVjm%2FMfOGLruqVGGQ6%2FO0zl242TJQrPpNhdto%2Fp2UdUZbiRBIhbedw3OF5qDLFXpGgaHNsk4Pu4Ns3ZNnNyWe4H1OopZ5hi0fZBK653NbTeEyYnHYi6QL7VR4vbojhuuW6eW2h03dtFoK89nOzzpVzupdxU6Pvtc5wNW01SiNUgROxTqdg1DQXRvyYlLbg3ciIGpizsW1QATKF1sz5iDGmV8SOjPUatDWNMO3aHVYdfVwoqeMw6mdIN1chTjmHrKwFstcoUAXvi0%2Fc7LyIwozlt0DW5FzDZV1yVPi57C7Atzk%2BRzJbtMjnY%2Bkx70VlEt66yiE7NGJaytbaJYRKi4kqF4fylRLN1Igroh3KjnjLMt750wKksaykAcYXtCSa9NDcRlla1DGYhMsgmptJ2lsLwZPXG5yuOtKengJk9FMk1Iq72NiaE80CFhX27tNIeU%2FLiIJt1uRhihBsJ2a9bp1ATioLfxReaB3qE58QOSSsjfnPFy96JwTtHvozjn2K6pZELfi6bliWUYBHnkXqdAXsX8NoOc5EFHg7vLr4GwXPnLJuqWSMHeRC%2FPRovtIPH9V%2FoFKrr2zN0nno%2FTGK0yohJdq3CBxUaVMx8niB6k8%2FUS5citA%2FKJblahAMmOLnOJ2z5qoCxPo97GC5SGskqZhZ0iz6tCV5oMfaBUVyyIrOhq%2BseMaunVf8nPS%2FL%2F9xQRwN2%2BxwHF3ac8SCEqXITJoK65hTJK6dfhxJRl39%2B3lchDXjskUPF%2FIGfDbFtZW8FAGUh3YMWGJoxgbC1nVZS10YNY3NqdHcvlV9N1tqB%2FOB1npoFHNzZ%2Bh%2FxFjGXiQJ3dduxWtlveyW5EUxm9ubLLl4TcfE4nzNXqq8o7o0qPMqDunooINdM6oT7cECHUdFa3ZfS2oFU7qwNs771ebQScpY0ATcyrPJcccoTdYyxx1tG7lciT%2F78wuS2NHPGavmmAkrBcI6%2FhhwndZJNNFvKYRY4vB3H4ncaNBvPmbLpu1gQvLKvIBS%2BwJ48PtEGWGPW3VKhthkuCks0XtNlsWnQESTU7ZRy%2Bzx5od4fIQWpDGit6e%2BZkFG01c5lHFS3ep3dFy0GczLa8cEdq8xy5zcpvqoVXdYGz3psbldOcHxjtVrImXlxTXfrSBC9s6GGbciG4rVTwQJ4xyn7u3zTUz8eiwreRGfqV1ciPyX5VSFEYQizTdyjKbK%2FKYy6TCFFHuMrhuU0mjQycsOaLzboBJzncfb95oandt8TD1%2F8A#%7B%22pageId%22%3A%22oHD4UgEJbGO4PoZvh1VS%22%7D&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;AWS Cloud Development Kit Tree/Node Diagram (draw.io viewer)&lt;/a&gt;&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;https://github-content-cache.adamlechnos.com/Adam-Lechnos/diagrams-charts/blob/main/devops/Devops-IaC-AWS_CDK_Tree_Node.drawio.png?raw=true&quot; alt=&quot;AWS Cloud Development Kit Tree/Node Diagram&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;details&quot;&gt;Details&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;The AWS CDK is a tree/node relationship structure, requiring the initializing of the root node via the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;app = new.cdk.App()&lt;/code&gt; object, imported from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;aws-cdk-lib&lt;/code&gt; CDK library. The object inherits the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Stage&lt;/code&gt; object which in turn inherits the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Construct&lt;/code&gt; object.&lt;/li&gt;
  &lt;li&gt;Subsequent AWS resources are instantiated &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Stack&lt;/code&gt; objects, such as the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bucketStack = new BucketStack(app, &apos;BucketStack&apos;)&lt;/code&gt; instance created, which in turn inherits the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Construct&lt;/code&gt; object.&lt;/li&gt;
  &lt;li&gt;Hence, each new instantiation of an AWS resource, is a child of the Construct, which is then added to the root Construct, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;app&lt;/code&gt; per the first &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scope&lt;/code&gt; argument for each instantiated resource’s constructor.
    &lt;ul&gt;
      &lt;li&gt;i.e., handlerStack = new HandlerStack(&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;app&lt;/code&gt;, ‘HandlerStack’, extendedProps..)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Resouces created inside resources, such as the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;new LambdaFunction(this, &apos;LambdaFunction&apos;, FunctionProps)&lt;/code&gt; Lambda functions, contains the first argument &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;this&lt;/code&gt;, for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scope&lt;/code&gt; parameter since this is the parent object, &lt;strong&gt;handlerStack&lt;/strong&gt;, which inherits a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Construct&lt;/code&gt; object.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To button up the tree node relationship, each object is inherited from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Construst&lt;/code&gt;, which in turn is nested within each other via the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scope&lt;/code&gt; parameter, either as &lt;em&gt;this&lt;/em&gt; when scoping in as a child of a resource, such as &lt;em&gt;handlerStack&lt;/em&gt;, or as &lt;em&gt;app&lt;/em&gt; for each new instantiated resource. Each nested resource is scoped within it’s parent, and each resource is scoped within its root node, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;app&lt;/code&gt;.&lt;/p&gt;

</description>
        <pubDate>Fri, 17 Feb 2023 12:00:00 +0000</pubDate>
        <link>https://adamlechnos.com/aws/devops/cdk/2023/02/17/aws-cdk-node-tree-relationship.html</link>
        <guid isPermaLink="true">https://adamlechnos.com/aws/devops/cdk/2023/02/17/aws-cdk-node-tree-relationship.html</guid>
        
        
        <category>aws</category>
        
        <category>devops</category>
        
        <category>cdk</category>
        
      </item>
    
      <item>
        <title>PCI Compliance in AWS - Simplified (featured in ISC2 Blog)</title>
        <description>&lt;h2 id=&quot;pci-compliance-in-aws---simplified&quot;&gt;PCI Compliance in AWS - Simplified&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;This blog post also featured in the &lt;a href=&quot;https://web.isc2ncrchapter.org/pci-compliance-in-aws-simplified/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;(ISC)² Blog&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Payment Card Industry Data Security Standards or PCI DSS, are a set of 12 requirements with over 300 controls which apply to any organization which stores, processes or transmits credit card data. Today, I will attempt to add some clarity around PCI compliance within AWS.&lt;/p&gt;

&lt;p&gt;Concepts and practices were sourced from the referenced document below and here I will break it down further. I do suggest you first read the Architecting for PCI DSS Scoping and Segmentation on AWS and come back to enhance your understanding of the methods being applied and its rationale.&lt;/p&gt;

&lt;p&gt;For a quick primer on PCI-DSS, please refer to the council’s overview PDF.
Referenced from: https://d1.awsstatic.com/whitepapers/pci-dss-scoping-on-aws.pdf&lt;/p&gt;

&lt;h3 id=&quot;infrastructure-services&quot;&gt;Infrastructure Services&lt;/h3&gt;

&lt;p&gt;Infrastructure services such as EC2 require the most amount of effort from a PCI compliance
perspective based on the AWS Shared Responsibility Model.
Other services are categorized as ‘Abstracted’ or ‘Containerized’(not to be confused with containers such as Docker or such services as Fargate thoughencompassed by this category).
Examples are EC2 instances which require host based firewalls, configuration and patch management, OS level logging, and an assurance of non-vendor defaults such as the usage CIS bench-marking (using AWS AMIs should be sufficient).&lt;/p&gt;

&lt;h3 id=&quot;kubernetes-on-ec2&quot;&gt;Kubernetes on EC2&lt;/h3&gt;

&lt;p&gt;Like EC2, ECS and EKS are all deemed ‘Infrastructure’ based services. These services expose administrative access and control at the OS layer and hence their designation. Today, since we manually manage Kubernetes in a cluster of EC2 instances, we therefore must apply PCI practices at all layers of the shared responsibility model except for physical controls such as in the examples mentioned above.&lt;/p&gt;

&lt;h4 id=&quot;aws-fargate-considerations&quot;&gt;AWS Fargate Considerations&lt;/h4&gt;

&lt;p&gt;Using AWS Fargate in lieu of EC2 hosting Kubernetes would reduce the PCI compliance footprint as Fargate is considered a ‘Containerized’ service and hence, the degree of PCI compliance requirements is greatly reduced as per the AWS Shared Responsibility Model.
The instantiation of Fargate within-in it’s own AWS Account and the endpoints it connects would be in scope. Fargate would not require network, OS level, and like EC2, nor physical level controls.&lt;/p&gt;

&lt;h3 id=&quot;abstracted-services&quot;&gt;Abstracted Services&lt;/h3&gt;

&lt;p&gt;URL Load Balancers, API Gateways, and other ‘Abstracted’ services are services in which the degree of control is limited to the movement of data using AWS APIs. AWS handles network, OS, and physical controls therefore, minimizing PCI scope of work.&lt;/p&gt;

&lt;p&gt;The instantiation of an Abstracted service within its own AWS Account and the endpoints it
connects would be in scope. Fargate would not require network or OS level controls and like EC2 nor physical level controls, like Containerized services.&lt;/p&gt;

&lt;h4 id=&quot;network-and-encryption-level-abstracted-services&quot;&gt;Network and Encryption Level Abstracted Services&lt;/h4&gt;

&lt;p&gt;Application Load Balancers, Web Application Firewalls, and KMS must be configured to terminate TLS version 1.1 or greater between itself and all endpoints.&lt;/p&gt;

&lt;h4 id=&quot;connected-to-and-security-impacting-gotchas&quot;&gt;Connected-to and Security-Impacting Gotchas&lt;/h4&gt;
&lt;p&gt;Any service that supports, directly impacts, or provide security to the CDE fall with-in scope of PCI compliance.
i.e, Vault provides configuration parameters for Docker Containers in Kubernetes within the CDE and hence, the EC2 instance in which Vault sits atop of, would fall with-in scope of PCI compliance.&lt;/p&gt;

&lt;h4 id=&quot;abstracted-service-caveats&quot;&gt;Abstracted Service Caveats&lt;/h4&gt;

&lt;p&gt;Normally, if Abstracted services such as AWS S3 or Application Load Balancer transmits or stores CHD, these services fall with-in scope of PCI compliance. Since these services are considered ‘Abstracted’, network and OS level controls do not apply. If these services do not handle CHD, segmentation is assumed and therefore out of scope for PCI compliance even if located within the same CDE environment.&lt;/p&gt;

&lt;h3 id=&quot;examples&quot;&gt;Examples&lt;/h3&gt;

&lt;p&gt;S3 Bucket without CHD
An S3 bucket with-in the same VPC as the CDE in which no CHD is stored or passes, is not considered part of the CDE.&lt;/p&gt;

&lt;p&gt;S3 Bucket with CHD
An S3 bucket containing CHD would fall with-in scope of PCI compliance however, only pertinent PC requirements would apply such as role-based access controls and not OS layer controls such as anti-virus, etc, essentially controls around data access via the S3 APIs.&lt;/p&gt;

&lt;p&gt;SQS without CHD
If we were to replace Kafka with AWS SQS, we eliminate the use of Infrastructure services in favor of Abstracted Services, as Kafka currently sits atop EC2, therefore, SQS would be out of scope for PCI compliance unless it processes CHD either though it’s connected to the CDE.&lt;/p&gt;

&lt;p&gt;SQS with CHD
If we were to replace Kafka with AWS SQS in which CHD would be stored and transmitted, only those endpoints in which SQS connects would fall with-in scope of PCI even if with-in the same CDE.&lt;/p&gt;

&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Within the newly created AWS PCI Zone, replacing Kubernetes on EC2 with Fargate and possibly Kafka with SQS, would eliminate many of the PCI requirements in that zone as a result of using only. Abstracted and Containerized services as mentioned in the preceding examples above.&lt;/p&gt;
</description>
        <pubDate>Sun, 01 Sep 2019 12:00:00 +0000</pubDate>
        <link>https://adamlechnos.com/grc/pci/2019/09/01/pci-compliance-in-aws-simplified.html</link>
        <guid isPermaLink="true">https://adamlechnos.com/grc/pci/2019/09/01/pci-compliance-in-aws-simplified.html</guid>
        
        
        <category>grc</category>
        
        <category>pci</category>
        
      </item>
    
  </channel>
</rss>
