Introduction — Why Identity-Aware Proxy, Why Now
As of 2026, the assumption that "anything on the corporate network can be trusted" is effectively a retired security model. Remote work is the norm, workloads are scattered across multiple clouds, and the line between SaaS and internal tooling has blurred. On top of that, AI agents now access internal systems on behalf of humans. Identity-first security — verifying "who (or what) is accessing, in what context" on every single request — has become the default posture.
This post covers the Identity-Aware Proxy (IAP), the most tangible implementation of Zero Trust. We will study the model laid out in Google BeyondCorp papers, then build an IAP ourselves by combining oauth2-proxy with [Keycloak](https://www.keycloak.org/documentation), down to the level of complete YAML and configuration files. At the end we compare commercial and open-source alternatives such as Cloudflare Access, Google Cloud IAP, and Pomerium, lay out a phased adoption roadmap, and look at access control in the age of AI agents.
The End of Perimeter Security and the Rise of Identity-First
The Limits of the Castle-and-Moat Model
Traditional network security is often described as the castle-and-moat model. You build a perimeter with firewalls and a VPN, and once traffic gets inside, it enjoys broad trust. The problems with this model are well known.
- Once an attacker breaches the perimeter (phishing, stolen VPN credentials, an exploit), lateral movement inside is largely unconstrained.
- A VPN grants access to an entire network. A contractor who needs a single app effectively gets the whole corporate LAN.
- Location-based trust loses all meaning with remote work, BYOD, and multi-cloud environments.
- The model is defenseless against insider threats and compromised endpoints.
Core Principles of Zero Trust
Zero Trust, standardized in NIST SP 800-207, boils down to the following principles.
1. **Network location is not a basis for trust** — the corporate LAN and a coffee-shop Wi-Fi are treated identically.
2. **Every access must be authenticated and authorized** — verified per request, not per session.
3. **Least privilege** — users and devices get access only to the resources their work requires.
4. **Dynamic, context-based policy** — decisions combine user identity, device state, location, time, and more.
5. **Continuous verification** — passing once is not the end; access is re-evaluated whenever signals change.
The component that implements these principles at the HTTP application layer is the Identity-Aware Proxy.
The Core of the BeyondCorp Papers
After the Operation Aurora breach in 2009, Google started the BeyondCorp project: phase out the corporate VPN, expose every internal application to the internet, and protect them all behind an access proxy. The key components from the [BeyondCorp paper series](https://research.google/pubs/pub43231/) are as follows.
- **Access Proxy** — a reverse proxy in front of every application. TLS termination, authentication, and authorization are handled centrally.
- **Device Inventory Database** — tracks the state of every company-managed device (OS version, patch level, disk encryption).
- **User/Group Database** — an identity store synchronized with HR systems.
- **Trust Inference** — dynamically computes a trust tier by combining user and device signals.
- **Access Control Engine** — decides via policy whether "this user, on this device, may access this application."
BeyondCorp left two lessons that matter most. First, **pulling authentication and authorization out of applications and centralizing them at a proxy layer** lets you raise the security baseline of hundreds of internal apps at once. Second, **user identity alone is not enough — device trust must be evaluated alongside it**.
How an IAP Works — Authentication and Authorization on Every Request
The operation of an IAP fits on a single diagram.
+----------------------------+
| Identity Provider (IdP) |
| Keycloak / OIDC |
+-------------+--------------+
| (2) OIDC authentication
| Authorization Code + PKCE
+----------+ (1) HTTPS +----------+-----------+ (4) inject headers +-------------+
| User +-------------->+ Identity-Aware Proxy +--------------------->+ Internal |
| browser | | (oauth2-proxy etc.) | X-Forwarded-* | app |
+----------+ +----------+-----------+ +-------------+
|
| (3) policy evaluation
| - user groups/roles
| - device state
| - location/time context
v
+----------------------+
| Policy / Device DB |
+----------------------+
Step by step, request processing looks like this.
1. When a user hits the URL of a protected app, the request must pass through the IAP. Direct access bypassing the IAP is blocked at the network policy level.
2. If there is no valid session, the IAP delegates authentication to the IdP using the OIDC Authorization Code Flow with PKCE.
3. Once authenticated, the IAP evaluates authorization policy using claims from the ID token (groups, roles) plus additional context (device, IP, time).
4. Only requests that pass get user identity headers (or a signed JWT) attached and are forwarded upstream.
5. This process repeats **on every request** even after the initial login, in the form of session cookie validation and policy re-evaluation. Sessions are kept short, and each refresh pulls the latest IdP state (account disabled, group changes).
The contrast with a traditional VPN, in table form:
| Aspect | VPN | Identity-Aware Proxy |
| ---------------- | ------------------------------ | ---------------------------------------- |
| Unit of trust | Network (once in, you are in) | Request (authn/authz every time) |
| Access scope | Whole LAN or subnets | Per application |
| Authz criteria | IP, account | Identity + groups + device + context |
| Visibility | Tunnel interior is opaque | Per-request audit logs |
| User experience | Client install, disconnections | SSO with just a browser |
| L3/L4 support | Yes | HTTP by default; TCP needs other tooling |
Hands-On — Building an IAP with oauth2-proxy + Keycloak
Let us build one. The setup:
- IdP: Keycloak 26.6 (26.6.2 is current as of May 2026, including passkeys login integration and final FAPI 2.0 support)
- IAP: [oauth2-proxy](https://oauth2-proxy.github.io/oauth2-proxy/) 7.x
- Reverse proxy: nginx ingress (auth_request pattern)
- Target: an internal admin dashboard deployed on Kubernetes
Step 1 — Configure the Keycloak Client
First, create a confidential client for oauth2-proxy in Keycloak. We assume a realm named internal. Using the Keycloak Admin CLI (kcadm):
Log in with the Keycloak admin CLI
kcadm.sh config credentials \
--server https://keycloak.example.com \
--realm master \
--user admin
Create the client for oauth2-proxy
kcadm.sh create clients -r internal -f - <<'EOF'
{
"clientId": "oauth2-proxy",
"protocol": "openid-connect",
"publicClient": false,
"standardFlowEnabled": true,
"directAccessGrantsEnabled": false,
"serviceAccountsEnabled": false,
"redirectUris": ["https://admin.example.com/oauth2/callback"],
"attributes": {
"pkce.code.challenge.method": "S256",
"post.logout.redirect.uris": "https://admin.example.com"
}
}
EOF
Add a groups claim mapper so that group membership is carried in the tokens.
Mapper that puts a groups claim into the ID token
CLIENT_UUID=$(kcadm.sh get clients -r internal -q clientId=oauth2-proxy --fields id --format csv --noquotes)
kcadm.sh create clients/$CLIENT_UUID/protocol-mappers/models -r internal -f - <<'EOF'
{
"name": "groups",
"protocol": "openid-connect",
"protocolMapper": "oidc-group-membership-mapper",
"config": {
"claim.name": "groups",
"full.path": "false",
"id.token.claim": "true",
"access.token.claim": "true",
"userinfo.token.claim": "true"
}
}
EOF
Since Keycloak 26.6 integrates passkeys into the login form with a conditional UI, enabling the WebAuthn Passwordless policy in the internal realm authentication flow makes passwordless primary authentication the default. In Zero Trust, a phishing-resistant authenticator is practically mandatory (see [WebAuthn Level 3](https://www.w3.org/TR/webauthn-3/) and [FIDO passkeys](https://fidoalliance.org/passkeys/)).
Step 2 — Deploy oauth2-proxy
Deploy oauth2-proxy to Kubernetes. The full manifest:
apiVersion: v1
kind: Secret
metadata:
name: oauth2-proxy-secrets
namespace: iap
type: Opaque
stringData:
client-secret: 'REPLACE_WITH_KEYCLOAK_CLIENT_SECRET'
python -c 'import secrets; print(secrets.token_urlsafe(32))'
cookie-secret: 'REPLACE_WITH_32_BYTE_RANDOM'
apiVersion: apps/v1
kind: Deployment
metadata:
name: oauth2-proxy
namespace: iap
labels:
app: oauth2-proxy
spec:
replicas: 2
selector:
matchLabels:
app: oauth2-proxy
template:
metadata:
labels:
app: oauth2-proxy
spec:
containers:
- name: oauth2-proxy
image: quay.io/oauth2-proxy/oauth2-proxy:v7.8.1
args:
- --provider=keycloak-oidc
- --client-id=oauth2-proxy
- --oidc-issuer-url=https://keycloak.example.com/realms/internal
- --code-challenge-method=S256
- --redirect-url=https://admin.example.com/oauth2/callback
- --email-domain=example.com
- --allowed-group=platform-admins
- --scope=openid email profile groups
- --cookie-secure=true
- --cookie-samesite=lax
- --cookie-refresh=4m
- --cookie-expire=8h
- --session-store-type=redis
- --redis-connection-url=redis://redis.iap.svc.cluster.local:6379
- --set-xauthrequest=true
- --set-authorization-header=true
- --pass-access-token=false
- --skip-provider-button=true
- --reverse-proxy=true
- --http-address=0.0.0.0:4180
- --metrics-address=0.0.0.0:44180
env:
- name: OAUTH2_PROXY_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: oauth2-proxy-secrets
key: client-secret
- name: OAUTH2_PROXY_COOKIE_SECRET
valueFrom:
secretKeyRef:
name: oauth2-proxy-secrets
key: cookie-secret
ports:
- containerPort: 4180
name: http
- containerPort: 44180
name: metrics
readinessProbe:
httpGet:
path: /ping
port: 4180
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
memory: 256Mi
apiVersion: v1
kind: Service
metadata:
name: oauth2-proxy
namespace: iap
spec:
selector:
app: oauth2-proxy
ports:
- name: http
port: 4180
targetPort: 4180
Things worth highlighting in this configuration:
- **code-challenge-method=S256** — applies PKCE, which the OAuth 2.1 draft effectively mandates, even to confidential clients ([RFC 7636](https://datatracker.ietf.org/doc/html/rfc7636), [draft-ietf-oauth-v2-1](https://datatracker.ietf.org/doc/draft-ietf-oauth-v2-1/)).
- **allowed-group=platform-admins** — first-pass authorization at the proxy based on Keycloak groups.
- **cookie-refresh=4m** — refreshes the session via refresh token every 4 minutes, pulling in the latest IdP state. A disabled account loses access within minutes.
- **session-store-type=redis** — stores sessions in Redis instead of stuffing whole tokens into cookies, mitigating cookie size limits and token exposure.
- **set-xauthrequest=true** — lets the nginx auth_request response carry X-Auth-Request-User, X-Auth-Request-Email, and X-Auth-Request-Groups headers for the upstream.
Step 3 — Wiring Up the nginx auth_request Pattern
The nginx auth_request directive means "before handling the main request, send a subrequest to check authentication." It is the glue of the IAP pattern.
server {
listen 443 ssl;
server_name admin.example.com;
ssl_certificate /etc/nginx/tls/tls.crt;
ssl_certificate_key /etc/nginx/tls/tls.key;
Auth check subrequest — oauth2-proxy /oauth2/auth returns
202 when authenticated, 401 otherwise
location = /oauth2/auth {
internal;
proxy_pass http://oauth2-proxy.iap.svc.cluster.local:4180;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
No need to forward the body
proxy_pass_request_body off;
proxy_set_header Content-Length "";
}
Login flow (redirects, callback, logout)
location /oauth2/ {
proxy_pass http://oauth2-proxy.iap.svc.cluster.local:4180;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
}
location / {
auth_request /oauth2/auth;
On 401, redirect to login
error_page 401 = /oauth2/start?rd=$scheme://$host$request_uri;
Pull identity from the auth subrequest response headers
and inject it for the upstream
auth_request_set $user $upstream_http_x_auth_request_user;
auth_request_set $email $upstream_http_x_auth_request_email;
auth_request_set $groups $upstream_http_x_auth_request_groups;
proxy_set_header X-Forwarded-User $user;
proxy_set_header X-Forwarded-Email $email;
proxy_set_header X-Forwarded-Groups $groups;
Keep this structure so user-forged identity headers
are always overwritten by proxy_set_header above
proxy_pass http://admin-dashboard.apps.svc.cluster.local:8080;
}
}
If you use Kubernetes ingress-nginx, the same pattern is expressed with annotations.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: admin-dashboard
namespace: apps
annotations:
nginx.ingress.kubernetes.io/auth-url: 'https://admin.example.com/oauth2/auth'
nginx.ingress.kubernetes.io/auth-signin: 'https://admin.example.com/oauth2/start?rd=$scheme://$host$request_uri'
nginx.ingress.kubernetes.io/auth-response-headers: 'X-Auth-Request-User, X-Auth-Request-Email, X-Auth-Request-Groups'
spec:
ingressClassName: nginx
rules:
- host: admin.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: admin-dashboard
port:
number: 8080
tls:
- hosts:
- admin.example.com
secretName: admin-dashboard-tls
Step 4 — Blocking Proxy Bypass
An IAP is neutralized if even one bypass path exists. Use a NetworkPolicy to force the upstream app to accept traffic only from the ingress controller.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: admin-dashboard-only-from-ingress
namespace: apps
spec:
podSelector:
matchLabels:
app: admin-dashboard
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: ingress-nginx
ports:
- protocol: TCP
port: 8080
In addition, the upstream app must verify "did this request really come from the proxy" before trusting identity headers. The most robust approach is to receive a signed ID token (JWT) via oauth2-proxy with set-authorization-header and verify the signature in the app. An architecture that trusts plain headers alone is forgeable if the internal network is ever compromised.
Device Trust and Context-Based Policy
Half of the BeyondCorp model is device trust. No matter how strong user authentication is, a malware-infected endpoint should have restricted access. Practical, incremental approaches:
1. **mTLS client certificates** — distribute client certificates only to company-managed devices via MDM (Intune, Jamf, etc.) and require TLS client authentication at the proxy. The simplest proof of "is this a managed device."
2. **Device posture signals** — query EDR/MDM APIs for OS version, disk encryption, and screen-lock status, and feed them to the policy engine. Cloudflare Access and Pomerium have built-in device posture integrations.
3. **Trust tiers** — like BeyondCorp, classify devices into fully-trusted, managed, and unknown tiers, and match them against application sensitivity. For example, the payments admin only from fully-trusted devices, the wiki from managed or above.
Requiring mTLS at the nginx layer looks like this.
server {
listen 443 ssl;
server_name payments-admin.example.com;
ssl_client_certificate /etc/nginx/tls/device-ca.crt;
ssl_verify_client on;
location / {
auth_request /oauth2/auth;
Forward device certificate info to the upstream and audit logs
proxy_set_header X-Device-Cert-DN $ssl_client_s_dn;
proxy_set_header X-Device-Cert-Verify $ssl_client_verify;
proxy_pass http://payments-admin.apps.svc.cluster.local:8080;
}
}
Context-based policy means making different decisions for the same user depending on the situation. Representative signals and example policies:
| Signal | Example policy |
| --------------- | -------------------------------------------------------------------- |
| Device tier | Unmanaged devices may access read-only apps only |
| Location | Access from outside allowed countries requires step-up (passkey) auth |
| Time | Production admin access outside business hours requires approval |
| Auth strength | Password-only sessions cannot reach sensitive apps |
| Anomaly signals | Impossible-travel detection revokes the session immediately |
In Keycloak, conditional executions in authentication flows plus step-up authentication (ACR/LoA) implement auth-strength policy, and the Workflows feature in 26.6 automates account lifecycle at the realm level (for example, disabling long-inactive accounts).
VPN Replacement Scenarios
The typical scenario for replacing a VPN with an IAP:
[Before] All staff --> VPN Gateway --> entire LAN (wiki, CI, admin, DB, SSH ...)
[After]
Staff/contractors --> IAP (HTTPS) --> wiki, CI, admin and other web apps (most traffic)
Operators --> dedicated SSH/DB solutions (Boundary, Teleport ...) (non-HTTP)
Legacy --> residual VPN (shrinking, minimal target subnets)
Key points:
- Moving web applications — the bulk of internal traffic — behind the IAP first slashes VPN concurrency load and helpdesk tickets.
- Non-HTTP protocols such as SSH, databases, and RDP are not the job of an IAP; apply the same identity-first principles with dedicated solutions like Teleport, Boundary, or Cloudflare Tunnel (TCP).
- Contractors and partners get IAP access to specific apps instead of VPN accounts. Offboarding becomes a single account-disable in the IdP.
Cloudflare Access vs Google Cloud IAP vs Pomerium vs oauth2-proxy
| Aspect | Cloudflare Access | Google Cloud IAP | Pomerium | oauth2-proxy |
| --------------- | ----------------------- | ---------------------------- | --------------------------------- | ----------------------- |
| Form | SaaS (edge network) | GCP managed | Open source + commercial | Open source |
| Runs at | Cloudflare edge | Integrated with GCP LB | Self-hosted | Self-hosted |
| IdP support | Any OIDC/SAML | Google + external IdP | Any OIDC | Any OIDC |
| Device posture | Built-in (WARP client) | Built-in (Endpoint Verif.) | Built-in (incl. Pomerium Zero) | None (assemble it) |
| Policy power | Groups, country, device | IAM conditions + Access Lvls | Rich Rego/expression policies | Group/email level |
| Non-HTTP | TCP/UDP (Tunnel) | TCP forwarding | TCP support | None |
| Lock-in | Cloudflare | GCP | Low | Low |
| Cost | Per-user pricing | Included in GCP billing | OSS free + commercial options | Free |
Selection guide:
- **GCP-centric infrastructure** — Google Cloud IAP integrates naturally with the LB and IAM, with the lowest operational burden.
- **Multi-cloud with a SaaS edge preference** — Cloudflare Access is the most complete package, including device posture and non-HTTP.
- **Self-hosted with sophisticated policy** — Pomerium beats oauth2-proxy on policy expressiveness (context conditions, device identity).
- **Simple group-based protection with minimal dependencies** — oauth2-proxy + nginx is the light, battle-tested choice.
Case Study — Protecting Internal Admin Tools
The most common and highest-impact target in practice is internal admin tooling: Grafana, ArgoCD, Airflow, home-grown back offices — tools with weak authentication or their own separate account systems.
The typical pattern:
1. Disable the tool's own login screen or switch it to header/OIDC auth mode. Grafana, for example, can trust the X-Forwarded-User header via its auth.proxy settings.
grafana.ini — header-based auth behind the IAP
[auth.proxy]
enabled = true
header_name = X-Forwarded-User
header_property = username
auto_sign_up = true
sync_ttl = 60
Trust only proxy IPs (the last line of defense against forgery)
whitelist = 10.0.0.0/8
2. Separate allowed groups per tool at the IAP. ArgoCD passes only the platform team group, Airflow only the data team group, and so on. Run a dedicated oauth2-proxy per tool, or use a proxy like Pomerium that supports per-route policy.
3. Log every access as structured logs. Who accessed what app, when, from which device — recorded per request, which makes audits straightforward.
4. Design a break-glass path. Document an emergency procedure (temporary static credentials plus heavy auditing) for reaching admin tools during an IdP outage.
A Phased Adoption Roadmap
Zero Trust is a journey, not a big-bang migration. A realistic roadmap:
Phase 0 Assessment (1 month)
- Inventory internal apps, auth methods, sensitivity classification
- Clean up the IdP: group/role taxonomy, MFA (preferably passkeys)
Phase 1 Pilot (1-2 months)
- Move 2-3 low-risk apps (wiki, dashboards) behind the IAP
- Validate login UX, session policy, failure modes
Phase 2 Expansion (3-6 months)
- All admin tools + IAP by default for new apps
- Roll out device certificates (mTLS), introduce trust tiers
- Adopt Teleport or similar for non-HTTP access (SSH/DB)
Phase 3 VPN reduction (6-12 months)
- Restrict VPN to legacy systems only
- Mature context-based policy (location, time, step-up)
- Policy as code (IaC) and automated periodic access reviews
Phase 4 Continuous improvement
- Session anomaly detection, risk-based re-authentication
- Unify workload identity (SPIFFE) and user identity policy
Define metrics for each phase as well. VPN concurrent connections, percentage of apps behind the IAP, average onboarding/offboarding time, and auth-related helpdesk tickets are the usual suspects.
The 2026 Perspective — Access Control for AI Agents
The new challenge of 2026 is access by non-human subjects, especially AI agents. With agents searching internal wikis and calling admin APIs as a daily occurrence, the policy subject of an IAP is expanding from "user + device" to "user + device + agent."
In practical terms:
- **Agents must be first-class identities.** Instead of the anti-pattern of copying a human account's API key into an agent, register a dedicated client for the agent in the IdP and issue short-lived tokens. Keycloak 26.6 experimental support for OAuth Client ID Metadata Document (CIMD) enables MCP (Model Context Protocol) based agents to present client identity in a standard way without pre-registration.
- **Preserve the delegation chain** — tokens should record "which agent is calling on behalf of which user." The actor claim and delegation patterns of OAuth Token Exchange ([RFC 8693](https://datatracker.ietf.org/doc/html/rfc8693)) are the standard tools.
- **Agent-specific policy** — agents get narrower scopes than humans, shorter token lifetimes, stricter rate limits, and heavier auditing. Identifying agent traffic at the IAP layer (by client identity) and evaluating it against a separate policy bundle is becoming the established structure.
- **Non-HTTP tool calls** — endpoints used by agents, such as MCP servers, should also sit behind the IAP, validating the agent's OAuth token. Keycloak becoming capable of acting as an MCP authorization server fits this context.
If BeyondCorp was the shift "from location to identity," the shift underway now is "from human identity to the identity of every subject (human + non-human)." When adopting an IAP, do not design the policy model narrowly for humans — keep the subject abstraction broad. That is the 2026 design point.
Operational Best Practices and Anti-Patterns
Finally, an operations checklist.
**Best practices**
- Session cookies should be Secure + HttpOnly + SameSite=Lax or stricter, with cookie-refresh periodically pulling IdP state.
- Clock skew between IdP, IAP, and upstream breaks token validation. Monitor NTP synchronization.
- Scrape oauth2-proxy metrics (port 44180) with Prometheus and alert on authentication failure rate and session refresh failure rate.
- An IdP outage means a company-wide app outage, so run Keycloak multi-instance with the 26.6 zero-downtime rolling patch updates.
- Manage policy changes as code-reviewed IaC, and periodically review "who can access which app."
**Anti-patterns**
- Trusting identity headers without signature verification and without a NetworkPolicy — one forged header and you are breached.
- Leaving the app's own login path alive after adopting the IAP — bypass paths must be removed.
- Setting session expiry extremely long (weeks) — it contradicts the "continuous verification" of Zero Trust.
- Applying identical policy to every app — sensitivity-based differentiated policy is the essence of Zero Trust.
- Turning off the VPN overnight in a big bang — without a plan for legacy and non-HTTP traffic, work grinds to a halt.
Closing Thoughts
The Identity-Aware Proxy is the implementation of Zero Trust you can feel the fastest. With nothing more than the battle-tested open-source combination of oauth2-proxy + Keycloak + nginx auth_request, you can start "authentication and authorization on every request" — the heart of BeyondCorp — today. What matters is not the tools but the principles: identity over location, requests over sessions, context over static rules. And in 2026, bake into your design from day one that the scope of identity now extends to AI agents.
In the next post we move behind the IAP and cover token validation at the API gateway and service mesh layer (Istio, Envoy).
References
- [BeyondCorp: A New Approach to Enterprise Security (Google Research)](https://research.google/pubs/pub43231/)
- [NIST SP 800-207 Zero Trust Architecture](https://csrc.nist.gov/pubs/sp/800/207/final)
- [oauth2-proxy official documentation](https://oauth2-proxy.github.io/oauth2-proxy/)
- [Keycloak documentation](https://www.keycloak.org/documentation)
- [Keycloak release notes](https://www.keycloak.org/docs/latest/release_notes/index.html)
- [nginx auth_request module](https://nginx.org/en/docs/http/ngx_http_auth_request_module.html)
- [RFC 7636 — Proof Key for Code Exchange (PKCE)](https://datatracker.ietf.org/doc/html/rfc7636)
- [RFC 8693 — OAuth 2.0 Token Exchange](https://datatracker.ietf.org/doc/html/rfc8693)
- [RFC 9700 — Best Current Practice for OAuth 2.0 Security](https://datatracker.ietf.org/doc/html/rfc9700)
- [OAuth 2.1 draft (draft-ietf-oauth-v2-1)](https://datatracker.ietf.org/doc/draft-ietf-oauth-v2-1/)
- [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html)
- [WebAuthn Level 3 (W3C)](https://www.w3.org/TR/webauthn-3/)
- [FIDO Alliance — Passkeys](https://fidoalliance.org/passkeys/)
- [Pomerium documentation](https://www.pomerium.com/docs)
- [Cloudflare Access documentation](https://developers.cloudflare.com/cloudflare-one/policies/access/)
- [Google Cloud IAP documentation](https://cloud.google.com/iap/docs)
현재 단락 (1/396)
As of 2026, the assumption that "anything on the corporate network can be trusted" is effectively a ...