Service Mesh (ASM) lets you integrate a custom authorization service into the authorization workflow of a mesh over the HTTP protocol or the gRPC protocol. This topic describes how to develop a custom HTTP-based authorization service that a mesh proxy calls to decide whether a request is allowed.
Background information
Service Mesh (ASM) authenticates the identity of a request before authorization rules apply to the request:
Requests that arrive at a gateway — Configure JWT authentication (RequestAuthentication) on the gateway to authenticate the identity of requests.
Requests inside the mesh — The mTLS certificates issued by the mesh authenticate request identities by default.
After the identity of a request is confirmed, you can use an authorization policy (AuthorizationPolicy) to restrict the behavior of the request. In addition to these standard capabilities, ASM supports integration with a custom authorization service that decides whether to allow a request.
How it works
When you integrate a custom HTTP-based authorization service, the mesh proxy (gateway or sidecar) populates an HTTP authorization request with the information of the received request. The mesh proxy then sends the authorization request to the custom authorization service, which decides whether to allow the request.
The status code that the custom authorization service returns determines the outcome:
A status code of 200 indicates that the request passes the check, and the request is allowed.
A status code of 5xx indicates that the custom authorization service is abnormal. In this case, the request is allowed or denied based on your configuration.
Any other status code indicates that the request fails the check, and the request is denied.
Develop the custom HTTP-based authorization service
ASM is compatible with the open source Istio service mesh, and the Istio community provides a sample implementation of a custom authorization service. The sample implements custom authorization services for both the HTTP protocol and the gRPC protocol. The following excerpt shows the HTTP logic, which resides in the ServeHTTP function:
// 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))
}
}The ServeHTTP function reads the request header that the checkHeader variable specifies. If the value of the header equals the value of allowedValue, the function returns 200 and the request is allowed. In all other cases, the function returns 403 and the request is denied.
The preceding code is an excerpt from the sample implementation. The ExtAuthzServer type, the returnIfNotTooLong function, and identifiers such as checkHeader, allowedValue, resultHeader, overrideHeader, and receivedHeader are defined in other parts of the sample.
This authorization service uses the header that corresponds to the checkHeader variable. Therefore, you must configure the Carry origin header within auth request configuration item when you import the custom authorization service into the mesh. Otherwise, you cannot obtain the expected result.
Integrate the custom authorization service with the mesh
Deploy the custom authorization service that you developed to your Container Service for Kubernetes (ACK) cluster, and then associate the service with your ASM instance in the ASM console. This topic covers development only. For the complete steps to import the custom authorization service into the mesh, see Implement custom authorization by using the HTTP protocol.
After you associate the service, specify the mesh proxies that use the authorization service in an authorization policy. For the authorization policy configuration, see Implement custom authorization by using the HTTP protocol.