Service Mesh (ASM) supports comprehensive authentication and authorization configurations. ASM allows you to configure JSON Web Token (JWT) authentication on a gateway to authenticate request identities. In an ASM instance, mutual TLS (mTLS) certificates are used to authenticate request identities by default. After you confirm the identity of a request, you can use authorization policies to restrict the behavior of the request. When these built-in capabilities do not cover your authorization requirements, you can build a custom authorization service based on HTTP or gRPC. A custom authorization service lets you implement any authorization logic and integrate it into the ASM request flow over HTTP.
How custom authorization works
When a mesh proxy (gateway or sidecar proxy) receives a request, it forwards the request details to your custom authorization service over HTTP before allowing the request through to the target workload. Your authorization service inspects the request and returns an HTTP status code to indicate the decision:
| Response status code | Meaning | Proxy behavior |
|---|---|---|
| 200 | Authorized | Forwards the request to the target workload |
| 403 (or any non-200, non-5xx code) | Denied | Rejects the request and returns the status code to the caller |
| 5xx | Authorization service error | Allows or rejects the request based on the failure mode you configure |
The following diagram shows the authorization flow:
Protocol contract
The mesh proxy sends an HTTP request to your authorization service with the following information:
Method and path: The original request method and path.
Headers: The original request headers. Which headers are forwarded depends on the Carry origin header within auth request setting when you register the authorization service.
Body: The original request body (if present).
Your authorization service returns:
Status code: Determines the authorization decision (see table above).
Response headers: Headers set in the authorization response can be forwarded to the target workload or back to the caller, depending on the status code.
Prerequisites
Before you begin, make sure that you have:
An ASM instance
A Container Service for Kubernetes (ACK) cluster added to the ASM instance
Familiarity with Go programming (the example below uses Go)
Build the authorization service
ASM is compatible with open-source Istio. The Istio project provides a reference implementation that handles both HTTP and gRPC authorization. The following walkthrough focuses on the HTTP path.
Core authorization logic
The ServeHTTP function in the ExtAuthzServer type contains the main decision logic. It reads the incoming request, checks for a specific header value, and returns either a 200 (allow) or 403 (deny) status code:
// ServeHTTP implements the HTTP check request.
func (s *ExtAuthzServer) ServeHTTP(response http.ResponseWriter, request *http.Request) {
body, err := io.ReadAll(request.Body)
if err != nil {
log.Printf("[HTTP] read body failed: %v", err)
}
l := fmt.Sprintf("%s %s%s, headers: %v, body: [%s]\n", request.Method, request.Host, request.URL, request.Header, returnIfNotTooLong(string(body)))
if allowedValue == request.Header.Get(checkHeader) {
log.Printf("[HTTP][allowed]: %s", l)
response.Header().Set(resultHeader, resultAllowed)
response.Header().Set(overrideHeader, request.Header.Get(overrideHeader))
response.Header().Set(receivedHeader, l)
response.WriteHeader(http.StatusOK)
} else {
log.Printf("[HTTP][denied]: %s", l)
response.Header().Set(resultHeader, resultDenied)
response.Header().Set(overrideHeader, request.Header.Get(overrideHeader))
response.Header().Set(receivedHeader, l)
response.WriteHeader(http.StatusForbidden)
_, _ = response.Write([]byte(denyBody))
}
}How the logic works:
The function reads the full request body and logs the request details (method, host, URL, headers, body).
It checks whether the value of the header specified by
checkHeadermatchesallowedValue.If the header value matches, the function returns
http.StatusOK(200), which tells the mesh proxy to allow the request.If the header value does not match or is missing, the function returns
http.StatusForbidden(403), which tells the mesh proxy to reject the request.
Both paths set response headers (resultHeader, overrideHeader, receivedHeader) to communicate the decision and debugging information back to the mesh proxy.
Adapt the logic for your use case
The reference implementation uses a simple header check. In a production authorization service, replace this logic with your own. Common approaches include:
Validating a token against an identity provider
Checking permissions in a database or policy engine
Verifying API keys or signatures
Regardless of the logic, your service must follow the same protocol contract: return 200 to allow a request and a non-200 status code to deny it.
Register the authorization service in ASM
After you deploy the authorization service to your ACK cluster, register it in the ASM console so the mesh proxy can route authorization checks to it.
Log on to the ASM console.
On the Define Custom Authorization Service page, register your authorization service.
Configure the Carry origin header within auth request parameter to specify which original request headers the mesh proxy forwards to the authorization service.
The reference implementation checks the header specified by the checkHeader variable. If this header is not forwarded, the authorization service cannot read it, and all requests will be denied. Make sure the relevant headers are included in the Carry origin header within auth request setting.
Create an authorization policy that specifies which mesh proxy (gateway or sidecar proxy) uses the custom authorization service.
For detailed configuration steps, see Implement custom authorization by using the HTTP protocol.
Related topics
Implement custom authorization by using the HTTP protocol -- Step-by-step instructions to register and configure the authorization service in ASM.
Istio external authorization task -- Upstream Istio documentation on external authorization.