-
Notifications
You must be signed in to change notification settings - Fork 10
AccessPolicy
One time setup to bring up OPA
- Configure global settings for OPA sidecar. Can be over-written on a per-service basis.
Following provides a sample configuration
# values.yaml with global settings
global:
titanSideCars:
imageRegistry: gcr.io/cloud-tools-images
opa:
enabled: false
imageName: opa
imageTag: v1.4.0- Configure OPA policy for token interpretation if token with custom format is used
By default, titan's opa implementation expects Authorization header with Bearer token where all claims are normal json attributes. If this is not true, then a custom opa policy must be supplied that parses the token and exposes all usable claims under a token object accesible via token. prefix.
For example, in following token payload, the 'custom_claim' is an stringified json. If a policy check is required on the 'privs' or 'scope' attributes in the stringified json, then a custom policy must be declared exposing them as first class json attributes.
{
"custom_claim": "{\"scope\":\"system\",\"privs\":\"read_users create_users\"}",
"iss": "https://example.com",
"exp": 1628805673,
"iat": 1628719273,
"jti": "lTe3-KPMQGyYaSXTBpLbgQ"
}Following sample policy handles above payload
# values.yaml with global settings
global:
titanSideCars:
opa:
customPolicies:
tokenSpec: |
package authz.token
import input.attributes.request.http as request
default authz_header = ""
authz_header = trim_space(request.headers.authorization)
token_raw = claims {
startswith(authz_header, "Bearer ")
[_, encoded] := regex.split("[ ]+", authz_header)
[_, claims, _] := io.jwt.decode(encoded)
} else = claims {
[_, claims, _] := io.jwt.decode(authz_header)
} else = claims {
claims := {"custom_claim": "{}", "jti": "null", "iss": "null"}
}
token = {
"custom_claim": json.unmarshal(token_raw.custom_claim),
"iss": token_raw.iss,
"jti": token_raw.jti
}- Enable opa side-car on a per-service basis for services that require OPA
# service's values.yaml
titanSideCars:
opa:
enabled: trueApart from authorization checks, OPA sidecar is also leveraged to enable ratelimiting on attributes from payload and token and request enrichment.
Click to expand!
# titanSideCars.opa.
enabled: bool
imageRegistry: string
imageName: string
imageTag: string
cpu:
request: string
limit: string
memory:
request: string
limit: string
ephemeralStorage:
request: string
limit: string
livenessFailureThreshold: integer
readinessFailureThreshold: integer
customPolicies:
tokenSpec: string(bool, default true) Set to false to disable opa sidecar
(string, optional) Docker image registry path used for OPA sidecar. Overrides titanSideCars.imageRegistry
(string, default opa)
(string, default latest)
(string, default 250m)
(string, default 1)
(string, default 256Mi)
(string, default 1Gi)
(string, default 100Mi)
(string, default 500Mi)
(integer, default 50)
(integer, default 100)
(string, optional)
# titanSideCars.ingress.
accessPolicy:
defaultAction: enum
routes:
- match: RouteMatch
accessPolicy: PerRouteAccessPolicy(enum, default ALLOW) Valid values are ALLOW or DENY.
If defaultAction is set to ALLOW then request is allowed by default. The request is denied if it matches one or more access policies defined on a per route basis.
If defaultAction is set to DENY then request is denied by default. The request is allowed if it matches one or more access policies defined on a per route basis.
An http status code 403 (Forbidden) is returned on denial.
(RouteMatch, required)
(PerRouteAccessPolicy, optional) If supplied, triggers access policy enforcement for matching requests.
# titanSideCars.ingress.routes[].accessPolicy
enabled: bool
name: string
oneOf: []AccessRuleSet (bool, default true) Controls enforecement of supplied access policy
(string, optional) Policy name to enhance readability of generated policy. If not supplied, a unique policy identifier gets auto-generated
([]AccessRuleSet, optional) A list of rulesets that collectively define the access policy for requests that match corresponding route definiton. The route definition is implicitly part of each ruleset. If unspecified, the policy is generated from route defintion alone.
A request a said to match the policy if it matches atleast one-of the rulesets
# titanSideCars.ingress.routes[].accessPolicy.oneOf[]
allOf: []AccessRule([]AccessRule, required) A set of rules that collectively define an access ruleset.
A request a said to match the ruleset if it matches all-of the rules in the ruleset
# titanSideCars.ingress.routes[].accessPolicy.oneOf[].allOf[]
key: string # left operand
# operator + right operand
eq: string # equals
sw: string # starts-with
ew: string # ends-with
co: string # contains
lk: string # like
pr: bool # present (unary)
neq: string # not equals
nsw: string # not starts-with
new: string # not ends-with
nco: string # not contains
nlk: string # not like
npr: bool # not present (unary)An access rule is a simple expression of the form 'left-operand operator right-operand' and follows standard rules of expression evaluation. The expression is capable of comparing headers, claim from token, json payload attributes, and raw text values.
A header can be referenced via header. notaion. Example: header.x-request-id
A token claim can be referenced via token. notation. Example: token.sub.scope or token.jti
A payload attribute can be referenced via payload. notation. Example: payload.userType
If operand has none of the special prefixes, it is treated as raw text
(string, required) Left hand operand. The left operand can be a header, a token claim, or a json payload attribute
(oneof required oneof) Comparison operator. For binary operators, the operator value indicates the right hand operand.
The supported operators are
- eq/neq: Exact string match
- sw/nsw: String prefix match
- ew/new: String suffix match
- co/nco: Substring match
- lk/nlk: Regex match. Regex syntax is documented here
-
pr/npr: Unary operator. Indicates if key is present or not. Only
truevalue is used. Useprto test presence andnprto test non presence.
The right hand operand can be a header, a token claim, a json payload attribute, or raw text
titanSideCars:
ingress:
accessPolicy:
defaultAction: DENY
routes:
- match:
path: /objects
method: POST
accessPolicy:
oneOf:
- allOf:
- key: token.privs
co: create_object
- key: token.scope
co: system
- allOf:
- key: token.privs
co: create_object
- key: token.scope
co: customer
- key: header.x-customer-id
eq: token.customer_id
- allOf:
- key: token.privs
co: create_object
- key: header.x-customer-id
eq: token.customer_id
- key: header.x-domain-id
eq: token.domain_idThe POST /objects request will be allowed if it matches one of the supplied policies. All other requests will be blocked.