diff options
| -rw-r--r-- | share/man/ENVOY.md | 77 |
1 files changed, 75 insertions, 2 deletions
diff --git a/share/man/ENVOY.md b/share/man/ENVOY.md index cbbf8ff..2eaa141 100644 --- a/share/man/ENVOY.md +++ b/share/man/ENVOY.md @@ -177,7 +177,7 @@ and send that message to me. Only I can decrypt that message using my private key. This ensures confidentiality so that the ciphertext produced can be snooped by anyone but only the recipient can convert the ciphertext back into plaintext. -### Authenticity +#### Authenticity To ensure that a message originated from the entity that claims to have sent the message an additional signature can be appended to the message. The signature @@ -188,7 +188,7 @@ then they can decrypt the signature using the public key of the sender. If signature can be decrypted without an error then we can trust that the message did in fact originate from the sender. This authenticates the message. -### Integrity +#### Integrity When a recipient receives a message from a sender the recipient also needs to verify that the message wasn't altered. If the signature of the message includes @@ -268,3 +268,76 @@ across services to allow the service to know who is logged in but each service should have its own access token for each user based on the permissions that the service declares that it needs and the permissions that the user agrees to give it. I need to say this again because understanding this is crucial! + +## Envoy Architecture + +Given all the concerns listed above this is where Envoy shines. It can be used +to take care of Authentication via an OpenID Connect transaction by slightly +abusing the built-in `envoy.filters.http.oauth2` HTTP filter. It can also be +used to validate any incoming JWTs via the `envoy.filters.http.jwt_authn` HTTP +filter. Finally, we can use the `envoy.filters.http.ext_authz` HTTP filter to +delegate authorization decisions to an external policy decision point (PDP). + +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. + +```mermaid +sequenceDiagram + participant User + participant Envoy + participant authzd + participant sparkled + 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 + User->>OIDC Provider: Login + OIDC Provider->>User: Redirect to /callback with code + User->>Envoy: GET /callback?code=... + Envoy->>OIDC Provider: Exchange code for tokens + OIDC Provider->>Envoy: Return tokens (ID, access, refresh) + Envoy->>User: Set cookies & redirect to /dashboard + + 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 + Note right of Envoy: Sets headers:<br/>x-jwt-payload<br/>x-jwt-claim-sub + + Envoy->>authzd: Check authorization (gRPC) + Note right of authzd: Request includes:<br/>- Method & Path<br/>- Headers (inc. cookies)<br/>- JWT claims + authzd->>authzd: Evaluate authorization rules + authzd->>Envoy: Return OK/Denied decision + + alt Authorization OK + Envoy->>sparkled: Forward request with JWT headers + sparkled->>sparkled: Extract user from x-jwt-claim-sub + sparkled->>User: Return dashboard content + 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. + +## Envoy Configuration + +Let's dive into the envoy configuration. |
