diff options
| author | mo khan <mo@mokhan.ca> | 2025-05-26 13:50:14 -0600 |
|---|---|---|
| committer | mo khan <mo@mokhan.ca> | 2025-05-26 13:50:14 -0600 |
| commit | 3989ad13fa19ea567e4f97ad8fc200232676b674 (patch) | |
| tree | e0235b6a98a54a3342fe4bafd94d7018e638d2b8 /share | |
| parent | 33a50904d80028fa06915987570800c5957e3167 (diff) | |
docs: describe authn and jwt validation via envoy
Diffstat (limited to 'share')
| -rw-r--r-- | share/man/ENVOY.md | 109 |
1 files changed, 88 insertions, 21 deletions
diff --git a/share/man/ENVOY.md b/share/man/ENVOY.md index 2eaa141..0eca644 100644 --- a/share/man/ENVOY.md +++ b/share/man/ENVOY.md @@ -228,6 +228,8 @@ assumptions about user authentication is valid. The `id_token` in the OpenID Connect (OIDC) workflow represents the authentication context. This _DOES NOT_ represent an authorization context. +TODO:: Describe the sections of a JWT and the schema of the `id_token`. + ### Authorization Authorization is the act of verifying that a party is allowed to perform a @@ -282,15 +284,20 @@ I wrote Sparkle as a proof-of-concept to model these ideas using Envoy. Before we dive into the configuration I want to quickly go over the high level architecture of how these pieces work together. +The proposed architecture ensures that authorization decisions are made consistently at the edge before requests reach the application. + +### Authentication Flow + ```mermaid sequenceDiagram participant User - participant Envoy - participant authzd - participant sparkled + box Pink Docker Image + participant Envoy + participant authzd + participant sparkled + end participant OIDC Provider - Note over User,OIDC Provider: Initial Authentication Flow User->>Envoy: GET /dashboard (no auth) Envoy->>Envoy: OAuth2 filter detects no auth Envoy->>User: Redirect to OIDC Provider @@ -300,8 +307,52 @@ sequenceDiagram Envoy->>OIDC Provider: Exchange code for tokens OIDC Provider->>Envoy: Return tokens (ID, access, refresh) Envoy->>User: Set cookies & redirect to /dashboard +``` + +The `envoy.filters.http.oauth2` HTTP filter can be configured to detect an +unauthenticated request and intercept all inbound requests by redirecting the +user-agent to the hard-coded OAuth Authorization Server endpoints. This filter +does not support the OIDC Discovery endpoint but an Envoy Gateway +[plugin](https://gateway.envoyproxy.io/docs/tasks/security/oidc/) does. +Envoy Gateway is a control plane that is outside the scope of this document. + +```yaml + - name: envoy.filters.http.oauth2 + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.oauth2.v3.OAuth2 + config: + auth_scopes: + - email + - openid + - profile + authorization_endpoint: "https://gitlab.com/oauth/authorize" + credentials: + client_id: "OAUTH_CLIENT_ID" + redirect_path_matcher: + path: + exact: /callback + redirect_uri: "%REQ(x-forwarded-proto)%://%REQ(:authority)%/callback" + signout_path: + path: + exact: /signout + token_endpoint: + cluster: oidc + uri: "https://gitlab.com/oauth/token" + use_refresh_token: true +``` + +### Authorization Flow + +```mermaid +sequenceDiagram + participant User + box Pink Docker Image + participant Envoy + participant authzd + participant sparkled + end + participant OIDC Provider - Note over User,sparkled: Authenticated Request Flow User->>Envoy: GET /dashboard (with cookies) Envoy->>Envoy: Extract ID token from cookie Envoy->>Envoy: JWT filter validates & extracts claims @@ -319,24 +370,40 @@ sequenceDiagram else Authorization Denied Envoy->>User: Return 401 Unauthorized end - - Note over User,sparkled: Public Endpoint Flow - User->>Envoy: GET /health - Envoy->>authzd: Check authorization (gRPC) - authzd->>authzd: Recognize public endpoint - authzd->>Envoy: Return OK (no auth required) - Envoy->>sparkled: Forward request - sparkled->>User: Return health status ``` -Request Flow Summary - -1. Initial Authentication: Unauthenticated users are redirected to the OIDC provider -1. Token Validation: Envoy validates ID tokens and extracts claims as headers -1. Authorization Check: Every request goes through `authzd` for authorization decisions -1. Application Layer: `sparkled` receives pre-authorized requests with user information in headers - -This architecture ensures that authorization decisions are made consistently at the edge before requests reach the application. +The ID token can be validated using the `envoy.filters.http.jwt_authn` HTTP +filter. The following configuration will look for an `id_token` cookie and then +parse the value, validate it against the list of keys specified at the +`remote_jwks` uri and then it will inject a header called `x-jwt-payload` with +the valid JWT as well as the `x-jwt-claim-sub` with the body section of the JWT. + +```yaml + - name: envoy.filters.http.jwt_authn + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.jwt_authn.v3.JwtAuthentication + providers: + gitlab_provider: + audiences: + - OAUTH_CLIENT_ID + claim_to_headers: + - header_name: x-jwt-claim-sub + claim_name: sub + forward: true + forward_payload_header: x-jwt-payload + from_cookies: + - id_token + issuer: https://gitlab.com + remote_jwks: + http_uri: + uri: https://gitlab.com/oauth/discovery/keys + cluster: oidc + rules: + - match: + path: / + requires: + provider_name: gitlab_provider +``` ## Envoy Configuration |
