-
Notifications
You must be signed in to change notification settings - Fork 35
Conditions #206
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conditions #206
Conversation
0c0f769
to
1eba442
Compare
2909ab9
to
a4d85f7
Compare
First thing in my mind after reading the descr of the PR: Minor thing, but wdyt? |
|
Totally valid suggestion, @eguzki. I thought about
|
I cannot find it. What is the semantic meaning as a boolean operation of a list of conditions? AND, OR? |
It's AND. |
The patterns can also be used in |
implementation looks good to me |
Influenced by OAS design (sorry I cannot avoid it), I miss some expression in the form of
I wonder if this is even a need. But I can think two example:
This use case is already covered having two different identity evaluators that are evaluated with OR semantics. So maybe does not apply but I think it is worth mentioning.
This use case requires defining two different identity evaluators which are exactly the same (except for the conditions) |
api/v1beta1/auth_config_types.go
Outdated
@@ -175,6 +212,9 @@ type Metadata struct { | |||
// +kubebuilder:default:=0 | |||
Priority int `json:"priority,omitempty"` | |||
|
|||
// Conditions that must match for Authorino to enforce this metadata config; otherwise, the config will be skipped. | |||
Conditions []JSONPattern `json:"conditions,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If there are no conditions set, is the default not to skip?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct. No conditions means always enforce it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps add to the description:
// If omitted, the config will be enforced every time.
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah sounds good, it is a minor thing , it just caught my attention as I read it
No problem, @eguzki. OR logics can be achieved by repeating the evaluator spec as many times as needed, varying only the For authorization based on JSON pattern-matching, because of #206 (comment), repeating the rules can get slightly cleaner. E.g.: spec:
patterns:
my-authz-rules:
- selector: some.json.path
operator: eq
value: some-expected-value
- selector: some.other.json.path
operation: incl
value: some-value-that-must-be-present-in-the-selected-array
authorization:
- name: use-case-1
conditions:
- selector: context.request.http.path
operator: eq
value: /path1
json:
rules:
- patternRef: my-authz-rules
- name: use-case-2
conditions:
- selector: context.request.http.path
operator: eq
value: /path2
json:
rules:
- patternRef: my-authz-rules As for the examples you shared... First one is simpler: spec:
patterns:
get-path1:
- selector: context.request.http.method
operation: eq
value: GET
- selector: context.request.http.path
operator: eq
value: /path1
identity:
- name: api-key
conditions:
- patternRef: get-path1
apikey: {...}
credentials:
in: custom_header
keySelector: API-KEY
- name: http-basic-auth
conditions:
- patternRef: get-path1
apikey: {...} # RFC 7235 happens to be mimicked in Authorino using API key authn as well, though the label selectors here would probably differ from the ones in the `apiKey` above
credentials:
in: authorization_header
keySelector: Basic Second one is a bit more annoying because it involves really duplicating the apiKey authn spec: spec:
patterns:
get:
- selector: context.request.http.method
operation: eq
value: GET
identity:
- name: path1-authn
conditions:
- patternRef: get
- selector: context.request.http.path
operator: eq
value: /path1
apikey: {...}
- name: path2-authn
conditions:
- patternRef: get
- selector: context.request.http.path
operator: eq
value: /path2
apikey: {...} # identical to the `apiKey` above |
@@ -124,19 +124,19 @@ spec: | |||
endpoint: http://keycloak.keycloak.svc.cluster.local:8080/auth/realms/kuadrant | |||
authorization: | |||
- name: email-verified-only | |||
conditions: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe not a good idea but will throw it out there: What if this were named: applyWhen
do you think it would me more intuative? Perhaps not just a thought
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you say it's an improvement and not subject to the possible misunderstanding I mention in my 2nd point in #206 (comment), sounds good to me too
To sum up a few options we've got so far:
conditions
when
applyWhen
if
I personally prefer single-word names whenever possible, but only when they are clear enough.
Let's start a quick poll?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes as an improvement. Single word is fine also. When
gets my vote
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two votes for when
. Sounds like a crushing majority to me 🙂
I'll make the changes.
Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have given it a first review and it looks pretty good to me. As you say it is a breaking change. I am going to cast my eye over it once more as there is quite a bit to take in.
Other than the suggestion to change conditions to when and a broad conversation about whether to focus config in the CR and Policy in rego. This looks good to me 👍 |
60c689b
to
3c4731d
Compare
3c4731d
to
f6be3b2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code looks good and all the tests described in the verification steps passed.
Conditions (new feature), named
when
in the AuthConfig API, are sets of expressions (JSON patterns) that whenever included must evaluate to true against the Authorization JSON, so the scope where the expressions are defined is enforced; otherwise Authorino will skip that scope in the pipeline.The scope for a set of conditions can be the entire
AuthConfig
(top level) or a particular evaluator of any phase of the auth pipeline.Each expression is a tuple composed of a
selector
, anoperator
and a fixed comparablevalue
, just like the pattern matching expressions used in the existingconditions
field of JSON pattern-matching authz and K8s SubjectAccessReview-based authz – both now superseded by this new implementation.Literal expressions and references to expression sets (
patterns
, defined at the top level of theAuthConfig
spec) can be listed, mixed and combined in thewhen
conditions in theAuthConfig
.E.g.,
when
conditions can be used:i. to skip an entire
AuthConfig
based on the context:ii. to skip parts of an
AuthConfig
(i.e. a specific evaluator):iii. to enforce a particular evaluator only in certain contexts (really the same as the above, though to a different use case):
iv. to avoid repetition while defining patterns for conditions:
v. to avoid repetition while defining JSON pattern-matching authorizaton rules:
vi. mixing and combining literal expressions and refs:
vii. to avoid evaluating unnecessary identity checks when the user can indicate the preferred authentication method (again the pattern of skipping based upon the context):
Verification steps
Try this PR locally with an
AuthConfig
that combines most of the use case patterns above into one same spec:Try the
/status
endpoint, skipped according to the top-levelwhen
conditional:curl http://talker-api-authorino.127.0.0.1.nip.io:8000/status -i # HTTP/1.1 200 OK
Try with missing authentication on a case where the
AuthConfig
is enforced, according to the conditions:curl http://talker-api-authorino.127.0.0.1.nip.io:8000/pets -i # HTTP/1.1 401 Unauthorized
Try protected endpoints as a user bound to the member role in Keycloak:
Try protected endpoints as a user bound to the admin role in Keycloak:
Try protected endpoints as an API-key user (admin by definition, according to the
AuthConfig
):Closes #205
Closes #24