Skip to main content

Policy Authoring

Policy authoring with Kong Mesh amounts to describing which HTTP APIs should be allowed into and out of a service running next to Kong Mesh data plane. Those policies are enforced by Kong Mesh, and a rejected API request is never seen by the service. Additionally, you can write a policy that your service calls into explicitly to provide additional information that Kong Mesh does not have; it is your service's responsibility to enforce that decision appropriately.

Pre-installed Policies

When you add the Kong Mesh System, several policies are automatically installed. In the Styra DAS, click app, egress or ingress folders from your Kong Mesh System to see the policies.

  • app: Custom policy that you can use if your application needs additional policy decisions from OPA.

  • egress: Policy that either allows or denies outgoing traffic.

  • ingress: Policy that either allows or denies incoming traffic.

Write Ingress and Egress Policies

Use Open Policy Agent's policy language called Rego to author policies.

For an introduction to Rego, Styra recommends you to read the following resources:

When writing Rego policies, you need to know the format of the JSON that is provided to each of your policies as input. The following shows a sample input provided by Kong Mesh for Ingress and Egress policies. This sample includes source, destination, the request itself, and additional metadata. Usually, the concern is around the request itself.

{
"attributes":{
"destination":{
"address":{
"socketAddress":{
"address":"172.17.0.5",
"portValue":5000
}
}
},
"metadataContext":{
"filterMetadata":{
"envoy.filters.http.header_to_metadata":{
"policy_type":"ingress"
}
}
},
"request":{
"http":{
"headers":{
":authority":"example-app-svc",
":method":"GET",
":path":"/finance/salary/alice",
":scheme":"http",
"accept":"*/*",
"authorization":"Basic Ym9iOnBhc3N3b3Jk",
"user-agent":"curl/7.74.0-DEV",
"x-ext-auth-allow":"yes",
"x-forwarded-proto":"http",
"x-kuma-tags":"&app=client-load&&kuma.io/instance=client-load-c86cfcd9-ztjqk&&kuma.io/protocol=tcp&&kuma.io/service=client-load_default_svc&&pod-template-hash=c86cfcd9&&system-type=kong-mesh&",
"x-request-id":"fd04efe0-aad2-4e82-ae54-eb6535aac3fc"
},
"host":"example-app-svc",
"id":"10687151102535961199",
"method":"GET",
"path":"/finance/salary/alice",
"protocol":"HTTP/2",
"scheme":"http"
},
"time":"2021-08-19T06:04:22.297377Z"
},
"source":{
"address":{
"socketAddress":{
"address":"172.17.0.6",
"portValue":54204
}
}
}
},
"parsed_body":null,
"parsed_path":[
"finance",
"salary",
"alice"
],
"parsed_query":{

},
"truncated_body":false,
"version":{
"encoding":"protojson",
"ext_authz":"v3"
}
}

When writing policies, the allow or deny rules are written to describe the conditions under which a request is allowed or denied. By default, requests are all allowed, so you must write policy to deny them.

For example, if you want to allow all GET requests and deny all POST requests to the root path, then write the following allow and deny rule.

# allow GET requests to the root path
allow {
input.attributes.request.http.method == "GET"
input.attributes.request.http.path == "/"
}

# deny POST requests to the root path
deny {
input.attributes.request.http.method == "POST"
input.attributes.request.http.path == "/"
}

Write App rules for OPA-aware Applications

In addition to the ingress and egress policies, the Kong Mesh systems also support application policies. The structure of these policies are customizable according to the application requirements. By default, the module policy.app contains allow and deny - rules similar to ingress and egress policies, but you can remove those and write any Rego that you want.

An application can directly query the OPA embedded in data plane sidecar, usually listening at localhost:8181, for application-specific authorization decisions. The default data document for application policies is data.application.main. This exercises the allow or deny rule created in policy.app module.

kongmesh-opa-das-app

Figure 1: Kong Mesh Architecture for OPA-aware Applications

The application-specific main rule can be queried in the following way:

curl -XPOST localhost:8181/v1/data/application/main \
-d '{
"input": {
"method": "GET",
"path": [
"finance",
"salary",
"bob"
],
"user": "bob"
}
}'
{
"decision_id":"f39ac6e7-89ba-4d61-8e17-7f2afba9a7e0",
"result":{
"allowed":true,
"code":200,
"http_status":200,
"outcome":{
"allowed":true,
"code":200,
"http_status":200,
"policy_type":"app",
"system_type":"template.kong-mesh:1.0"
}
}
}

The decision mappings for Kong Mesh systems rely on the presence of well-known fields to correctly parse the results. The decision mapper expects an outcome structure in the result with two required fields.

  1. allowed
  2. policy_type
{
"outcome": {
"allowed": false, # boolean value to determine if decision was Allowed or Denied
# an absence of this value will mark the decision as Unknown
"policy_type": "app" # classifies the decision as an app decision
# useful for filtering decisions by type in the Decisions UI
}
}