{"id":1021,"date":"2026-06-04T21:05:54","date_gmt":"2026-06-04T21:05:54","guid":{"rendered":"https:\/\/www.devopsschool.com\/tutorials\/?p=1021"},"modified":"2026-06-04T21:05:55","modified_gmt":"2026-06-04T21:05:55","slug":"complete-tutorial-guide-proxy-identity-aware-proxy-iap-aws-and-azure","status":"publish","type":"post","link":"https:\/\/www.devopsschool.com\/tutorials\/complete-tutorial-guide-proxy-identity-aware-proxy-iap-aws-and-azure\/","title":{"rendered":"Complete Tutorial Guide: Proxy, Identity-Aware Proxy, IAP, AWS, and Azure"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">1. What is a Proxy?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A <strong>proxy<\/strong> is a server that sits between a client and another service.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Instead of this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>User \u2192 Application\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">you get this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>User \u2192 Proxy \u2192 Application\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The proxy receives the user request, checks or modifies it, and then forwards it to the real backend service.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. Types of Proxies<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Proxy type<\/th><th>Direction<\/th><th>Main use<\/th><\/tr><\/thead><tbody><tr><td><strong>Forward proxy<\/strong><\/td><td>Client \u2192 Internet<\/td><td>Used by users\/devices to access external websites through a controlled gateway<\/td><\/tr><tr><td><strong>Reverse proxy<\/strong><\/td><td>Internet\/User \u2192 Internal app<\/td><td>Protects backend apps and exposes a controlled public endpoint<\/td><\/tr><tr><td><strong>Load-balancing proxy<\/strong><\/td><td>User \u2192 Multiple backend servers<\/td><td>Distributes traffic across app servers<\/td><\/tr><tr><td><strong>API gateway<\/strong><\/td><td>Client\/API consumer \u2192 APIs<\/td><td>Authentication, rate limits, API routing, request validation<\/td><\/tr><tr><td><strong>Identity-aware proxy<\/strong><\/td><td>User \u2192 Protected app<\/td><td>Allows access only after identity and policy checks<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Most production \u201cproxy in front of app\u201d designs are <strong>reverse proxies<\/strong>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>flowchart LR\n    U&#91;User Browser] --&gt; P&#91;Reverse Proxy]\n    P --&gt; A1&#91;App Server 1]\n    P --&gt; A2&#91;App Server 2]\n    P --&gt; A3&#91;App Server 3]\n\n    P --&gt; L&#91;Logs \/ Monitoring]\n    P --&gt; W&#91;WAF \/ Security Rules]\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">3. What is Identity-Aware Proxy?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">An <strong>Identity-Aware Proxy<\/strong>, often shortened to <strong>IAP<\/strong>, is a proxy that checks <strong>who the user is<\/strong> before allowing access to an application.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A normal reverse proxy usually asks:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u201cWhere should I route this request?\u201d<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">An Identity-Aware Proxy asks:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u201cWho is this user, are they allowed, is their device trusted, and should this request reach the app?\u201d<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">Google Cloud has a product literally called <strong>Identity-Aware Proxy<\/strong>, which creates a central authorization layer for HTTPS applications and lets teams use application-level access control instead of depending mainly on network-level firewalls. Google describes IAP as a cloud-native alternative to traditional VPNs for apps on services such as Cloud Run, App Engine, Compute Engine, and GKE. (<a href=\"https:\/\/docs.cloud.google.com\/iap\/docs\/concepts-overview?utm_source=chatgpt.com\">Google Cloud Documentation<\/a>)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In AWS and Azure, the same pattern exists, but the product names are different:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Cloud<\/th><th>IAP-style service<\/th><\/tr><\/thead><tbody><tr><td>Google Cloud<\/td><td>Identity-Aware Proxy<\/td><\/tr><tr><td>AWS<\/td><td>AWS Verified Access, or ALB authentication with Cognito\/OIDC<\/td><\/tr><tr><td>Azure<\/td><td>Microsoft Entra Application Proxy, App Service Authentication, Microsoft Entra Private Access<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">4. Why Use Identity-Aware Proxy?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Without IAP:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>flowchart LR\n    U&#91;User] --&gt; VPN&#91;VPN \/ Network Access]\n    VPN --&gt; NET&#91;Private Network]\n    NET --&gt; A&#91;Internal App]\n    NET --&gt; DB&#91;Other Internal Systems]\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The problem: once a user gets into the network, they may have broader network reach than they actually need.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">With IAP:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>flowchart LR\n    U&#91;User] --&gt; IAP&#91;Identity-Aware Proxy]\n    IAP --&gt;|Allowed request only| A&#91;Specific App]\n    IAP -.-&gt;|Denied| D&#91;Blocked]\n\n    IDP&#91;Identity Provider] --&gt; IAP\n    POLICY&#91;Access Policy] --&gt; IAP\n    DEVICE&#91;Device Posture] --&gt; IAP\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The user gets access to <strong>one application<\/strong>, not the whole network.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Key Benefits<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Benefit<\/th><th>Explanation<\/th><\/tr><\/thead><tbody><tr><td><strong>No broad VPN access<\/strong><\/td><td>Users access only the app they are authorized for<\/td><\/tr><tr><td><strong>Central authentication<\/strong><\/td><td>Login is handled by IdP such as Google, Microsoft Entra ID, Okta, Cognito, Auth0<\/td><\/tr><tr><td><strong>Central authorization<\/strong><\/td><td>Rules are managed outside the application<\/td><\/tr><tr><td><strong>MFA support<\/strong><\/td><td>You can require multi-factor authentication before app access<\/td><\/tr><tr><td><strong>Group-based access<\/strong><\/td><td>Allow only specific teams, such as DevOps, Finance, HR, Admin<\/td><\/tr><tr><td><strong>Device-aware access<\/strong><\/td><td>Some platforms can check device compliance, risk, or security posture<\/td><\/tr><tr><td><strong>Better audit logs<\/strong><\/td><td>Access attempts are logged before traffic reaches the backend<\/td><\/tr><tr><td><strong>Legacy app protection<\/strong><\/td><td>Old apps can be protected without rewriting app authentication logic<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">5. How Identity-Aware Proxy Works<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">At a high level:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sequenceDiagram\n    participant User as User Browser\n    participant IAP as Identity-Aware Proxy\n    participant IdP as Identity Provider\n    participant Policy as Policy Engine\n    participant App as Backend App\n\n    User-&gt;&gt;IAP: Request app.example.com\n    IAP-&gt;&gt;IdP: Redirect user to login\n    IdP-&gt;&gt;User: Login page \/ MFA\n    User-&gt;&gt;IdP: Credentials + MFA\n    IdP-&gt;&gt;IAP: Token \/ identity claims\n    IAP-&gt;&gt;Policy: Evaluate user, group, device, request\n    Policy--&gt;&gt;IAP: Allow or deny\n    alt Allowed\n        IAP-&gt;&gt;App: Forward request\n        App--&gt;&gt;IAP: Response\n        IAP--&gt;&gt;User: App response\n    else Denied\n        IAP--&gt;&gt;User: Access denied\n    end\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">IAP Decision Inputs<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Input<\/th><th>Example<\/th><\/tr><\/thead><tbody><tr><td>User identity<\/td><td><code>rajesh@example.com<\/code><\/td><\/tr><tr><td>Group membership<\/td><td><code>DevOps<\/code>, <code>Admins<\/code>, <code>Finance<\/code><\/td><\/tr><tr><td>Device posture<\/td><td>Managed laptop, compliant device, antivirus healthy<\/td><\/tr><tr><td>Location \/ IP<\/td><td>Company region, trusted IP range<\/td><\/tr><tr><td>MFA status<\/td><td>MFA completed or not<\/td><\/tr><tr><td>Request details<\/td><td>HTTP method, path, hostname<\/td><\/tr><tr><td>Time<\/td><td>Business hours only<\/td><\/tr><tr><td>Risk score<\/td><td>Suspicious login, impossible travel, compromised device<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">6. Normal Proxy vs Identity-Aware Proxy<\/h1>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Feature<\/th><th>Reverse Proxy<\/th><th>Identity-Aware Proxy<\/th><\/tr><\/thead><tbody><tr><td>Routes traffic<\/td><td>Yes<\/td><td>Yes<\/td><\/tr><tr><td>TLS termination<\/td><td>Yes<\/td><td>Yes<\/td><\/tr><tr><td>Load balancing<\/td><td>Often<\/td><td>Sometimes<\/td><\/tr><tr><td>User authentication<\/td><td>Usually no<\/td><td>Yes<\/td><\/tr><tr><td>Group-based authorization<\/td><td>Usually no<\/td><td>Yes<\/td><\/tr><tr><td>MFA support<\/td><td>Usually no<\/td><td>Yes, through IdP<\/td><\/tr><tr><td>Device-aware policy<\/td><td>No<\/td><td>Often yes<\/td><\/tr><tr><td>Zero Trust friendly<\/td><td>Limited<\/td><td>Yes<\/td><\/tr><tr><td>Best for internal apps<\/td><td>Sometimes<\/td><td>Yes<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">7. Core Architecture Components<\/h1>\n\n\n\n<pre class=\"wp-block-code\"><code>flowchart TB\n    subgraph UserSide&#91;User Side]\n        U&#91;User Browser]\n        D&#91;User Device]\n    end\n\n    subgraph ControlPlane&#91;Identity and Policy Control Plane]\n        IDP&#91;Identity Provider]\n        MFA&#91;MFA]\n        DIR&#91;User \/ Group Directory]\n        POL&#91;Policy Engine]\n        LOG&#91;Audit Logs]\n    end\n\n    subgraph ProxyLayer&#91;Identity-Aware Proxy Layer]\n        IAP&#91;IAP \/ Access Proxy]\n        WAF&#91;Optional WAF]\n        TLS&#91;TLS Certificate]\n    end\n\n    subgraph AppLayer&#91;Private Application Layer]\n        APP&#91;Internal Web App]\n        API&#91;Internal API]\n        DB&#91;(Database)]\n    end\n\n    U --&gt; IAP\n    D --&gt; IAP\n    IAP --&gt; IDP\n    IDP --&gt; MFA\n    IDP --&gt; DIR\n    IAP --&gt; POL\n    IAP --&gt; LOG\n    IAP --&gt; WAF\n    IAP --&gt; TLS\n    IAP --&gt; APP\n    APP --&gt; API\n    API --&gt; DB\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Components Table<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Component<\/th><th>Purpose<\/th><\/tr><\/thead><tbody><tr><td><strong>User\/browser<\/strong><\/td><td>Makes the request<\/td><\/tr><tr><td><strong>Identity provider<\/strong><\/td><td>Authenticates user<\/td><\/tr><tr><td><strong>Policy engine<\/strong><\/td><td>Decides whether access is allowed<\/td><\/tr><tr><td><strong>IAP\/proxy<\/strong><\/td><td>Enforces the decision<\/td><\/tr><tr><td><strong>Backend app<\/strong><\/td><td>Receives only allowed traffic<\/td><\/tr><tr><td><strong>Audit logs<\/strong><\/td><td>Record allow\/deny events<\/td><\/tr><tr><td><strong>WAF<\/strong><\/td><td>Optional extra layer for web attacks<\/td><\/tr><tr><td><strong>DNS<\/strong><\/td><td>Routes app domain to proxy<\/td><\/tr><tr><td><strong>TLS certificate<\/strong><\/td><td>Secures HTTPS traffic<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">8. Tools to Implement Identity-Aware Proxy<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">Cloud-Native Tools<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Platform<\/th><th>Tool<\/th><th>Best use case<\/th><\/tr><\/thead><tbody><tr><td>Google Cloud<\/td><td>Identity-Aware Proxy<\/td><td>Native IAP for Google Cloud apps and some on-prem\/private apps<\/td><\/tr><tr><td>AWS<\/td><td>AWS Verified Access<\/td><td>Identity-aware access to corporate\/private apps without VPN<\/td><\/tr><tr><td>AWS<\/td><td>Application Load Balancer authentication<\/td><td>Basic web authentication using Cognito or OIDC before forwarding to targets<\/td><\/tr><tr><td>Azure<\/td><td>Microsoft Entra Application Proxy<\/td><td>Publish private\/on-prem web apps with Entra ID authentication<\/td><\/tr><tr><td>Azure<\/td><td>Azure App Service Authentication \/ Easy Auth<\/td><td>Add authentication to App Service, Azure Functions, APIs with little\/no app code<\/td><\/tr><tr><td>Azure<\/td><td>Microsoft Entra Private Access<\/td><td>Broader Zero Trust private access and VPN replacement pattern<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">AWS Verified Access provides secure access to corporate applications without VPN and evaluates requests in real time. AWS also supports authentication directly at Application Load Balancer using Cognito or OIDC before routing to applications. (<a href=\"https:\/\/docs.aws.amazon.com\/verified-access\/?utm_source=chatgpt.com\">AWS Documentation<\/a>)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Microsoft Entra Application Proxy provides secure remote access to on-premises web applications, while Azure App Service Authentication, also called Easy Auth, provides built-in authentication and authorization for App Service and Azure Functions. (<a href=\"https:\/\/learn.microsoft.com\/en-us\/entra\/identity\/app-proxy\/overview-what-is-app-proxy?utm_source=chatgpt.com\">Microsoft Learn<\/a>)<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Open-Source \/ Vendor Tools<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Tool<\/th><th>Type<\/th><th>Notes<\/th><\/tr><\/thead><tbody><tr><td><code>oauth2-proxy<\/code><\/td><td>Open-source reverse proxy<\/td><td>Protects apps using OAuth2\/OIDC authentication<\/td><\/tr><tr><td>Pomerium<\/td><td>Identity-aware proxy<\/td><td>Zero Trust, context-aware access proxy<\/td><\/tr><tr><td>Cloudflare Access<\/td><td>SaaS \/ ZTNA<\/td><td>Identity-based access to private apps<\/td><\/tr><tr><td>Teleport Application Access<\/td><td>Access platform<\/td><td>Identity-aware access for apps, SSH, Kubernetes, databases<\/td><\/tr><tr><td>NGINX + OIDC module\/lua<\/td><td>Reverse proxy pattern<\/td><td>Powerful but needs careful configuration<\/td><\/tr><tr><td>Envoy + external authorization<\/td><td>Service mesh \/ proxy<\/td><td>Advanced pattern for microservices<\/td><\/tr><tr><td>Traefik ForwardAuth<\/td><td>Reverse proxy middleware<\/td><td>Can delegate authentication to another service<\/td><\/tr><tr><td>Authentik<\/td><td>Identity provider + proxy features<\/td><td>Useful in self-hosted environments<\/td><\/tr><tr><td>Authelia<\/td><td>Authentication gateway<\/td><td>Common for homelab\/internal app protection<\/td><\/tr><tr><td>Keycloak<\/td><td>Identity provider<\/td><td>Often paired with oauth2-proxy, NGINX, Pomerium, or custom apps<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><code>oauth2-proxy<\/code> describes itself as a flexible open-source tool that can work as a standalone reverse proxy or middleware for OAuth2\/OIDC authentication. Pomerium describes itself as an identity and context-aware reverse proxy, Cloudflare Access is Cloudflare\u2019s ZTNA product, and Teleport Application Access supports secure access to private applications. (<a href=\"https:\/\/github.com\/oauth2-proxy\/oauth2-proxy?utm_source=chatgpt.com\">GitHub<\/a>)<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">9. Example IAP Use Cases<\/h1>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Use case<\/th><th>Example<\/th><\/tr><\/thead><tbody><tr><td>Protect internal dashboard<\/td><td>Grafana, Kibana, Prometheus, Jenkins<\/td><\/tr><tr><td>Protect admin console<\/td><td><code>\/admin<\/code>, Django admin, Rails admin<\/td><\/tr><tr><td>Protect staging app<\/td><td><code>staging.example.com<\/code><\/td><\/tr><tr><td>Replace VPN for web apps<\/td><td>Give users access to one app, not the network<\/td><\/tr><tr><td>Protect legacy app<\/td><td>App has weak\/no auth, IAP adds modern SSO<\/td><\/tr><tr><td>Contractor access<\/td><td>Allow external partner only to one app<\/td><\/tr><tr><td>Production support access<\/td><td>Require MFA and device compliance for prod tools<\/td><\/tr><tr><td>Secure APIs<\/td><td>Require identity before API requests reach backend<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">10. Example Architecture: Protecting Grafana with IAP<\/h1>\n\n\n\n<pre class=\"wp-block-code\"><code>flowchart LR\n    Dev&#91;Developer] --&gt; DNS&#91;dashboard.company.com]\n    DNS --&gt; IAP&#91;Identity-Aware Proxy]\n    IAP --&gt; IdP&#91;Okta \/ Entra ID \/ Google \/ Cognito]\n    IAP --&gt; Policy&#91;Access Policy: DevOps group only]\n    IAP --&gt; Grafana&#91;Private Grafana]\n    Grafana --&gt; Metrics&#91;(Metrics DB)]\n\n    IAP --&gt; Logs&#91;Audit Logs]\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Policy idea:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Allow access only when:\n- user is authenticated\n- user belongs to DevOps group\n- MFA is completed\n- device is compliant\n- request is for dashboard.company.com\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">11. Implement Identity-Aware Proxy in AWS<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">AWS does not call its service \u201cIAP.\u201d The closest AWS-native equivalent is <strong>AWS Verified Access<\/strong>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">AWS Option A: AWS Verified Access<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Use this when:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Requirement<\/th><th>Good fit?<\/th><\/tr><\/thead><tbody><tr><td>Private corporate app access<\/td><td>Yes<\/td><\/tr><tr><td>Replace VPN for web apps<\/td><td>Yes<\/td><\/tr><tr><td>Identity-aware access<\/td><td>Yes<\/td><\/tr><tr><td>Device-aware access<\/td><td>Yes, depending on provider<\/td><\/tr><tr><td>App should stay private in VPC<\/td><td>Yes<\/td><\/tr><tr><td>Need policy-based access<\/td><td>Yes<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">AWS Verified Access evaluates each request using trust data from identity\/device providers and policies. Verified Access endpoints represent applications, endpoints can inherit group policy, and app-specific endpoint policies can also be attached. Policies are written in Cedar and evaluated against identity\/device trust data. (<a href=\"https:\/\/docs.aws.amazon.com\/verified-access\/latest\/ug\/verified-access-endpoints.html?utm_source=chatgpt.com\">AWS Documentation<\/a>)<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">AWS Verified Access Architecture<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>flowchart TB\n    U&#91;Remote User] --&gt; DNS&#91;app.company.com]\n    DNS --&gt; VA&#91;AWS Verified Access Endpoint]\n\n    subgraph AWS&#91;AWS Account \/ Region]\n        VA --&gt; VG&#91;Verified Access Group]\n        VG --&gt; POL&#91;Cedar Access Policy]\n        VA --&gt; ALB&#91;Internal Application Load Balancer]\n        ALB --&gt; EC2&#91;Private EC2 \/ ECS \/ EKS App]\n    end\n\n    IDP&#91;IAM Identity Center \/ OIDC IdP] --&gt; VA\n    DEVICE&#91;Device Trust Provider] --&gt; VA\n    VA --&gt; LOGS&#91;CloudWatch \/ S3 Logs]\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">AWS Verified Access Components<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Component<\/th><th>Meaning<\/th><\/tr><\/thead><tbody><tr><td><strong>Verified Access instance<\/strong><\/td><td>Main container for Verified Access configuration<\/td><\/tr><tr><td><strong>Trust provider<\/strong><\/td><td>Source of identity or device trust data<\/td><\/tr><tr><td><strong>Verified Access group<\/strong><\/td><td>Logical group of protected apps<\/td><\/tr><tr><td><strong>Verified Access endpoint<\/strong><\/td><td>Represents one protected application<\/td><\/tr><tr><td><strong>Policy<\/strong><\/td><td>Cedar rule deciding allow\/deny<\/td><\/tr><tr><td><strong>Target app<\/strong><\/td><td>ALB, network interface, or private application endpoint<\/td><\/tr><tr><td><strong>Logs<\/strong><\/td><td>Access records for auditing and troubleshooting<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Verified Access trust providers send user\/device context to AWS Verified Access; this context can include user attributes such as email or group membership and device information such as patch or antivirus posture. AWS supports IAM Identity Center as a user-identity trust provider, and it also supports OIDC-based providers. (<a href=\"https:\/\/docs.aws.amazon.com\/verified-access\/latest\/ug\/trust-providers.html?utm_source=chatgpt.com\">AWS Documentation<\/a>)<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">AWS Verified Access Step-by-Step<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Step 1: Prepare the private application<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Example target:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Private EC2\/ECS\/EKS app\n\u2193\nInternal Application Load Balancer\n\u2193\nAWS Verified Access\n\u2193\nPublic HTTPS hostname\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Your backend app should not be directly public. Keep it in private subnets or restrict direct access using security groups.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 2: Configure identity provider<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Common choices:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>IdP<\/th><th>Example<\/th><\/tr><\/thead><tbody><tr><td>AWS IAM Identity Center<\/td><td>Native AWS workforce identity<\/td><\/tr><tr><td>Okta<\/td><td>OIDC\/SAML enterprise login<\/td><\/tr><tr><td>Auth0<\/td><td>OIDC provider<\/td><\/tr><tr><td>Microsoft Entra ID<\/td><td>OIDC\/SAML provider<\/td><\/tr><tr><td>Amazon Cognito<\/td><td>User pool \/ OIDC-style login<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">For the AWS-native path, use IAM Identity Center as a trust provider. AWS notes that IAM Identity Center for Verified Access must be an AWS Organizations instance, not a standalone account instance. (<a href=\"https:\/\/docs.aws.amazon.com\/verified-access\/latest\/ug\/user-trust.html?utm_source=chatgpt.com\">AWS Documentation<\/a>)<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 3: Create Verified Access trust provider<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Conceptually:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Trust Provider:\n  Type: User identity\n  Provider: IAM Identity Center or OIDC\n  Policy reference name: idp\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The <strong>policy reference name<\/strong> matters because it becomes the context key used inside Cedar policies. AWS documentation says that if the policy reference name is <code>idp123<\/code>, the context key becomes <code>context.idp123<\/code>. (<a href=\"https:\/\/docs.aws.amazon.com\/verified-access\/latest\/ug\/trust-data-iam.html?utm_source=chatgpt.com\">AWS Documentation<\/a>)<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 4: Create Verified Access instance<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>Verified Access Instance:\n  Trust provider: idp\n  Logging: enabled\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Step 5: Create Verified Access group<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>Verified Access Group:\n  Name: internal-apps\n  Policy: shared access rules for many apps\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Step 6: Create endpoint for the application<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>Verified Access Endpoint:\n  Domain: app.company.com\n  Type: load balancer\n  Target: internal ALB\n  Certificate: ACM public certificate\n  Group: internal-apps\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">AWS describes a Verified Access endpoint as representing an application. Each endpoint is associated with a Verified Access group and can inherit the group policy. (<a href=\"https:\/\/docs.aws.amazon.com\/verified-access\/latest\/ug\/verified-access-endpoints.html?utm_source=chatgpt.com\">AWS Documentation<\/a>)<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 7: Add access policy<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Example Cedar policy for IAM Identity Center group + verified email:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>permit(principal, action, resource)\nwhen {\n  context.idp.groups has \"c242c5b0-6081-1845-6fa8-6e0d9513c107\" &amp;&amp;\n  context.idp.user.email.verified == true\n};\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Replace:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>idp\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">with your actual policy reference name.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Replace:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>c242c5b0-6081-1845-6fa8-6e0d9513c107\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">with your real IAM Identity Center group ID.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">AWS recommends using IAM Identity Center group IDs rather than group names so the policy does not break when a group name changes. (<a href=\"https:\/\/docs.aws.amazon.com\/verified-access\/latest\/ug\/trust-data-iam-add-pol.html?utm_source=chatgpt.com\">AWS Documentation<\/a>)<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 8: Configure DNS<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Create DNS record:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>app.company.com \u2192 Verified Access endpoint domain\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Step 9: Test access<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Test<\/th><th>Expected result<\/th><\/tr><\/thead><tbody><tr><td>Unauthenticated user opens app<\/td><td>Redirected to IdP<\/td><\/tr><tr><td>Authenticated but wrong group<\/td><td>Denied<\/td><\/tr><tr><td>Correct group + verified email<\/td><td>Allowed<\/td><\/tr><tr><td>Direct backend ALB access<\/td><td>Blocked by security group<\/td><\/tr><tr><td>Policy removed<\/td><td>Denied by default<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">AWS says Verified Access denies application requests by default until a policy is defined.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">12. AWS Option B: Application Load Balancer Authentication<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Use this when you want simpler authentication at the load balancer level.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>flowchart LR\n    User&#91;User] --&gt; ALB&#91;Public ALB with Auth Rule]\n    ALB --&gt; Cognito&#91;Amazon Cognito \/ OIDC IdP]\n    ALB --&gt; TG&#91;Target Group]\n    TG --&gt; App&#91;EC2 \/ ECS \/ EKS App]\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">AWS Application Load Balancer can authenticate users using corporate or social identities before routing requests to applications. It can integrate with Amazon Cognito or an OIDC provider. (<a href=\"https:\/\/docs.aws.amazon.com\/elasticloadbalancing\/latest\/application\/listener-authenticate-users.html?utm_source=chatgpt.com\">AWS Documentation<\/a>)<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">ALB Auth vs Verified Access<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Feature<\/th><th>ALB Authentication<\/th><th>AWS Verified Access<\/th><\/tr><\/thead><tbody><tr><td>Basic login before app<\/td><td>Yes<\/td><td>Yes<\/td><\/tr><tr><td>OIDC\/Cognito support<\/td><td>Yes<\/td><td>Yes<\/td><\/tr><tr><td>Central Zero Trust policy<\/td><td>Limited<\/td><td>Stronger<\/td><\/tr><tr><td>Device posture<\/td><td>No \/ limited<\/td><td>Supported via trust providers<\/td><\/tr><tr><td>Private-app VPN replacement<\/td><td>Not as complete<\/td><td>Yes<\/td><\/tr><tr><td>Best for<\/td><td>Simple web login<\/td><td>Enterprise app access<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">AWS ALB Authentication Steps<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Create an Amazon Cognito user pool or use OIDC provider.<\/li>\n\n\n\n<li>Create an Application Load Balancer.<\/li>\n\n\n\n<li>Create HTTPS listener.<\/li>\n\n\n\n<li>Add listener rule: authenticate first, then forward to target group.<\/li>\n\n\n\n<li>Configure callback URL in IdP\/Cognito.<\/li>\n\n\n\n<li>Restrict backend security group so only ALB can reach the app.<\/li>\n\n\n\n<li>Test login and logout behavior.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">AWS recommends special CloudFront forwarding behavior if CloudFront is placed in front of an authenticated ALB, including forwarding all request headers to avoid cached authenticated responses being served after session expiry. (<a href=\"https:\/\/docs.aws.amazon.com\/elasticloadbalancing\/latest\/application\/listener-authenticate-users.html?utm_source=chatgpt.com\">AWS Documentation<\/a>)<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">13. Implement Identity-Aware Proxy in Azure<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Azure has several IAP-style patterns. Choose based on where the app runs.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Azure Decision Table<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>App location<\/th><th>Best Azure option<\/th><\/tr><\/thead><tbody><tr><td>Azure App Service \/ Azure Functions<\/td><td>App Service Authentication \/ Easy Auth<\/td><\/tr><tr><td>On-premises private web app<\/td><td>Microsoft Entra Application Proxy<\/td><\/tr><tr><td>Broad private access \/ VPN replacement<\/td><td>Microsoft Entra Private Access<\/td><\/tr><tr><td>Kubernetes \/ containers<\/td><td>Ingress + Entra ID\/OIDC, or external IAP tool<\/td><\/tr><tr><td>Public app needing WAF + auth<\/td><td>App Gateway\/Front Door + app-level auth or Easy Auth<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">14. Azure Option A: Microsoft Entra Application Proxy<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Use this when your app is on-premises or private, and you want remote users to access it without opening inbound firewall ports.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Microsoft Entra Application Proxy provides secure remote access to on-premises web apps. Microsoft says users can access on-premises apps through an external URL or internal application portal after SSO to Microsoft Entra ID. (<a href=\"https:\/\/learn.microsoft.com\/en-us\/entra\/identity\/app-proxy\/overview-what-is-app-proxy?utm_source=chatgpt.com\">Microsoft Learn<\/a>)<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Azure Application Proxy Architecture<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>flowchart TB\n    U&#91;Remote User] --&gt; URL&#91;External URL]\n    URL --&gt; ENTRA&#91;Microsoft Entra ID Login]\n    ENTRA --&gt; CAP&#91;Conditional Access \/ MFA]\n    CAP --&gt; APPSVC&#91;Application Proxy Cloud Service]\n\n    subgraph PrivateNetwork&#91;Private Network \/ On-Prem]\n        CONN&#91;Private Network Connector]\n        APP&#91;Internal Web App]\n    end\n\n    APPSVC --&gt; CONN\n    CONN --&gt; APP\n\n    ENTRA --&gt; LOGS&#91;Sign-in Logs \/ Audit Logs]\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">How Azure Application Proxy Works<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>sequenceDiagram\n    participant User\n    participant Entra as Microsoft Entra ID\n    participant Proxy as App Proxy Service\n    participant Connector as Private Network Connector\n    participant App as On-Prem App\n\n    User-&gt;&gt;Proxy: Open external app URL\n    Proxy-&gt;&gt;Entra: Redirect for sign-in\n    Entra-&gt;&gt;User: Login + MFA \/ Conditional Access\n    User-&gt;&gt;Proxy: Sends token after successful sign-in\n    Proxy-&gt;&gt;Connector: Forward authorized request\n    Connector-&gt;&gt;App: Send request to internal app\n    App--&gt;&gt;Connector: App response\n    Connector--&gt;&gt;Proxy: Return response\n    Proxy--&gt;&gt;User: Show app\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Microsoft explains that Application Proxy includes a cloud service and a private network connector installed on an on-premises server. The connector uses outbound connections, so you do not need to open inbound firewall ports. (<a href=\"https:\/\/learn.microsoft.com\/en-us\/entra\/identity\/app-proxy\/overview-what-is-app-proxy?utm_source=chatgpt.com\">Microsoft Learn<\/a>)<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Azure Application Proxy Step-by-Step<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Step 1: Prepare prerequisites<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Requirement<\/th><th>Example<\/th><\/tr><\/thead><tbody><tr><td>Microsoft Entra tenant<\/td><td>Your Azure\/Entra organization<\/td><\/tr><tr><td>App Proxy license support<\/td><td>Depends on tenant licensing<\/td><\/tr><tr><td>Windows Server for connector<\/td><td>Server with network access to internal app<\/td><\/tr><tr><td>Internal app URL<\/td><td><code>http:\/\/intranet.local<\/code><\/td><\/tr><tr><td>External app URL<\/td><td><code>https:\/\/intranet-company.msappproxy.net<\/code> or custom domain<\/td><\/tr><tr><td>Users\/groups<\/td><td><code>Finance<\/code>, <code>DevOps<\/code>, <code>Support<\/code><\/td><\/tr><tr><td>Conditional Access<\/td><td>MFA, compliant device, location rule<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Step 2: Install private network connector<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Install the Microsoft Entra private network connector on a Windows Server that can reach the internal application.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The connector should be placed close to the app network. For production, use at least two connectors for high availability.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Microsoft notes that connectors are lightweight agents installed inside the private network. Connectors create outbound connections to Application Proxy and Private Access services, and connector groups can be used for high availability and traffic routing. (<a href=\"https:\/\/learn.microsoft.com\/en-us\/entra\/global-secure-access\/concept-connectors?utm_source=chatgpt.com\">Microsoft Learn<\/a>)<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 3: Publish the internal application<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">In Microsoft Entra admin center:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Enterprise applications\n\u2192 New application\n\u2192 On-premises application\n\u2192 Configure Application Proxy\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Example settings:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Setting<\/th><th>Example<\/th><\/tr><\/thead><tbody><tr><td>Name<\/td><td>Internal Grafana<\/td><\/tr><tr><td>Internal URL<\/td><td><code>http:\/\/grafana.internal:3000<\/code><\/td><\/tr><tr><td>External URL<\/td><td><code>https:\/\/grafana-company.msappproxy.net<\/code><\/td><\/tr><tr><td>Pre-authentication<\/td><td>Microsoft Entra ID<\/td><\/tr><tr><td>Connector group<\/td><td>Production-Connectors<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Microsoft\u2019s tutorial for Application Proxy covers installing\/verifying the connector and adding an on-premises application to the Microsoft Entra tenant. (<a href=\"https:\/\/learn.microsoft.com\/en-us\/entra\/identity\/app-proxy\/application-proxy-add-on-premises-application?utm_source=chatgpt.com\">Microsoft Learn<\/a>)<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 4: Assign users or groups<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Assign only the users\/groups that need access:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Users and groups:\n- DevOps\n- SRE\n- Platform Admins\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Step 5: Add Conditional Access<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Example policy:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>For app: Internal Grafana\nGrant access only when:\n- User is in DevOps group\n- MFA completed\n- Device is compliant\n- Sign-in risk is low\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Microsoft says Application Proxy can use Microsoft Entra Conditional Access, allowing richer policy controls before connections to the private network are established. (<a href=\"https:\/\/learn.microsoft.com\/en-us\/entra\/identity\/app-proxy\/application-proxy-security?utm_source=chatgpt.com\">Microsoft Learn<\/a>)<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 6: Test<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Test<\/th><th>Expected result<\/th><\/tr><\/thead><tbody><tr><td>User not assigned<\/td><td>Access denied<\/td><\/tr><tr><td>Assigned user without MFA<\/td><td>MFA challenge<\/td><\/tr><tr><td>Assigned user with MFA<\/td><td>App opens<\/td><\/tr><tr><td>Connector stopped<\/td><td>App unavailable<\/td><\/tr><tr><td>Internal app down<\/td><td>Proxy reachable but backend fails<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">15. Azure Option B: Azure App Service Authentication \/ Easy Auth<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Use this when your application runs on:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Azure App Service\nAzure Functions\nAzure Web App\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Azure App Service provides built-in authentication and authorization, commonly called <strong>Easy Auth<\/strong>, and Microsoft says it can help secure web apps, REST APIs, mobile backends, and functions with little or no code. (<a href=\"https:\/\/learn.microsoft.com\/en-us\/azure\/app-service\/overview-authentication-authorization?utm_source=chatgpt.com\">Microsoft Learn<\/a>)<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Easy Auth Architecture<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>flowchart LR\n    User&#91;User Browser] --&gt; AppSvc&#91;Azure App Service]\n    AppSvc --&gt; Entra&#91;Microsoft Entra ID \/ Other IdP]\n    AppSvc --&gt; App&#91;Your Application Code]\n    App --&gt; API&#91;Backend API]\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Easy Auth Step-by-Step<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open your Azure App Service.<\/li>\n\n\n\n<li>Go to <strong>Authentication<\/strong>.<\/li>\n\n\n\n<li>Add identity provider.<\/li>\n\n\n\n<li>Choose Microsoft Entra ID or another IdP.<\/li>\n\n\n\n<li>Configure unauthenticated requests:\n<ul class=\"wp-block-list\">\n<li>Redirect to login, or<\/li>\n\n\n\n<li>Return HTTP 401.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Restrict app access to selected users\/groups through Entra enterprise application assignment.<\/li>\n\n\n\n<li>Add Conditional Access if required.<\/li>\n\n\n\n<li>Test login.<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Easy Auth vs Application Proxy<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Feature<\/th><th>Easy Auth<\/th><th>Entra Application Proxy<\/th><\/tr><\/thead><tbody><tr><td>Protect Azure App Service<\/td><td>Excellent<\/td><td>Not usually needed<\/td><\/tr><tr><td>Protect on-prem app<\/td><td>No<\/td><td>Yes<\/td><\/tr><tr><td>Requires connector<\/td><td>No<\/td><td>Yes<\/td><\/tr><tr><td>Little\/no app code<\/td><td>Yes<\/td><td>Yes<\/td><\/tr><tr><td>Best for<\/td><td>Azure-hosted apps<\/td><td>Private\/on-prem apps<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">16. Azure Option C: Microsoft Entra Private Access<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Use this for a broader VPN-replacement architecture.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Microsoft Entra Private Access is part of Global Secure Access and provides granular access to private resources. Microsoft describes it as a way to replace VPN-style access using Conditional Access controls. (<a href=\"https:\/\/learn.microsoft.com\/en-us\/entra\/global-secure-access\/concept-private-access?utm_source=chatgpt.com\">Microsoft Learn<\/a>)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>flowchart TB\n    User&#91;User Device] --&gt; GSA&#91;Global Secure Access Client]\n    GSA --&gt; Entra&#91;Microsoft Entra ID]\n    Entra --&gt; CA&#91;Conditional Access]\n    GSA --&gt; PrivateAccess&#91;Microsoft Entra Private Access]\n\n    subgraph PrivateNetwork&#91;Private Network]\n        Connector&#91;Private Network Connector]\n        App1&#91;Private Web App]\n        App2&#91;Private TCP App]\n        DB&#91;Internal Resource]\n    end\n\n    PrivateAccess --&gt; Connector\n    Connector --&gt; App1\n    Connector --&gt; App2\n    Connector --&gt; DB\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Use this when you need access to multiple private apps\/resources, not only one web app.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">17. Advanced Identity-Aware Proxy Patterns<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">Pattern 1: Protect only <code>\/admin<\/code><\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>flowchart LR\n    User --&gt; Proxy\n    Proxy --&gt;|\/public| PublicApp&#91;Public App]\n    Proxy --&gt;|\/admin requires login| IAP&#91;IAP Auth]\n    IAP --&gt; AdminApp&#91;Admin Backend]\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Path<\/th><th>Auth required?<\/th><\/tr><\/thead><tbody><tr><td><code>\/<\/code><\/td><td>No<\/td><\/tr><tr><td><code>\/docs<\/code><\/td><td>No<\/td><\/tr><tr><td><code>\/admin<\/code><\/td><td>Yes<\/td><\/tr><tr><td><code>\/metrics<\/code><\/td><td>Yes<\/td><\/tr><tr><td><code>\/api\/internal<\/code><\/td><td>Yes<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Pattern 2: Multiple apps, one access layer<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>flowchart TB\n    User --&gt; IAP&#91;Central IAP]\n\n    IAP --&gt; Grafana&#91;Grafana]\n    IAP --&gt; Jenkins&#91;Jenkins]\n    IAP --&gt; Kibana&#91;Kibana]\n    IAP --&gt; Admin&#91;Admin Portal]\n\n    IDP&#91;Identity Provider] --&gt; IAP\n    Policy&#91;Central Policies] --&gt; IAP\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Pattern 3: Device-aware access<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>flowchart LR\n    User --&gt; IAP\n    IAP --&gt; IdP&#91;Identity Provider]\n    IAP --&gt; Device&#91;Device Trust Provider]\n    IAP --&gt; Policy&#91;Policy Engine]\n    Policy --&gt; Decision{Allow?}\n    Decision --&gt;|Yes| App\n    Decision --&gt;|No| Deny&#91;Access Denied]\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Policy:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Allow only when:\n- user is in Admin group\n- MFA is complete\n- laptop is managed\n- device risk is low\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Pattern 4: IAP + WAF<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>flowchart LR\n    User --&gt; WAF&#91;Web Application Firewall]\n    WAF --&gt; IAP&#91;Identity-Aware Proxy]\n    IAP --&gt; App&#91;Private App]\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Use this when the app is exposed to the internet and you also want protection against common web attacks.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">18. Security Best Practices<\/h1>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Area<\/th><th>Best practice<\/th><\/tr><\/thead><tbody><tr><td>Identity<\/td><td>Use SSO with Entra ID, Okta, Google, Cognito, or IAM Identity Center<\/td><\/tr><tr><td>MFA<\/td><td>Require MFA for sensitive apps<\/td><\/tr><tr><td>Groups<\/td><td>Grant access through groups, not individual users<\/td><\/tr><tr><td>Least privilege<\/td><td>Give users access only to required apps<\/td><\/tr><tr><td>Backend exposure<\/td><td>Do not allow direct public access to backend app<\/td><\/tr><tr><td>TLS<\/td><td>Use HTTPS everywhere<\/td><\/tr><tr><td>Logging<\/td><td>Enable access logs and sign-in logs<\/td><\/tr><tr><td>WAF<\/td><td>Add WAF for public-facing apps<\/td><\/tr><tr><td>Device posture<\/td><td>Require compliant devices for production\/admin apps<\/td><\/tr><tr><td>Break-glass access<\/td><td>Maintain emergency admin access with strong controls<\/td><\/tr><tr><td>Session duration<\/td><td>Use shorter sessions for sensitive apps<\/td><\/tr><tr><td>Secrets<\/td><td>Do not pass long-lived secrets in headers<\/td><\/tr><tr><td>Headers<\/td><td>Trust identity headers only from the proxy, never from public internet<\/td><\/tr><tr><td>Testing<\/td><td>Test denied cases, not only allowed cases<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">19. Common Mistakes<\/h1>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Mistake<\/th><th>Why it is dangerous<\/th><\/tr><\/thead><tbody><tr><td>Backend app is still public<\/td><td>Attackers can bypass IAP<\/td><\/tr><tr><td>Trusting user-supplied headers<\/td><td>User can spoof identity headers<\/td><\/tr><tr><td>No MFA<\/td><td>Stolen password can become full access<\/td><\/tr><tr><td>Assigning access to everyone<\/td><td>Defeats the purpose of IAP<\/td><\/tr><tr><td>Using passthrough authentication accidentally<\/td><td>Proxy may not authenticate users first<\/td><\/tr><tr><td>No logs<\/td><td>Hard to investigate incidents<\/td><\/tr><tr><td>No health checks<\/td><td>Outages become confusing<\/td><\/tr><tr><td>Long sessions<\/td><td>Compromised sessions last too long<\/td><\/tr><tr><td>No separate admin policy<\/td><td>Admin apps need stricter policy<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">For Azure Application Proxy specifically, Microsoft warns that choosing passthrough preauthentication does not provide the same benefit as Microsoft Entra preauthentication, because anonymous traffic is not blocked before reaching the backend path. (<a href=\"https:\/\/learn.microsoft.com\/en-us\/entra\/identity\/app-proxy\/application-proxy-security?utm_source=chatgpt.com\">Microsoft Learn<\/a>)<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">20. Troubleshooting Checklist<\/h1>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Symptom<\/th><th>Possible cause<\/th><th>Fix<\/th><\/tr><\/thead><tbody><tr><td>User gets access denied<\/td><td>Not assigned to app\/group<\/td><td>Add user\/group<\/td><\/tr><tr><td>Infinite login loop<\/td><td>Redirect URI mismatch<\/td><td>Fix callback\/external URL<\/td><\/tr><tr><td>App loads but assets fail<\/td><td>App uses absolute internal URLs<\/td><td>Configure link translation \/ app base URL<\/td><\/tr><tr><td>Backend unavailable<\/td><td>Connector\/ALB\/app down<\/td><td>Check health and routing<\/td><\/tr><tr><td>Everyone can access<\/td><td>Policy too broad<\/td><td>Tighten groups\/MFA\/device rules<\/td><\/tr><tr><td>Direct backend access works<\/td><td>Backend exposed publicly<\/td><td>Restrict security group\/firewall<\/td><\/tr><tr><td>User authenticated but app does not know user<\/td><td>Missing identity headers\/token handling<\/td><td>Configure trusted headers or app token validation<\/td><\/tr><tr><td>AWS policy denies everyone<\/td><td>Wrong policy reference name<\/td><td>Match Cedar context key to trust provider policy reference<\/td><\/tr><tr><td>Azure connector offline<\/td><td>Connector service stopped\/outbound blocked<\/td><td>Check connector health and outbound 80\/443<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">21. Recommended Learning Path<\/h1>\n\n\n\n<pre class=\"wp-block-code\"><code>flowchart TD\n    A&#91;Learn proxy basics] --&gt; B&#91;Learn reverse proxy]\n    B --&gt; C&#91;Learn SSO: SAML \/ OIDC]\n    C --&gt; D&#91;Learn MFA and Conditional Access]\n    D --&gt; E&#91;Learn IAP architecture]\n    E --&gt; F&#91;Implement one small internal app]\n    F --&gt; G&#91;Add group-based policy]\n    G --&gt; H&#91;Add device\/MFA policy]\n    H --&gt; I&#91;Add logging and alerting]\n    I --&gt; J&#91;Roll out production pattern]\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">22. Final Summary<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">An <strong>Identity-Aware Proxy<\/strong> is a secure gatekeeper in front of your application. It checks identity, group membership, MFA, device posture, and policy before allowing traffic to reach the backend.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For production:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Environment<\/th><th>Recommended implementation<\/th><\/tr><\/thead><tbody><tr><td>Google Cloud<\/td><td>Google Cloud IAP<\/td><\/tr><tr><td>AWS private apps<\/td><td>AWS Verified Access<\/td><\/tr><tr><td>AWS simple web auth<\/td><td>ALB authentication with Cognito\/OIDC<\/td><\/tr><tr><td>Azure App Service<\/td><td>App Service Authentication \/ Easy Auth<\/td><\/tr><tr><td>Azure on-prem\/private web apps<\/td><td>Microsoft Entra Application Proxy<\/td><\/tr><tr><td>Azure VPN replacement<\/td><td>Microsoft Entra Private Access<\/td><\/tr><tr><td>Self-hosted\/Kubernetes<\/td><td>oauth2-proxy, Pomerium, NGINX + OIDC, Envoy, Traefik ForwardAuth<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The core idea is simple:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Do not expose the app directly.\nExpose the proxy.\nAuthenticate the user.\nEvaluate policy.\nForward only allowed requests.\nLog everything.\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>1. What is a Proxy? A proxy is a server that sits between a client and another service. Instead of this: you get this: The proxy receives&#8230; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1021","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts\/1021","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/comments?post=1021"}],"version-history":[{"count":1,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts\/1021\/revisions"}],"predecessor-version":[{"id":1022,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts\/1021\/revisions\/1022"}],"wp:attachment":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/media?parent=1021"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/categories?post=1021"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/tags?post=1021"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}