Closed guicassolato closed 1 year ago
Closing as most of it was covered at #417.
Any other proposed enhancement not included in this iteration may be reopened as an independent issue later on if considered still relevant.
Enhancements left out from AuthConfig v1beta2 for now:
runtime.RawExtension
for selectors' comparison values@split → Array
@replace
response
→ authResponse
authorization.action
)
Package of API enhancements.
Main goals of AuthConfig v1beta2:
The enhancements were organized in 8 groups or topics:
response
denyWith
messagesauthorization.action
)ReferenceGrant
s for cross-namespace referencesSome of the proposed enhancements may imply as well introduction of new features.
I'm also leaving an all-in-one example AuthConfig in the end.
The first purpose and current state of this issue is to collect feedback on the proposed enhancements, to agree on the right package of enhancements – suggestions to be refined, dropped, and new ones to add. Then we can plan on a series of iterations to achieve that, including a migration path (tools and/or automation) for users to upgrade from v1beta1.
Proposed enhancements
1. From lists (arrays) of named definitions to maps (objects)
Names are already first-class citizens in all named definitions - i.e. required in all cases. Although technically any valid string will continue to be a valid key ("object name"), intuitively this change is expected to lead to rather normalized names, thus making referencing more assertive and less error-prone.
[{name: "<name>", …}]
→"<name>": {…}
E.g.
is a more natural object name and reference than:
Affected structures:
identity.extendedProperties
metadata.http.parameters
metadata.http.headers
response.wristband.customClaims
response.json.properties
denyWith..headers
2. Dynamic values, interpolation, selector expansion, and comparison values
2.1. Dynamic values (or values fetched from the Authorization JSON with
valueFrom.authJSON
)The
valueFrom
construct:was originally thought to be later extended as well to:
...which never happened.
Do we want to keep this door open or make it simple,
authJSON
-only?If it becomes
authJSON
-only, then the API could be simplifed to:2.2. Interpolation
Golang templates-inspired delimiters (i.e.
{{ … }}
), to improve readability especially when templating JSON content.E.g. (assuming 2.1 above):
instead of (current):
2.3. Selector expansion
Just like values can be static or dynamic, selectors could be static values or paths in the Authorization JSON.
E.g. (assuming with 2.2 above)
2.4.
runtime.RawExtension
for selectors' comparison valuesCurrently selectors' comparison values are limited to string comparisons only. We want to be smart and support other operations such as
in
andnotIn
(see #357), as well asgt
,lt
,ge
,le
for numeric comparisons, with less risk of running into parsing errors.This change may require even more inferrence on the operand type based on the operator, i.e.:
eq
,neq
→ both sides are scalars ("scalar comparison")matches
→ left side is a string, right side is a regular expression ("regex")incl
,excl
→ left side is a list, right side is a scalar ("list to scalar comparison")in
,notIn
→ left side is a scalar, right side is a list ("scalar to list comparison")gt
,lt
,ge
,le
→ both sides are numeric ("numeric comparison")where "left side" ==
selector
and "right side" ==value
.The implementation must also be able to detect the right type of scalar:
string
,numeric
,bool
,null
.2.5. New string modifier:
@split → Array
To deprecate/replace or additionally to current
@extract:{sep, pos} → String
.2.6. New API and behavior for the string modifier
@replace
Current:
@replace:{"old": String, "new": String}
New:
@replace:{<String:old>: <String:new>, …}
Alternative (to avoid the breaking change): new string modifier, e.g.
@translate
3. Renaming of phases of the Auth Pipeline
3.1.
identity
→authentication
From the beginning, we have always been reluctant about calling the identity phase of the Auth Pipeline "authentication". The reason for that is because, strictly speaking, Authorino performs authentication only on the specific case of user/client verification based upon API keys. All other identity verification methods in Authorino would be better described as token verification or certificate verification, where these are issued not by Authorino, but by a proper authentication server. The authentication server is the actual agent doing the authentication of the user's or client application's identity.
However, we have learnt that most people will not make such distinction. Rather, they see Authorino's identity verification as the Zero Trust extension of user and client authentication. If you can't beat them... possibly you're just being stubborn. So we have been wondering whether it isn't time to embrace this simplification and finally renaming "identity" as "authentication".
Of course, the resolved identity object (post-authentication phase) will continue to be the identity object. Therefore, this change also implies rethinking the JSON path by which the identity object is accessed. Should
auth.identity
becomeauth.authentication.identity
(orauth.authentication.principal
)? Perhapsauth.authentication
could store hints of the exact authentication rule that succeeded verifying the client's identity.3.2.
response
→authResponse
Users find "response" confusing. It is named from Authorino's perspective of building a response to an authorization request. However, that phase is often misunderstood by the response returned to the end-user or client application whose request is being handled by a gateway or proxy that checked authorization with Authorino in the middle of the process.
When Authorino uses the response phase to command mutating of the request to Envoy, this refers to the HTTP request before hitting the upstream protected service, not the HTTP response. Other possible names for the response phase could be mutation, injection, postAuthorization, or the recently suggested authResponse.
4. Renaming of auth methods
4.1.
identity.oidc
→.jwt
or
4.2.
identity.oauth2
→.oauth2Introspection
4.3.
identity.mtls
→.x509
4.4.
identity.kubernetes
→.kubernetesTokenReview
4.5.
identity.credentials
4.6.
identity.extendedProperties
→.override
and.default
.override
: extension properties that will be written to the identity object regardless of pre-existing values with same name of the property.default
: extension properties that will only be written to the identity object when missing a pre-existing value with same name of the property4.7.
authorization.json
→.rules
4.8.
authorization.kubernetes
→.kubernetesSubjectAccessReview
4.9.
authorization.authzed
→.spicedb
5. Restructuring of
response
5.1.
wrapper
s as structured propertyThe
response
config would be more explicitly divided into the different kinds of wrappers, instead of wrapping being an option of each response evaluator.E.g.:
5.2.
denyWith
merged intoresponse
denyWith
is also a response. Perhaps we want to fully embrace that and restructure as follows:6. Rule-level
denyWith
messagesHaving one single
denyWithSpec
for the authentication and one for the authorization is very limiting regarding the information that is provided to the user when access is denied. It should be possible to customize the response returned to the user depending on the specific authentication or authorization rule that failed to grant access.E.g.:
This may be a tricky one to deliver due to the fail-fast strategy under concurrent evaluators implemented by Authorino, or lead to erratic behavior perceived by the end-user.
In case of denial by multiple evaluators, Authorino would have to guess which
denyWithSpec
is the best to use.7. Allow/deny action (
authorization.action
)The goal is to make it easy for users to sometimes write inverted authorization rules, i.e. patterns and policies that deny access instead of allowing it.
E.g.:
which is equivalent to:
TBD - how this would look like for OPA Rego policies. E.g.:
8. Gateway API's
ReferenceGrant
s for cross-namespace referencesCurrently, this would be mainly for controlling the references to Kubernetes
Secret
s.Affected structures:
Secret
label selectors - allow ditching the over-permissiveallNamespaces
Secret
references9. AuthConfig Composition
AuthConfigs that references other AuthConfigs by name.
All-in-one example
* User-defined property names written between double quotes to highlight the difference to API property names.